From 15f6c72c6e1d0d6a28d3f4cf465a4ceaa082e78b Mon Sep 17 00:00:00 2001
From: giancarlo
Date: Wed, 1 May 2024 17:35:48 +0700
Subject: [PATCH] Add i18n support to email-templates
The email-templates package now uses the i18n (internationalization) library to translate email content based on user language preferences. This update involves changes to the email structure, the addition of translation JSON files, and modifications to the files referencing the emails. Email file locations were also restructured for better organization.
---
packages/email-templates/package.json | 3 +-
.../src/{ => emails}/account-delete.email.tsx | 50 +++++++++----
.../src/{ => emails}/invite.email.tsx | 73 +++++++++++++++----
packages/email-templates/src/index.ts | 4 +-
packages/email-templates/src/lib/i18n.ts | 30 ++++++++
.../src/locales/en/account-delete-email.json | 9 +++
.../src/locales/en/invite-email.json | 9 +++
.../account-invitations-webhook.service.ts | 4 +-
.../webhooks/account-webhooks.service.ts | 4 +-
pnpm-lock.yaml | 3 +
10 files changed, 152 insertions(+), 37 deletions(-)
rename packages/email-templates/src/{ => emails}/account-delete.email.tsx (51%)
rename packages/email-templates/src/{ => emails}/invite.email.tsx (61%)
create mode 100644 packages/email-templates/src/lib/i18n.ts
create mode 100644 packages/email-templates/src/locales/en/account-delete-email.json
create mode 100644 packages/email-templates/src/locales/en/invite-email.json
diff --git a/packages/email-templates/package.json b/packages/email-templates/package.json
index ce8c33385..d68e0612e 100644
--- a/packages/email-templates/package.json
+++ b/packages/email-templates/package.json
@@ -19,7 +19,8 @@
"@kit/eslint-config": "workspace:*",
"@kit/prettier-config": "workspace:*",
"@kit/tailwind-config": "workspace:*",
- "@kit/tsconfig": "workspace:*"
+ "@kit/tsconfig": "workspace:*",
+ "@kit/i18n": "workspace:*"
},
"eslintConfig": {
"root": true,
diff --git a/packages/email-templates/src/account-delete.email.tsx b/packages/email-templates/src/emails/account-delete.email.tsx
similarity index 51%
rename from packages/email-templates/src/account-delete.email.tsx
rename to packages/email-templates/src/emails/account-delete.email.tsx
index e57983bfa..eaaa9eac4 100644
--- a/packages/email-templates/src/account-delete.email.tsx
+++ b/packages/email-templates/src/emails/account-delete.email.tsx
@@ -10,53 +10,75 @@ import {
render,
} from '@react-email/components';
+import { initializeEmailI18n } from '../lib/i18n';
+
interface Props {
productName: string;
userDisplayName: string;
+ language?: string;
}
-export function renderAccountDeleteEmail(props: Props) {
- const previewText = `We have deleted your ${props.productName} account`;
+export async function renderAccountDeleteEmail(props: Props) {
+ const namespace = 'account-delete-email';
- return render(
+ const { t } = await initializeEmailI18n({
+ language: props.language,
+ namespace,
+ });
+
+ const previewText = t(`${namespace}:previewText`, {
+ productName: props.productName,
+ });
+
+ const subject = t(`${namespace}:subject`);
+
+ const html = render(
{previewText}
-
+
{previewText}
- Hello {props.userDisplayName},
+ {t(`${namespace}:hello`, {
+ displayName: props.userDisplayName,
+ })}
- This is to confirm that we've processed your request to
- delete your account with {props.productName}.
+ {t(`${namespace}:paragraph1`, {
+ productName: props.productName,
+ })}
- We're sorry to see you go. Please note that this action is
- irreversible, and we'll make sure to delete all of your data
- from our systems.
+ {t(`${namespace}:paragraph2`)}
- We thank you again for using {props.productName}.
+ {t(`${namespace}:paragraph3`, {
+ productName: props.productName,
+ })}
- Best,
-
- The {props.productName} Team
+ {t(`${namespace}:paragraph4`, {
+ productName: props.productName,
+ })}
,
);
+
+ return {
+ html,
+ subject,
+ };
}
diff --git a/packages/email-templates/src/invite.email.tsx b/packages/email-templates/src/emails/invite.email.tsx
similarity index 61%
rename from packages/email-templates/src/invite.email.tsx
rename to packages/email-templates/src/emails/invite.email.tsx
index a7bb74fe6..e501ae006 100644
--- a/packages/email-templates/src/invite.email.tsx
+++ b/packages/email-templates/src/emails/invite.email.tsx
@@ -17,6 +17,8 @@ import {
render,
} from '@react-email/components';
+import { initializeEmailI18n } from '../lib/i18n';
+
interface Props {
teamName: string;
teamLogo?: string;
@@ -24,31 +26,60 @@ interface Props {
invitedUserEmail: string;
link: string;
productName: string;
+ language?: string;
}
-export function renderInviteEmail(props: Props) {
- const previewText = `Join ${props.invitedUserEmail} on ${props.productName}`;
+export async function renderInviteEmail(props: Props) {
+ const namespace = 'invite-email';
- return render(
+ const { t } = await initializeEmailI18n({
+ language: props.language,
+ namespace,
+ });
+
+ const previewText = `Join ${props.invitedUserEmail} on ${props.productName}`;
+ const subject = t(`${namespace}:subject`);
+
+ const heading = t(`${namespace}:heading`, {
+ teamName: props.teamName,
+ productName: props.productName,
+ });
+
+ const hello = t(`${namespace}:hello`, {
+ invitedUserEmail: props.invitedUserEmail,
+ });
+
+ const mainText = t(`${namespace}:mainText`, {
+ inviter: props.inviter,
+ teamName: props.teamName,
+ productName: props.productName,
+ });
+
+ const joinTeam = t(`${namespace}:joinTeam`, {
+ teamName: props.teamName,
+ });
+
+ const html = render(