Skip to content

feat(email): let self-hosters brand transactional emails - #445

Open
faizan47 wants to merge 1 commit into
QuackbackIO:mainfrom
faizan47:feat/brandable-transactional-emails
Open

feat(email): let self-hosters brand transactional emails#445
faizan47 wants to merge 1 commit into
QuackbackIO:mainfrom
faizan47:feat/brandable-transactional-emails

Conversation

@faizan47

Copy link
Copy Markdown

Fixes #444.

Most of Quackback white-labels fine already: workspace name, logo, colors, custom domain. The transactional emails were the gap. A handful of them hardcode "Quackback" in the subject and the heading, so an install running under its own brand still sends sign-in and password-reset mail that names the platform in the recipient's inbox, the one surface none of the in-app theming reaches.

The notification emails (status change, new comment, changelog) already read the workspace name and were fine. This only touches the auth and onboarding set.

What changed

A new EMAIL_BRAND_NAME env var, defaulting to "Quackback". When set, it replaces the hardcoded product name in:

  • Subjects: sign-in link, sign-in refusal, password reset, invitation, welcome
  • Headings and body: "Sign in to X", "Welcome to X!", "The X Team", "Reset your X password", "invited to join Acme on X"

It's passed as a brandName prop into the templates (default "Quackback"), so the components stay self-contained and existing installs render exactly as before.

I kept it separate from workspaceName on purpose. workspaceName is the board the mail is about; the brand name is the product it's sent from. Keeping them distinct means "join Acme on Quackback" still reads right instead of collapsing to "join Acme on Acme".

I left the "Powered by Quackback" footer alone, since that's the existing attribution link with its own toggle and seemed out of scope here.

On the config surface

I went with an env var because the email package is already env-configured (EMAIL_FROM, SMTP, SES), and it keeps the change contained with no call-site changes. If you'd rather source the name from settings so it can be set in the admin UI, I'm glad to switch it over. Just say so.

Testing

  • New email-brand-name.test.ts covering the custom brand and the "Quackback" default for each affected template
  • Full email package suite passes (184 tests), including the existing logo and signup tests
  • prettier, oxlint, and the email package tsc --noEmit are clean

Documented the var in .env.example and .env.prod.example.

The sign-in, invite, welcome, and password-reset emails hardcoded
"Quackback" in their subjects and headings, so an install running under
its own brand still sent mail naming the platform in the one place
in-app theming, a custom logo, and a custom domain never reach — the
recipient's inbox.

Add an EMAIL_BRAND_NAME env var (default "Quackback") and thread it
through those subjects and templates as a product name that stays
separate from each workspace's own name, so "join Acme on Quackback"
keeps both halves distinct. Existing installs are unchanged.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@faizan47

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

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.

Transactional emails hardcode "Quackback" in subjects/bodies (branding leak for self-hosters)

2 participants