Files
twenty/packages/twenty-emails
Charles Bochet 4fc3650b2d fix(emails): deterministic i18n catalog order to stop recurring i18n PR conflicts (#22803)
## Problem

The automated `i18n - translations` PR (branch `i18n`) conflicts on
`twenty-emails` `.po` files on **every** cycle. Each time, the msgid
*set* is identical to main — only the entry **order** differs.

## Root cause

`twenty-emails` uses explicit message ids (`js-lingui-explicit-id`).
With lingui's default ordering, **`lingui extract` is non-idempotent for
this catalog** — two consecutive runs on identical source produce
different `.po` orderings:

```
# no source change between runs
lingui extract  # run 1
lingui extract  # run 2  -> ~170 lines reordered vs run 1
```

So the order produced by the `i18n-push` extract on main, the order
stored in Crowdin, and the order the `i18n-pull` bot downloads never
agree, and the translation PR re-conflicts perpetually.
`twenty-front`/`twenty-server` use hashed ids and are already idempotent
— this is isolated to emails.

## Fix

Set `orderBy: 'messageId'` in `twenty-emails/lingui.config.ts`. Verified
this makes extraction idempotent — two consecutive extracts now produce
byte-identical output.

This commit includes the one-time reorder of the existing catalogs into
the stable order. Generated `.ts` output is unchanged (already
order-independent). After merge, one push cycle syncs Crowdin to the
stable order, after which the recurring conflicts stop.

## Test plan

- `nx run twenty-emails:lingui:extract` twice → no diff on the second
run.
- `nx run twenty-emails:lingui:compile` → succeeds, generated `.ts`
unchanged.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22803?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-10 15:16:33 +02:00
..
2025-04-03 14:26:19 +02:00

Twenty Emails

This package contains the email templates used by Twenty.

Features

  • Email templates built with React Email
  • Internationalization (i18n) support via @lingui/react
  • Local preview server for testing email templates

Getting Started

Starting the Local Preview Server

To start the local preview server for email development:

npx nx start twenty-emails

This will run the development server on port 4001. You can then view your email templates at http://localhost:4001.

Building Emails

To build the email templates:

npx nx build twenty-emails

Email Structure

Each email template is located in the src/emails directory. The templates use various components from the src/components directory to maintain consistent styling and functionality.