Next.js App Router: A Practical Guide for Real Projects
Server components, layouts, loading states and caching explained with the decisions that matter when you ship a real Next.js site.
Vercel hosts Next.js natively and can run an Express API as a serverless function. Here is a setup that works.
Create two Vercel projects pointing to two folders: the Next.js client and the Express server. Set the root directory for each in the project settings.
Express must be exported as a handler instead of calling listen.
// api/index.ts
import app from '../src/app';
export default app;
{
"version": 2,
"builds": [{ "src": "api/index.ts", "use": "@vercel/node" }],
"routes": [{ "src": "/(.*)", "dest": "/api/index.ts" }]
}
Add your database URL, JWT secrets and allowed origins in the Vercel dashboard for each project. Redeploy after changing them; they are baked in at build or cold start.
Serverless functions open many short connections. Use a managed database such as MongoDB Atlas or a pooled PostgreSQL URL, and allow Vercel's IPs, which in practice means allowing access from anywhere and relying on strong credentials.
If the frontend and API live on different domains, proxy API calls through Next.js rewrites so cookies stay first-party:
async rewrites() {
return [{ source: '/api/v1/:path*', destination: `${process.env.API_URL}/api/v1/:path*` }];
}
/health directly.Export the Express app, route everything to one function, keep secrets in project settings and proxy through Next.js for clean cookies.
Server components, layouts, loading states and caching explained with the decisions that matter when you ship a real Next.js site.
Implement secure login with short-lived access tokens, rotating refresh tokens and httpOnly cookies, and avoid the common JWT mistakes.
Write a small, secure Node.js Docker image with multi-stage builds, layer caching and docker compose for local development.