refactor: derive marketing, docs and shared hosts from config
Summary
The low-risk parts of #8513: the shared config, then marketing and docs moved onto it (#8610 was merged into this branch). Merge with a merge commit, not a squash, so each part stays revertable on its own.
Part 1: config
packages/shared/src/app-identity.ts:ROOT_DOMAIN,CANONICAL_URLS(marketing, app, docs follow the root domain; the API stayshttps://api.superset.sh) andIOS_APP, kept apart fromconstants.tsso the Expo config can import it without pulling in the rest.constants.ts: re-exports them, addsCOMPANY.SUPPORT_EMAIL, and addsSTAFF_EMAIL_DOMAINS/isStaffEmail, which accept@superset.shand the configured domain.@superset/email/sender:NOREPLY_FROM, built fromEMAIL_SENDING_DOMAIN(defaultsuperset.sh), not from the root domain.apps/mobile/app.config.tsimportsIOS_APPfrom@superset/shared/app-identity. Node loads the Expo config and can't resolve the extensionless importconstants.tsnow has. The resolved config is byte-identical to main's.- CI and deploy workflows,
turbo.jsoncand the.envexamples pass throughNEXT_PUBLIC_ROOT_DOMAIN,EXPO_PUBLIC_ROOT_DOMAIN,EMAIL_SENDING_DOMAINandRELAY_BACKUP_URL.
Part 2: marketing and docs (#8610)
Marketing and docs build their links from the Part 1 helpers, not from hardcoded superset.sh strings.
- Marketing:
next.config.tslegacy docs redirects and/mcp, the install command, WebMCP tools, contact/download/enterprise actions (sender fromNOREPLY_FROM),llms.ts,product-facts.tsandapi-url.ts. - The PublishCard text and the contact page's status and trust hosts follow the root domain. The contact catalog entry now uses
{statusHost}/{trustHost}; all 17 translations are carried over with the same wording. - Docs: the MCP server card, docs MCP server instructions,
llms.txtand the base URL insource.ts.
API references (/mcp, the OpenAPI Link header and MCP instructions) stay on https://api.superset.sh.
Behaviour
With none of the new env set, every value equals the one on main. None of the new secrets exist yet, so the workflows pass empty strings, and every reader treats an empty string as unset. No Vercel project defines these variables.
Verification
All of this was verified on #8513 with the same code:
- Default env: a production build crawl of 3,603 marketing URLs, including all 153 legacy redirects, plus 184 docs URLs, matched main. The only differences were build hashes, OG images and the live leaderboard API rate limit.
- Root domain set to example.org: links, canonical URLs and docs redirects move; API, relay and realtime hosts stay.
- Browser check: headless Chrome over CDP showed no new console errors or CSP violations.
This branch was also rebuilt against current main: marketing (526 pages) and docs (244) match main apart from build hashes and live data. Docs page order also varies between two builds of main.
Tests
packages/shared: 1,400 pass, includingapp-identity.test.ts, which checks the default and a changed root domain.packages/email: 5 pass, includingsender.test.ts.apps/marketing: 173 pass;bun run check:i18nclean.
The server, clients and desktop display-name parts stay in #8513 for later PRs.
Summary by CodeRabbit
- New Features
- App and marketing domains can be customized for web and mobile deployments, with documentation and marketing URLs configurable per deployment.
- Company-domain settings are reflected in published links and contact information, including service-status and security documentation links.
- Outgoing no-reply email addresses can use a configured sending domain, defaulting to
superset.sh.