710d4da4b1
## Problem Fixes #23307. Every transactional email (workspace invite, password reset, email verification, etc.) is delivered with an **empty body** — no title, text, or CTA. ## Root cause `twenty-server` pins `@react-email/render` directly at `^1.2.3`: ```jsonc // packages/twenty-server/package.json "@react-email/render": "^1.2.3", ``` In 1.2.3, `render()` reads `renderToReadableStream` **before** the email template's async Suspense boundary (i18n/locale load) has resolved. The result is the Suspense fallback marker instead of the real markup: ```html <!DOCTYPE html ...><!--$!--><template></template><!--/$--> ``` This was fixed upstream in `@react-email/render@2.0.6` (*"await stream.allReady before reading renderToReadableStream output"*). `twenty-emails` already resolves a 2.x render via `react-email@6.5.0`, so the server's direct pin was simply stale — the two were out of sync. ## Fix Bump the direct pin to `^2.0.6` (resolves to `2.1.0`) and regenerate the lockfile. The server's `render()` imports now use the fixed 2.x. > Note: a `1.2.3` entry remains in `yarn.lock` — it is an internal transitive > pin of `@react-email/components@0.5.3`, not the server render path, so it is > expected and harmless. ## Verification Rendering `SendInviteLinkEmail` through the real `render()` (Node 24) now returns full markup (5.7 kB) with no Suspense marker and the resolved invite link + workspace content, instead of the empty fallback. A jest unit test was intentionally not added: `@react-email/render` 2.x uses a dynamic import that jest's CJS runtime rejects ("A dynamic import callback was invoked without --experimental-vm-modules") — which is exactly why the existing email specs mock `render`. The fix was verified with a standalone Node script. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/23323?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. --> --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
47 lines
1.1 KiB
JSON
47 lines
1.1 KiB
JSON
{
|
|
"name": "twenty-emails",
|
|
"description": "",
|
|
"author": "",
|
|
"private": true,
|
|
"license": "AGPL-3.0",
|
|
"main": "./dist/index.js",
|
|
"scripts": {
|
|
"build": "npx vite build"
|
|
},
|
|
"dependencies": {
|
|
"@lingui/core": "^5.9.5",
|
|
"@lingui/react": "^5.9.5",
|
|
"twenty-shared": "workspace:*"
|
|
},
|
|
"peerDependencies": {
|
|
"react": "^18.2.0 || ^19.0.0",
|
|
"react-dom": "^18.2.0 || ^19.0.0"
|
|
},
|
|
"devDependencies": {
|
|
"@lingui/cli": "^5.9.5",
|
|
"@lingui/swc-plugin": "^5.11.0",
|
|
"@lingui/vite-plugin": "^5.9.5",
|
|
"@react-email/ui": "^6.9.0",
|
|
"@tiptap/core": "^3.4.2",
|
|
"@types/react": "^19.2.0",
|
|
"@types/react-dom": "^19.2.0",
|
|
"@typescript/native-preview": "^7.0.0-dev.20260116.1",
|
|
"@vitejs/plugin-react-swc": "^4.3.1",
|
|
"react-email": "^6.9.0",
|
|
"tsc-alias": "^1.8.16",
|
|
"vite-plugin-dts": "^4.5.4"
|
|
},
|
|
"exports": {
|
|
".": {
|
|
"types": "./dist/index.d.ts",
|
|
"import": "./dist/index.mjs",
|
|
"require": "./dist/index.js"
|
|
}
|
|
},
|
|
"engines": {
|
|
"node": "^24.5.0",
|
|
"npm": "please-use-yarn",
|
|
"yarn": "^4.0.2"
|
|
}
|
|
}
|