shellscape / shellscape/jsx-email

MSO conditional comments in <head> use non-standard <![endif]/--> closing that breaks Classic Outlook

Open
#403 25 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.3k
Forks
55
PR merge metrics
No merged PRs in 30d

Description

  • Component or Package Name: jsx-email (renderer/conditional.ts)
  • Component or Package Version: 2.8.4
  • @jsx-email/cli Version?: 2.8.4
  • Operating System (or Browser): Linux / Classic Outlook 2019, Outlook 365 desktop
  • Node Version: 24.13.0
  • Link to reproduction (⚠️ read below): Not relevant
Expected Behavior

MSO conditional comments in the <head> section should use the standard closing syntax <![endif]-->:

<!--[if mso]><xml><o:OfficeDocumentSettings><o:AllowPNG /><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->
Actual Behavior

MSO conditional comments in the use non-standard closing syntax <![endif]/-->:

<!--[if mso]><xml><o:OfficeDocumentSettings><o:AllowPNG /><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]/-->

Note the trailing / before -->. This causes Classic Outlook (2007-2019, Office 365 desktop) to fail to parse the conditional, resulting in emails not rendering at all.

Additional Information

The issue is in src/renderer/conditional.ts where there's intentional logic to use <![endif]/--> for head conditionals:

// when adjacent comments appear. Use the `<![endif]/-->` form
closeRaw = '<![endif]/-->';

However, <![endif]/--> is not valid IE/Outlook conditional comment syntax. The standard closing is <![endif]-->. Classic Outlook's Word rendering engine doesn't recognize the non-standard form.

Workaround:

const html = await render(<Email />);
const fixed = html.replaceAll('<![endif]/-->', '<![endif]-->');

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/renderer/conditional.ts and inspect the head-conditional branch that assigns closeRaw. Render an email containing an MSO head conditional and verify that the output uses the standard <![endif]--> closing without the slash. Done means Classic Outlook-compatible conditional markup is emitted without requiring the documented workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
html, typescript
Domain
web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.