The Challenge of Dynamic Subdomains
When scaling a professional B2B SaaS platform at Smart Tech Devs, providing clients with their own custom subdomains (e.g., acme.smarttechdevs.in) is a premium feature that instantly elevates your brand. However, architecting this on the frontend can be complex. In a monolithic React app, you might find yourself writing messy `useEffect` hooks to parse the window.location.host and render different components based on the URL.
This approach is slow, causes screen flickering, and ruins SEO. To build enterprise-grade routing, we must intercept the request before it ever reaches the React rendering engine. We do this using Next.js Edge Middleware.
The Power of the Edge
Next.js Middleware runs on the Edge (e.g., Vercel's Edge Network), meaning the code executes in milliseconds at a server node geographically closest to the user. It intercepts the incoming HTTP request, inspects the headers, and transparently rewrites the URL to the correct internal Next.js route without changing the URL shown in the user's browser.
Step 1: Architecting the App Router Directory
First, we organize our Next.js app/ directory to handle the dynamic rewrites. We create a dynamic route segment specifically for subdomains.
app/
├── (public)/ # Your main marketing site (smarttechdevs.in)
│ └── page.tsx
├── [tenant]/ # The hidden folder where subdomain traffic is routed
│ └── dashboard/
│ └── page.tsx
└── middleware.ts # The Edge routing engine
Step 2: The Middleware Logic
The middleware.ts file sits at the root of your project. Here, we parse the host header, determine if it is a subdomain, and rewrite the URL transparently to our hidden [tenant] folder.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export const config = {
// Only run middleware on relevant paths (ignore static files, API, etc.)
matcher: [
"/((?!api/|_next/|_static/|_vercel|[\\w-]+\\.\\w+).*)",
],
};
export default async function middleware(req: NextRequest) {
const url = req.nextUrl;
// 1. Get hostname (e.g., 'acme.smarttechdevs.in' or 'localhost:3000')
const hostname = req.headers.get('host') || 'smarttechdevs.in';
// 2. Define your root domains to exclude them from subdomain logic
const isRootDomain = hostname === 'smarttechdevs.in' || hostname === 'localhost:3000';
// 3. Extract the subdomain (if it exists)
// 'acme.smarttechdevs.in' -> 'acme'
const subdomain = hostname.replace(`.smarttechdevs.in`, '');
if (!isRootDomain && subdomain) {
// 4. Transparent Rewrite:
// The user sees 'acme.smarttechdevs.in/dashboard'
// Next.js internally renders 'app/[tenant]/dashboard/page.tsx' where [tenant] = 'acme'
return NextResponse.rewrite(new URL(`/${subdomain}${url.pathname}`, req.url));
}
// Pass through normal root domain requests untouched
return NextResponse.next();
}
The Engineering ROI
Using Edge Middleware for subdomain routing fundamentally upgrades your SaaS architecture:
- Zero Layout Shift: Because the routing decision happens on the server edge, the user never sees a flash of the wrong layout or a loading spinner while the app figures out who they are.
- Blazing Fast Verification: You can also inject JWT authentication verification directly into this middleware, rejecting unauthorized users before they consume any React server rendering resources.
- Clean Codebase: Your React components remain pure. They don't have to parse URLs; they simply receive the
tenantparameter cleanly as a prop from the dynamic folder structure.
Conclusion
Dynamic subdomains require a dynamic routing strategy. By pushing the heavy lifting of domain parsing to Next.js Edge Middleware, you ensure that your B2B clients receive a perfectly tailored, blazingly fast experience from the very first byte of the page load.