Skip to content

Enhance email templates with configurable branding and compliance support#37

Merged
Enalmada merged 2 commits intomainfrom
email-best-practices-improvements
Jan 7, 2026
Merged

Enhance email templates with configurable branding and compliance support#37
Enalmada merged 2 commits intomainfrom
email-best-practices-improvements

Conversation

@Enalmada
Copy link
Owner

@Enalmada Enalmada commented Jan 7, 2026

Summary

Follow-up improvements to PR #36, adding configurable branding and email compliance features:

  • Added appName required prop for white-label branding support
  • Added unsubscribeUrl optional prop for CAN-SPAM/GDPR compliance
  • Added JSDoc comments documenting all interface props
  • Used as const satisfies Required<T> pattern for type-safe preview data
  • Added new Storybook story variants (WithoutUsername, WithLongUsername, WithoutUnsubscribe, CustomBranding)
  • Updated documentation with best practices

Changes

Modified files:

  • src/emails/components/EmailLayout.tsx - Added appName and unsubscribeUrl props with JSDoc docs
  • src/emails/WelcomeEmail.tsx - Added new props, updated interface
  • src/emails/WelcomeEmail.stories.tsx - New story variants for edge cases
  • src/emails/preview-data.ts - Uses as const satisfies Required<T> pattern
  • src/emails/index.ts - Updated exports
  • .plan/plans/email-updates/README.md - Expanded documentation

Test plan

  • bun run check-types passes
  • bun run lint passes
  • bun run test:unit passes
  • bun run test-storybook passes
  • Verify Storybook email stories render with new variants

@changeset-bot
Copy link

changeset-bot bot commented Jan 7, 2026

⚠️ No Changeset found

Latest commit: a7f39c5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@gemini-code-assist
Copy link

Summary of Changes

Hello @Enalmada, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the reusability and compliance features of the email templating system. By introducing configurable branding through a new "appName" prop and an optional "unsubscribeUrl" for regulatory compliance, the templates become more adaptable and legally sound. Additionally, the changes improve developer experience with better type safety for preview data and comprehensive JSDoc documentation.

Highlights

  • Configurable Branding: Introduced an "appName" prop to "EmailLayout" and "WelcomeEmail" to support white-label branding, replacing hardcoded app names and making templates more reusable.
  • Email Compliance: Added an optional "unsubscribeUrl" prop to "EmailLayout" and "WelcomeEmail" to facilitate CAN-SPAM/GDPR compliance by conditionally rendering an unsubscribe link in the email footer.
  • Improved Type Safety: Adopted the "as const satisfies Required" pattern for preview data, ensuring type-safe Storybook stories and preventing "exactOptionalPropertyTypes" issues with optional props.
  • Enhanced Documentation: Added JSDoc comments to interface props in "EmailLayoutProps" and updated the ".plan/plans/email-updates/README.md" with new architecture decisions and best practices related to branding and type safety.
  • New Storybook Variants: Created new Storybook stories ("WithoutUsername", "WithLongUsername", "WithoutUnsubscribe", "CustomBranding") to cover various use cases and edge cases for email templates, improving testing and visualization.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the email templates by introducing configurable branding with an appName prop and compliance support with an unsubscribeUrl prop. The changes are well-documented and tested with new Storybook variants. The use of as const satisfies Required<T> for preview data is a great improvement for type safety.

My review includes a couple of suggestions to improve code readability and user experience. Specifically, I've recommended simplifying how an optional prop is passed to a component and making the support email in the footer a clickable mailto: link for consistency and convenience.

Add mailto: link to supportEmail in footer for better UX and
consistency with WelcomeEmail template.
@Enalmada
Copy link
Owner Author

Enalmada commented Jan 7, 2026

Response to Review Comments

✅ Clickable support email (EmailLayout.tsx:59-62)

Implemented in a7f39c5 - the support email in the footer is now a clickable mailto: link for consistency with the WelcomeEmail template.

❌ Conditional spread pattern (WelcomeEmail.tsx:24)

Keeping the current pattern. This project uses exactOptionalPropertyTypes: true in tsconfig. With this setting, TypeScript doesn't allow passing undefined to an optional prop - you must either pass a concrete value or not pass the prop at all.

Using unsubscribeUrl={unsubscribeUrl} produces this error:

Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.

The conditional spread {...(unsubscribeUrl ? { unsubscribeUrl } : {})} is the correct pattern for this TypeScript configuration - it only adds the prop when the value exists.

@Enalmada Enalmada merged commit a0c1956 into main Jan 7, 2026
8 checks passed
@Enalmada Enalmada deleted the email-best-practices-improvements branch January 7, 2026 03:33
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.

1 participant

Comments