Skip to content

Updated welcome email renderer to use custom design settings when enabled#27191

Merged
cmraible merged 6 commits intomainfrom
chris-ny-1197-rebased
Apr 7, 2026
Merged

Updated welcome email renderer to use custom design settings when enabled#27191
cmraible merged 6 commits intomainfrom
chris-ny-1197-rebased

Conversation

@cmraible
Copy link
Copy Markdown
Collaborator

@cmraible cmraible commented Apr 6, 2026

closes https://linear.app/ghost/issue/NY-1197/use-design-settings-from-the-database-when-rendering-welcome-emails

Summary

  • Updated the welcome email renderer to use custom design settings (background color, button style, header image, footer content, badge, etc.) from the database instead of hardcoded defaults
  • All new behavior is gated behind the welcomeEmailsDesignCustomization labs flag — existing welcome emails are unchanged when the flag is off
  • The service wrapper reinitializes when the labs flag changes, so toggling the flag takes effect without a restart

Changes

Renderer (member-welcome-email-renderer.js):

  • Reads designSettings and passes them through to getEmailDesign() (when flag is on) or uses hardcoded defaults (when flag is off)
  • Reuses registerHelpers and the newsletter styles partial for consistent rendering with newsletter emails
  • Passes header image, footer content, badge, and header title settings to the wrapper template

Service (service.js):

  • Loads emailDesignSetting relation when fetching automated emails (flag-gated)
  • Caches design settings at load time alongside other email data
  • Wrapper class tracks labs flag state and reinitializes when it changes

Template (wrapper.hbs):

  • Added post-content-row / post-content classes for newsletter-consistent content styling
  • Added conditional footer content, badge, and powered-by-Ghost sections

Test plan

  • Existing snapshot tests pass unchanged with the flag off (no regression)
  • New snapshot tests cover flag-on rendering
  • Unit tests verify design settings are passed through correctly vs. ignored when flag is off
  • Integration tests verify cached design settings are used (not re-fetched at send time)
  • Integration test verifies service reinitializes when labs flag changes

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Walkthrough

This pull request implements a feature-flagged design customization system for member welcome emails. It adds support for loading and applying design settings from the database when the welcomeEmailsDesignCustomization feature flag is enabled, while preserving legacy behavior when disabled. Changes include updating the email wrapper template structure, modifying the renderer to accept design settings, updating the service to load design settings conditionally, and adding corresponding test coverage for both legacy and new modes.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: updating the welcome email renderer to use custom design settings when the feature flag is enabled.
Description check ✅ Passed The description is directly related to the changeset, providing a comprehensive overview of the changes to the renderer, service, and template, as well as testing approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chris-ny-1197-rebased

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@cmraible cmraible marked this pull request as ready for review April 6, 2026 20:53
@cmraible cmraible changed the title Updated welcome email renderer to use custom design settings when flag is enabled Updated welcome email renderer to use custom design settings when enabled Apr 6, 2026
@cmraible
Copy link
Copy Markdown
Collaborator Author

cmraible commented Apr 6, 2026

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cmraible cmraible requested a review from troyciesco April 6, 2026 23:30
@cmraible cmraible requested a review from troyciesco April 7, 2026 18:11
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
20.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

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 (2)
ghost/core/core/server/services/member-welcome-emails/member-welcome-email-renderer.js (2)

226-235: Consider extracting ctaBgColors to a module-level constant.

This static array could be moved alongside DEFAULT_DESIGN_SETTINGS for consistency and to make it easier to maintain if the same colors are needed elsewhere.

♻️ Optional extraction
+const CTA_BG_COLORS = [
+    'grey',
+    'blue',
+    'green',
+    'yellow',
+    'red',
+    'pink',
+    'purple',
+    'white'
+];
+
 class MemberWelcomeEmailRenderer {

Then use ctaBgColors: CTA_BG_COLORS in the template context.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@ghost/core/core/server/services/member-welcome-emails/member-welcome-email-renderer.js`
around lines 226 - 235, Extract the inline ctaBgColors array into a module-level
constant named CTA_BG_COLORS (placed alongside DEFAULT_DESIGN_SETTINGS) and
replace the inline property in the template context with ctaBgColors:
CTA_BG_COLORS; ensure the new constant is imported or referenced where needed
and update any other occurrences of ctaBgColors in
member-welcome-email-renderer.js to use the new CTA_BG_COLORS symbol.

151-156: Consider defensive null check for designSettings.

The default parameter = {} handles undefined but not explicit null. If a caller passes null, accessing properties like designSettings.background_color would throw a TypeError.

Since this is an internal API and the service appears to pass valid objects, this is low risk. However, a defensive check could prevent future bugs:

🛡️ Optional defensive fix
 async render({lexical, subject, designSettings = {}, member, siteSettings}) {
     const useDesignCustomization = labs.isSet('welcomeEmailsDesignCustomization');

     if (!useDesignCustomization) {
         designSettings = DEFAULT_DESIGN_SETTINGS;
+    } else {
+        designSettings = designSettings || {};
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@ghost/core/core/server/services/member-welcome-emails/member-welcome-email-renderer.js`
around lines 151 - 156, In render({lexical, subject, designSettings = {},
member, siteSettings}) ensure designSettings is treated defensively so an
explicit null doesn't cause a TypeError: check if designSettings is falsy or not
an object (e.g. null) before using it and, when
labs.isSet('welcomeEmailsDesignCustomization') is false or designSettings is
null/invalid, assign DEFAULT_DESIGN_SETTINGS to designSettings; update the logic
around useDesignCustomization and the designSettings variable in the render
function to perform this null/invalid-object check and fallback to
DEFAULT_DESIGN_SETTINGS.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@ghost/core/core/server/services/member-welcome-emails/member-welcome-email-renderer.js`:
- Around line 226-235: Extract the inline ctaBgColors array into a module-level
constant named CTA_BG_COLORS (placed alongside DEFAULT_DESIGN_SETTINGS) and
replace the inline property in the template context with ctaBgColors:
CTA_BG_COLORS; ensure the new constant is imported or referenced where needed
and update any other occurrences of ctaBgColors in
member-welcome-email-renderer.js to use the new CTA_BG_COLORS symbol.
- Around line 151-156: In render({lexical, subject, designSettings = {}, member,
siteSettings}) ensure designSettings is treated defensively so an explicit null
doesn't cause a TypeError: check if designSettings is falsy or not an object
(e.g. null) before using it and, when
labs.isSet('welcomeEmailsDesignCustomization') is false or designSettings is
null/invalid, assign DEFAULT_DESIGN_SETTINGS to designSettings; update the logic
around useDesignCustomization and the designSettings variable in the render
function to perform this null/invalid-object check and fallback to
DEFAULT_DESIGN_SETTINGS.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61120e51-78d3-4ecb-bce5-1148b861d6dc

📥 Commits

Reviewing files that changed from the base of the PR and between 72e93aa and 4da1bd0.

⛔ Files ignored due to path filters (1)
  • ghost/core/test/integration/services/__snapshots__/member-welcome-emails-snapshot.test.js.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • ghost/core/core/server/services/member-welcome-emails/member-welcome-email-renderer.js

@cmraible cmraible enabled auto-merge (squash) April 7, 2026 18:27
@cmraible cmraible merged commit 05c81f8 into main Apr 7, 2026
38 of 39 checks passed
@cmraible cmraible deleted the chris-ny-1197-rebased branch April 7, 2026 18:43
9larsons pushed a commit that referenced this pull request Apr 7, 2026
…bled (#27191)

closes
https://linear.app/ghost/issue/NY-1197/use-design-settings-from-the-database-when-rendering-welcome-emails

## Summary

- Updated the welcome email renderer to use custom design settings
(background color, button style, header image, footer content, badge,
etc.) from the database instead of hardcoded defaults
- All new behavior is gated behind the
`welcomeEmailsDesignCustomization` labs flag — existing welcome emails
are unchanged when the flag is off
- The service wrapper reinitializes when the labs flag changes, so
toggling the flag takes effect without a restart

## Changes

**Renderer** (`member-welcome-email-renderer.js`):
- Reads `designSettings` and passes them through to `getEmailDesign()`
(when flag is on) or uses hardcoded defaults (when flag is off)
- Reuses `registerHelpers` and the newsletter styles partial for
consistent rendering with newsletter emails
- Passes header image, footer content, badge, and header title settings
to the wrapper template

**Service** (`service.js`):
- Loads `emailDesignSetting` relation when fetching automated emails
(flag-gated)
- Caches design settings at load time alongside other email data
- Wrapper class tracks labs flag state and reinitializes when it changes

**Template** (`wrapper.hbs`):
- Added `post-content-row` / `post-content` classes for
newsletter-consistent content styling
- Added conditional footer content, badge, and powered-by-Ghost sections
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