Summary
Migrate the primary domain from frontman.sh to getfrontman.com. This touches DNS, infrastructure, SDK libraries, marketing site, email, and third-party service integrations.
Current State (audited 2026-04-03)
Cloudflare
frontman.sh — fully configured: A record for api (Hetzner 46.225.13.x, proxied), CNAMEs for app/root/www (proxied), 5 Google Workspace MX records, Resend MX on send, SPF/DKIM/DMARC TXT records, WorkOS + Google + Pinterest verification TXT records
getfrontman.com — zone exists in Cloudflare, zero DNS records configured
Codebase
- 247 occurrences of
frontman.sh across 115 files
- Single source of truth for API host:
libs/frontman-core/src/FrontmanCore__Hosts.res
- Subdomains in use:
api.frontman.sh (Phoenix API/WS), app.frontman.sh (client bundle CDN), root (marketing site)
Migration Plan
Phase 1: DNS + External Services (before any code changes)
Phase 2: Code Changes (ship before DNS cutover)
Phase 3: DNS Cutover
Phase 4: Redirects + Transition
Phase 5: Cleanup (after 6+ months)
Key Risks
- SDK breaking change — existing installed integrations hardcode
api.frontman.sh. Must keep that domain resolving and serving the same backend indefinitely (or until usage drops to zero).
- SEO — 301 redirects preserve ~90-95% of link equity but there will be a temporary ranking dip. All backlinks, Google index, AI training data reference
frontman.sh.
- Email deliverability — new domain needs reputation warm-up. Consider keeping
frontman.sh as the sending domain initially and switching gradually.
- WebSocket connections —
check_origin must accept both domains during the entire transition period.
Files with frontman.sh references (key ones)
Infrastructure:
infra/production/Caddyfile.template
infra/production/deploy.sh
infra/production/server-setup.sh
infra/production/env.template
render.yaml
SDK/Libraries:
libs/frontman-core/src/FrontmanCore__Hosts.res (single source of truth)
libs/frontman-vite/src/FrontmanVite__Config.res
libs/frontman-nextjs/src/FrontmanNextjs__Config.res
libs/frontman-wordpress/frontman.php
libs/frontman-wordpress/includes/class-frontman-ui.php
Server:
apps/frontman_server/config/runtime.exs
apps/frontman_server/lib/frontman_server/accounts/user_notifier.ex
apps/frontman_server/lib/frontman_server_web/user_auth.ex
Marketing:
apps/marketing/astro.config.mjs
apps/marketing/public/llms.txt
- ~50+ blog/content markdown files
- Multiple
.astro layout and page files
Summary
Migrate the primary domain from
frontman.shtogetfrontman.com. This touches DNS, infrastructure, SDK libraries, marketing site, email, and third-party service integrations.Current State (audited 2026-04-03)
Cloudflare
frontman.sh— fully configured: A record forapi(Hetzner46.225.13.x, proxied), CNAMEs forapp/root/www(proxied), 5 Google Workspace MX records, Resend MX onsend, SPF/DKIM/DMARC TXT records, WorkOS + Google + Pinterest verification TXT recordsgetfrontman.com— zone exists in Cloudflare, zero DNS records configuredCodebase
frontman.shacross 115 fileslibs/frontman-core/src/FrontmanCore__Hosts.resapi.frontman.sh(Phoenix API/WS),app.frontman.sh(client bundle CDN), root (marketing site)Migration Plan
Phase 1: DNS + External Services (before any code changes)
getfrontman.com— mirrorfrontman.shzone:A api.getfrontman.com → 46.225.13.x(DNS-only so Caddy can ACME)CNAME getfrontman.com → same target as frontman.sh rootCNAME www.getfrontman.com → same targetCNAME app.getfrontman.com → same target as app.frontman.shMX send.getfrontman.com → same as send.frontman.shgetfrontman.comas sending domain, get new DKIM TXT recordsgetfrontman.comOAuth redirect URIs (keep old ones)getfrontman.comas alias domaingetfrontman.compropertyapi.getfrontman.comserver block alongside existingapi.frontman.sh(both proxy to same backend, Caddy gets certs for both)Phase 2: Code Changes (ship before DNS cutover)
FrontmanCore__Hosts.res— updateapiHost,clientJs,clientCsstogetfrontman.comsubdomainsruntime.exs— addgetfrontman.compatterns tocheck_origin(keepfrontman.shpatterns too)user_notifier.ex— update@fromemail address fromdanni@frontman.shtodanni@getfrontman.comastro.config.mjs— updatesite: "https://getfrontman.com"frontman.shURLs in blog posts, comparison pages, layouts, structured data,llms.txtDOMAINindeploy.sh,server-setup.sh,Caddyfile.template,env.templaterender.yaml— updatePHX_HOST(if still in use)frontman.phpandclass-frontman-ui.phpPhase 3: DNS Cutover
api.getfrontman.comapi.getfrontman.comfrom DNS-only to proxied (if desired)PHX_HOST=api.getfrontman.comgetfrontman.comapi.getfrontman.com@getfrontman.comPhase 4: Redirects + Transition
frontman.shzone:frontman.sh/*→https://getfrontman.com/$1(301)api.frontman.shalive — both domains in Caddy, same backend. Do NOT redirect API traffic (breaks WebSockets and existing SDK versions)frontman.sh→getfrontman.comapps/marketing/scripts/indexnow.mjs)Phase 5: Cleanup (after 6+ months)
frontman.shpatterns fromcheck_originfrontman.shreferencesfrontman.shDNS (keepapi.frontman.shas long as any SDK version in the wild uses it)Key Risks
api.frontman.sh. Must keep that domain resolving and serving the same backend indefinitely (or until usage drops to zero).frontman.sh.frontman.shas the sending domain initially and switching gradually.check_originmust accept both domains during the entire transition period.Files with
frontman.shreferences (key ones)Infrastructure:
infra/production/Caddyfile.templateinfra/production/deploy.shinfra/production/server-setup.shinfra/production/env.templaterender.yamlSDK/Libraries:
libs/frontman-core/src/FrontmanCore__Hosts.res(single source of truth)libs/frontman-vite/src/FrontmanVite__Config.reslibs/frontman-nextjs/src/FrontmanNextjs__Config.reslibs/frontman-wordpress/frontman.phplibs/frontman-wordpress/includes/class-frontman-ui.phpServer:
apps/frontman_server/config/runtime.exsapps/frontman_server/lib/frontman_server/accounts/user_notifier.exapps/frontman_server/lib/frontman_server_web/user_auth.exMarketing:
apps/marketing/astro.config.mjsapps/marketing/public/llms.txt.astrolayout and page files