Skip to content

Fixed plaintext email content#27848

Merged
sam-lord merged 2 commits into
mainfrom
plaintext-email-fix
May 14, 2026
Merged

Fixed plaintext email content#27848
sam-lord merged 2 commits into
mainfrom
plaintext-email-fix

Conversation

@sam-lord
Copy link
Copy Markdown
Contributor

ref ONC-1682

Remove the whitespace characters used only for presentation from the plaintext version of the email

@sam-lord sam-lord requested a review from aileen May 12, 2026 15:39
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (2)
  • ghost/core/test/integration/services/__snapshots__/member-welcome-emails-snapshot.test.js.snap is excluded by !**/*.snap
  • ghost/core/test/integration/services/email-service/__snapshots__/cards.test.js.snap is excluded by !**/*.snap

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f0d316e-8d3b-4f8c-87c9-0ee5e34cf3d5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Hidden review stack artifact

Walkthrough

This PR adds the preheader-spacing CSS class to the hidden preheader wrapper in the email-wrapper template, bumps @tryghost/html-to-plaintext from 1.0.8 to 1.0.10, and adds a unit test that asserts plaintext output excludes specific preheader-adjacent spacing Unicode characters (figure space, combining grapheme joiner, soft hyphen).

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fixed plaintext email content' directly relates to the main objective of removing presentation whitespace from plaintext emails to fix deliverability issues.
Description check ✅ Passed The description references ONC-1682 and clearly explains the intent to remove whitespace characters used only for presentation from plaintext emails to eliminate encoding artifacts affecting deliverability.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch plaintext-email-fix

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
ghost/core/test/unit/server/services/email-service/email-renderer.test.js (1)

1658-1677: ⚡ Quick win

Add a positive plaintext assertion to avoid false positives.

This test only checks excluded characters; it should also verify expected preheader content is still present.

Proposed test hardening
         it('excludes preheader spacing characters from plaintext', async function () {
             const post = createModel(basePost);
             const newsletter = createModel(baseNewsletter);

             const response = await emailRenderer.renderBody(
                 post,
                 newsletter,
                 null,
                 {}
             );

+            assert(
+                response.plaintext.includes('Test plaintext for post'),
+                'plaintext should retain preheader content'
+            );
+
             // These characters are in the spacing after the preheader, which should be excluded
             const FIGURE_SPACE = '\u2007';
             const COMBINING_GRAPHEME_JOINER = '\u034F';
             const SOFT_HYPHEN = '\u00AD';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ghost/core/test/unit/server/services/email-service/email-renderer.test.js`
around lines 1658 - 1677, The test currently only asserts excluded characters
are not present; add a positive assertion to ensure expected preheader text is
retained. After calling emailRenderer.renderBody(post, newsletter, null, {}),
derive the expected preheader from the test fixtures (e.g. use
post.custom_excerpt || post.excerpt || post.title) and assert that
response.plaintext.includes(expectedPreheader) so the test verifies the
preheader content exists as well as excluded characters are removed; update the
test case around the existing assertions that reference response.plaintext,
post, basePost, baseNewsletter, createModel and emailRenderer.renderBody.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@ghost/core/test/unit/server/services/email-service/email-renderer.test.js`:
- Around line 1658-1677: The test currently only asserts excluded characters are
not present; add a positive assertion to ensure expected preheader text is
retained. After calling emailRenderer.renderBody(post, newsletter, null, {}),
derive the expected preheader from the test fixtures (e.g. use
post.custom_excerpt || post.excerpt || post.title) and assert that
response.plaintext.includes(expectedPreheader) so the test verifies the
preheader content exists as well as excluded characters are removed; update the
test case around the existing assertions that reference response.plaintext,
post, basePost, baseNewsletter, createModel and emailRenderer.renderBody.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 64340bb3-7eeb-4f22-bf72-a3a6c8d5c91c

📥 Commits

Reviewing files that changed from the base of the PR and between f5481ad and e370652.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • ghost/core/core/server/services/email-rendering/partials/email-wrapper.hbs
  • ghost/core/package.json
  • ghost/core/test/unit/server/services/email-service/email-renderer.test.js

@sam-lord sam-lord force-pushed the plaintext-email-fix branch from e370652 to b6d2e68 Compare May 12, 2026 16:06
Copy link
Copy Markdown
Member

@aileen aileen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took me a while to connect the dots why adding the preheader-spacing class is the only change here, but seeing that the main change actually happened in the upstream dependency, made it clear.

Just one more snapshot that needs updating, otherwise LGTM

ref [ONC-1682](https://linear.app/ghost/issue/ONC-1682/plain-text-newsletter-encoding-artifacts-potential-deliverability)

Remove the whitespace characters used only for presentation from the
plaintext version of the email
@sam-lord sam-lord force-pushed the plaintext-email-fix branch from b6d2e68 to 9cddaa1 Compare May 14, 2026 10:10
@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.81%. Comparing base (9eed023) to head (d7f274e).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #27848   +/-   ##
=======================================
  Coverage   73.81%   73.81%           
=======================================
  Files        1519     1519           
  Lines      128187   128187           
  Branches    15357    15356    -1     
=======================================
+ Hits        94621    94625    +4     
+ Misses      32636    32632    -4     
  Partials      930      930           
Flag Coverage Δ
admin-tests 53.46% <ø> (ø)
e2e-tests 73.81% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sam-lord sam-lord merged commit 596e46f into main May 14, 2026
45 checks passed
@sam-lord sam-lord deleted the plaintext-email-fix branch May 14, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants