Skip to content
DnsLister Forum

Where domain hunters compare notes

Three custom-domain gotchas in Next.js multi-tenant apps I keep re-learning (from 6 shipped SaaS)

i've shipped six saas on next.js in the last two years (translatorsage, pdfgpt, getroa, growyourbrand, landedfees, universalreco), all solo. the custom-domain multi-tenant setup is the one piece i keep re-learning from first principles because the docs don't cover the messy middle. three things that would've saved me hours across every ship.

**1. middleware runs before host-based rewrites, and that order matters more than you think.**

if you're doing multi-tenant custom domains (customer buys yourbrand.com and maps it to app.yourproduct.com/tenant/yourbrand), the mental model most tutorials give you is 'middleware rewrites the request based on host header'. that works until you also want auth guards in middleware. then you learn the hard way that middleware runs on the original hostname, so req.nextUrl.hostname will be the customer domain, but any downstream redirect() calls will use whatever you set in NEXT_PUBLIC_APP_URL, not the original host. cost me half a day on landedfees because signed-in users on custom domains kept getting redirected to the app subdomain. fix: pass the original host down as a header and re-read it in the destination.

**2. vercel's automatic ssl-per-domain is fine right up until you cross the plan domain cap.**

the docs say up to 50 domains on hobby and 100 on pro. what they don't say clearly: `vercel domains`, `vercel dns`, and 'custom domain on a project' count separately toward different pools, and hitting the ceiling silently degrades new customer onboarding without a clear error. on growyourbrand i had to migrate ssl to cloudflare for anything past ~40 customers. the pattern that scales: run your own dns pointer and use cloudflare for cert issuance via api once volume matters. pennies per domain, doesn't gate on plan tier.

**3. getStaticProps + revalidate looks like magic until a customer buys their domain at 2am.**

if any static content depends on the tenant identity (landing page for that customer's brand, terms page with their entity name), a fresh domain won't have anything pre-rendered. the first request will be slow, and if your revalidate window is long, the second request also hits the cold path. on pdfgpt i moved everything tenant-dependent to on-demand isr with revalidateTag after a signup event, keyed to the domain. the first visitor still eats a small warmup but the tag invalidation is deterministic instead of window-based.

none of these are in the vercel docs in the same place. all three cost me either hours of debugging or a real customer bump.

what's the next.js thing you re-learn from scratch every project?

Source: r/nextjs · by /u/futurist_hp

Leave a Reply

Your email address will not be published. Required fields are marked *