From 5811716d12b58eb28d40bf12faf16be0b4c2e379 Mon Sep 17 00:00:00 2001 From: Tanushree Ahir <81023203+tanushree-coder-girl@users.noreply.github.com> Date: Fri, 14 Nov 2025 09:42:36 +0530 Subject: [PATCH] fix(email): preserve word wrap and line breaks in email body (#2139) (#2159) --- .../template-custom-message-body.tsx | 35 +++++++++++++++++++ packages/email/templates/document-invite.tsx | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 packages/email/template-components/template-custom-message-body.tsx diff --git a/packages/email/template-components/template-custom-message-body.tsx b/packages/email/template-components/template-custom-message-body.tsx new file mode 100644 index 000000000..5623261af --- /dev/null +++ b/packages/email/template-components/template-custom-message-body.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +export type TemplateCustomMessageBodyProps = { + text?: string; +}; + +export const TemplateCustomMessageBody = ({ text }: TemplateCustomMessageBodyProps) => { + if (!text) { + return null; + } + + const normalized = text + .trim() + .replace(/\r\n?/g, '\n') + .replace(/\n\s*\n+/g, '\n\n') + .replace(/\n{2,}/g, '\n\n'); + + const paragraphs = normalized.split('\n\n'); + + return paragraphs.map((paragraph, i) => ( +

+ {paragraph.split('\n').map((line, j) => ( + + {j > 0 &&
} + {line} +
+ ))} +

+ )); +}; + +export default TemplateCustomMessageBody; diff --git a/packages/email/templates/document-invite.tsx b/packages/email/templates/document-invite.tsx index 86cb4bc6d..59d635e4b 100644 --- a/packages/email/templates/document-invite.tsx +++ b/packages/email/templates/document-invite.tsx @@ -8,6 +8,7 @@ import { RECIPIENT_ROLES_DESCRIPTION } from '@documenso/lib/constants/recipient- import { Body, Container, Head, Hr, Html, Img, Link, Preview, Section, Text } from '../components'; import { useBranding } from '../providers/branding'; +import { TemplateCustomMessageBody } from '../template-components/template-custom-message-body'; import type { TemplateDocumentInviteProps } from '../template-components/template-document-invite'; import { TemplateDocumentInvite } from '../template-components/template-document-invite'; import { TemplateFooter } from '../template-components/template-footer'; @@ -105,7 +106,7 @@ export const DocumentInviteEmailTemplate = ({ {customBody ? ( -
{customBody}
+ ) : ( {inviterName} has invited you to {action} the document "{documentName}".