Restructuring 73 system emails into a reusable template system

Moving a public-sector platform's notification emails out of individual Figma frames and into one structured source.

Restructuring 73 system emails into a reusable template system

Moving a public-sector platform's notification emails out of individual Figma frames and into one structured source.

Role

End-to-end design (Audit, System design, Figma plugin)

Type

Client project, public-sector case-management platform

Duration

3 weeks

Constraints

Under NDA · Real emails can’t be shown

This case study is from a client project under NDA. The example emails on this page are made up, but the problem and the system are the same. The platform sends 73 system emails, and each one was designed as its own Figma frame. The goal was to give everyone one place to write, review and build the emails from.

01 - The Problem

How might we keep 73 system emails consistent and up to date, when their designs are scattered, duplicated or missing?

The platform sends 73 system emails. Counting the versions for different roles and reasons, that becomes 91. Each email was its own Figma frame, spread across several files. This works for a handful of emails, but not for 73.

Issue

  • Each email was a separate Figma frame across several files

  • Similar layouts were rebuilt by hand for each email

  • There was no single list of what each email says, when it's sent and who receives it

  • Variants were kept as near-identical copies

  • Some emails had no design at all

  • Clients reviewed design files instead of the email itself

Operational Consequence

Consequence

  • Changing one line of copy meant finding the right frame first

  • Small inconsistencies built up over time

  • Developers worked out requirements from the mockups at handover

  • One email had six versions to keep in sync by hand

  • Developers built them from requirements alone

  • Feedback was harder to give and to track

Who this affected

  • Designers had to find and edit frames by hand for every change.

  • [Delivery managers] had no single place to check what each email says and when it's sent.

  • Developers had to piece requirements together from mockups.

  • Clients were asked to review design files rather than the emails as they'd be read.

02 - Separating Content from Design

The main change was to stop treating each email as a design, and instead write what each email says in one structured sheet. The design is then generated from that content.

I split the system into four layers, each with its own place:

Layer

  • Content

  • Design

  • Review

  • Render

What it covers

Consequence

  • What each email says, its structure and its variants

  • How each component looks

  • How the email reads to the recipient

  • The final styled email

Where it lives

Consequence

  • One shared sheet

  • The existing pattern library

  • A formatted Preview

  • A Figma plugin that builds it from the sheet

03 - How an email is written in the sheet

Each email is written as an ordered list of labelled blocks. [13] block types cover all 73 emails.

A made up example

Subject

Logo

header

beforeBody

tableTitle

columnName-1

column-1

columnName-2

column-2

columnName-3

column-3

afterBody

Button

Footer

Your request has been approved

Dear {requester.name},

{officer.name} has approved your request for {item}.

Please proceed to counter A on {collection.date} to collect your item(s).

Request details

Reference

{request.id}

Approved by

{officer.name}

Quantity

{item.quantity}

If there is any discrepancy with the item(s), please do not hesitate to contact {officer.name}.

View request

Footer

Subject

Logo

header

beforeBody

tableTitle

columnName-1

column-1

columnName-2

column-2

columnName-3

column-3

afterBody

Button

Footer

Your request has been approved

Dear {requester.name},

{officer.name} has approved your request for {item}.

Please proceed to counter A on {collection.date} to collect your item(s).

Request details

Reference

{request.id}

Approved by

{officer.name}

Quantity

{item.quantity}

If there is any discrepancy with the item(s), please do not hesitate to contact {officer.name}.

View request

Footer

  1. Block Types

  • Fixed slots : Subject, Logo, Button, Footer

  • Content blocks : header, beforeBody, table and table block types, afterBody, etc

  1. Formatting

Bold, italics, links and line breaks are written as <xml> tags inside the cell. Values that change for each recipient are marked with {tokens}, so developers can see what is fixed and what is dynamic.

  1. Variants

Block

Subject

Logo

header

beforeBody

beforeBody

tableTitle

columnName-1

column-1

columnName-2

column-2

columnName-3

column-3

afterBody

Button

Footer

Content

Your request has been approved

Dear {requester.name},

{officer.name} has approved your request for {item}.

Please proceed to counter A on {collection.date} to collect your item(s).

{officer.name} has approved your request for {item}.

Your item(s) will be delivered to {delivery.address} on {delivery.date}.

Request details

Reference

{request.id}

Approved by

{officer.name}

Quantity

{item.quantity}

If there is any discrepancy with the item(s), please do not hesitate to contact {officer.name}.

View request

Footer

Variant

//Normal scenario

//Delivery scenario

Block

Subject

Logo

header

beforeBody

beforeBody

tableTitle

columnName-1

column-1

columnName-2

column-2

columnName-3

column-3

afterBody

Button

Footer

Content

Your request has been approved

Dear {requester.name},

{officer.name} has approved your request for {item}.

Please proceed to counter A on {collection.date} to collect your item(s).

{officer.name} has approved your request for {item}.

Your item(s) will be delivered to {delivery.address} on {delivery.date}.

Request details

Reference

{request.id}

Approved by

{officer.name}

Quantity

{item.quantity}

If there is any discrepancy with the item(s), please do not hesitate to contact {officer.name}.

View request

Footer

Variant

//Normal scenario

//Delivery scenario

Some emails can have several versions depending on the different context required. The shared copy is written once, and only the lines that differ are tagged by variant. Changing a shared line updates every version.

  1. Repeating content

I implemented the ability to specify how many times a piece of content - for example the number of rows in a table - repeats. The cell tells the developer how many times the content will repeat.

04 - My Key Decisions and Tradeoffs

Decision

Alternatives I considered

Why I chose this

Tradeoffs

Write email content in one sheet and generate the design from it

Keep one Figma frame per email

Everyone works from the same source

The sheet has to be kept accurate, since everything depends on it

Write formatting as plain-text tags in the cell

Format directly in Figma

Developers can see exactly what to build, and the text is searchable

Authors need to learn the tags

Tag only the lines that differ between variants

Keep each variant as a separate email

Shared lines only need to be changed once

Harder to see a whole variant at a glance

Write repeating content as one row with a repeat count

Copy the rows out in full

Shorter, and the pattern is clear

Edge cases need extra handling

Give clients a formatted Preview with a Comments column

Send design files for review

Clients review the email as it will be read, and feedback is kept per email

One more view to keep in sync

Build a Figma plugin to generate designs from the sheet

Build each email by hand from components

Designs stay in sync with the content

Built, but not rolled out to the team

05 - What I Built

06 - What I Can't Show Here

The contents of each email in the template are under NDA. Some of the common questions about this email template system:

  • What happens when the same event goes to an officer and their lead; how much should the message change?

  • Is there a way to visualize the email while it is being drafted?

  • How do you introduce this tagging system when only the authors need to learn it, and how flexible are the tags?

I'm happy to walk through these in a call.

07 - Where it stands

The sheet, the Preview and the Figma plugin are built, and the system is currently in client review. The plugin works, but it hasn't been rolled out to the team. Another designer and I have since applied the same approach to a second platform's emails, which is also in review.

08 - Reflections

I expected some emails to be missing designs, and they were. What I didn’t expect was that most designs were already in one place, but the sheer number of variants made them hard to make sense of. Having everything in one file didn’t make it clear. The structure had to be pulled out of it.

If I started again, I’d talk to the developers first. The emails already existed in the system, and developers could have confirmed what each one does and when it’s sent. Working that out myself from the designs took time that a few early conversations would have saved.

Building the Figma plugin was the most satisfying part of the project. It showed me I could use what I know about building with AI to solve a design problem directly, instead of writing a spec and waiting for someone else to build it.

The team decided not to roll out the plugin, and the focus stayed on the template itself. I still believe that being able to see a text-based system rendered as a real design helps people trust it, and it’s something I’d want to test properly on a future project.

Ron Ang | 2026 | Crafted with

, powered by Framer