refactor: derive marketing, docs and shared hosts from config

Merged
KI
21d ago
+299-79

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 stays https://api.superset.sh) and IOS_APP, kept apart from constants.ts so the Expo config can import it without pulling in the rest.
  • constants.ts: re-exports them, adds COMPANY.SUPPORT_EMAIL, and adds STAFF_EMAIL_DOMAINS / isStaffEmail, which accept @superset.sh and the configured domain.
  • @superset/email/sender: NOREPLY_FROM, built from EMAIL_SENDING_DOMAIN (default superset.sh), not from the root domain.
  • apps/mobile/app.config.ts imports IOS_APP from @superset/shared/app-identity. Node loads the Expo config and can't resolve the extensionless import constants.ts now has. The resolved config is byte-identical to main's.
  • CI and deploy workflows, turbo.jsonc and the .env examples pass through NEXT_PUBLIC_ROOT_DOMAIN, EXPO_PUBLIC_ROOT_DOMAIN, EMAIL_SENDING_DOMAIN and RELAY_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.ts legacy docs redirects and /mcp, the install command, WebMCP tools, contact/download/enterprise actions (sender from NOREPLY_FROM), llms.ts, product-facts.ts and api-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.txt and the base URL in source.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, including app-identity.test.ts, which checks the default and a changed root domain.
  • packages/email: 5 pass, including sender.test.ts.
  • apps/marketing: 173 pass; bun run check:i18n clean.

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.