diff --git a/packages/email-renderer/package.json b/packages/email-renderer/package.json
index c6530bb9..4d4d5c0a 100644
--- a/packages/email-renderer/package.json
+++ b/packages/email-renderer/package.json
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/email-renderer",
- "version": "0.1.15",
+ "version": "0.1.16",
"type": "module",
"description": "WRNexus block email renderers with HTML, text, AMP Email, and MJML interoperability.",
"exports": {
diff --git a/packages/email-renderer/src/blocks.ts b/packages/email-renderer/src/blocks.ts
index 0b043c14..d6dbe76d 100644
--- a/packages/email-renderer/src/blocks.ts
+++ b/packages/email-renderer/src/blocks.ts
@@ -117,9 +117,9 @@ export const emailDocumentBlock = defineBlock({
emailHtml: ({ node, slots }) =>
`
${attrs(node).logoUrl ? ` ` : ""} |
`,
ampEmail: ({ node, slots }) =>
- ``,
+ `| ${attrs(node).logoUrl ? `` : ""} |
`,
mjml: ({ node, slots }) =>
- `${slots.content}`,
+ `${attrs(node).logoUrl ? `` : ""}${slots.content}`,
},
textRenderer: ({ slots }) => slots.content,
} satisfies BlockDefinition);
diff --git a/packages/email-renderer/test/email.test.ts b/packages/email-renderer/test/email.test.ts
index faa5fa36..96deba54 100644
--- a/packages/email-renderer/test/email.test.ts
+++ b/packages/email-renderer/test/email.test.ts
@@ -57,6 +57,27 @@ const document: BlockDocument = {
};
describe("email renderer", () => {
+ test("global brand logo survives HTML, AMP, and strict MJML export", async () => {
+ const draft = structuredClone(document);
+ draft.root.props.logoUrl = "https://example.com/logo.png";
+ draft.root.props.logoAlt = 'Brand & "Company"';
+ const result = await renderEmail(draft,{amp:true,mjml:true});
+ expect(result.ok).toBe(true);
+ if (!result.ok) return;
+ for (const output of [result.value.parts.html.content,result.value.parts.amp?.content,result.value.exports?.mjml]) {
+ expect(output).toContain('src="https://example.com/logo.png"');
+ expect(output).toContain('alt="Brand & "Company""');
+ }
+ expect(result.value.parts.amp?.validation.valid).toBe(true);
+ expect(await validateMjml(result.value.exports!.mjml!)).toEqual([]);
+ draft.root.props.logoUrl = "";
+ const empty = await renderEmail(draft,{amp:true,mjml:true});
+ expect(empty.ok).toBe(true);
+ if (empty.ok) {
+ expect(empty.value.parts.amp?.content).not.toContain(" {
const draft = structuredClone(document);
const text = 'First line\r\nSecond line\n\n\rLast line';