Deploy a Dynamic Next.js App to Vercel with Edge Middleware Caching
Deploy a dynamic Next.js app to Vercel with custom Edge Middleware for smart caching, covering setup, middleware, deployment, performance tuning.
7 min read
Next.js is a popular framework for building modern, dynamic web applications. Pairing it with Vercel provides seamless deployments, automatic scaling, and built‑in edge capabilities. This guide walks through deploying a dynamic Next.js app to Vercel and adding a custom Edge Middleware layer to manage response caching at the edge.
1. Prepare Your Next.js Project
Before deploying, ensure your local development environment is set up. The installation steps below cover Debian/Ubuntu (using apt) and AlmaLinux/Rocky/RHEL (using dnf). If you are using Windows, use PowerShell or WSL with the respective Linux commands.
Install Node.js and npm
Use the NodeSource script to add the official repository and install the latest LTS version of Node.js.
npx create-next-app@latest my-dynamic-app
cd my-dynamic-app
The starter template includes a pages directory (or the app directory if you opt‑in to the App Router). This tutorial uses the Pages Router, which integrates well with edge middleware.
Test Locally
npm run dev
Open http://localhost:3000 in your browser to confirm the default page loads. Once verified, your project is ready for deployment.
2. Add Dynamic Routes and API Endpoints
Dynamic content, such as product pages, user profiles, or real‑time dashboards, is central to many applications. We will create a dynamic route that fetches data from a public API and a simple API route that returns JSON.
Vercel treats paths under /api as serverless functions. This endpoint is useful for health checks and will be referenced when configuring edge caching.
3. Configure Edge Middleware for Smart Caching
Vercel Edge Middleware runs at the CDN edge, before a request reaches your Next.js server. You can use it to determine which responses should be cached, for how long, and under what conditions.
Create the Middleware File
Create a middleware.js file at the project root (or inside the /middleware directory if using the new layout). The file must export a middleware function.
import { NextResponse } from 'next/server';
export function middleware(request) {
const url = request.nextUrl.clone();
// Bypass caching for API routes and auth pages
if (url.pathname.startsWith('/api/') || url.pathname.startsWith('/login')) {
return NextResponse.next();
}
// Cache HTML pages for 10 seconds, JSON for 60 seconds
const response = NextResponse.next();
if (url.pathname.endsWith('.json')) {
response.headers.set('Cache-Control', 'public, max-age=60, stale-while-revalidate=30');
} else {
response.headers.set('Cache-Control', 'public, max-age=10, stale-while-revalidate=20');
}
// Add a custom header for debugging
response.headers.set('X-Edge-Middleware', 'active');
return response;
}
// Apply middleware to all routes except static assets
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
Key parts of this configuration:
matcher: Defines which paths the middleware should run on. It excludes Next.js internal static folders.
Cache-Control: Sets HTTP caching directives that Vercel’s edge network respects. stale-while-revalidate allows serving stale content while a fresh version is fetched in the background.
Bypass logic: API routes and authentication pages are typically not cacheable, so they are passed through unchanged.
Test Middleware Locally
Next.js 13+ supports running middleware in development mode. Start the dev server and inspect response headers using your browser’s developer tools or curl:
curl -I https://localhost:3000/products/1
Look for the Cache-Control and X-Edge-Middleware headers. If they appear, the middleware is wired correctly.
4. Set Up Vercel Project and Deploy
Deploying to Vercel is straightforward due to its Git integration. The steps below are identical regardless of the operating system used locally.
Push Code to a Git Repository
git init
git add .
git commit -m "Initial commit with middleware"
git branch -M main
git remote add origin https://github.com/your-username/your-repo.git
git push -u origin main
Replace the URL with your actual repository location. Vercel supports GitHub, GitLab, and Bitbucket.
Click New Project and select the repository you just pushed.
Vercel automatically detects the Next.js framework and suggests the correct build settings (npm install and npm run build).
Keep the default “Production Branch” as main unless you prefer a different workflow.
Click Deploy. Vercel will clone the repo, install dependencies, build the app, and provision the CDN edge network.
Verify the Deployment
After the build finishes, Vercel provides a preview URL (e.g., https://my-dynamic-app.vercel.app). Open it in a browser and navigate to a dynamic product page, such as /products/2. Use the network tab to confirm the custom headers from the middleware are present.
Configure Environment Variables (Optional)
If your app requires secrets (API keys, database URLs, etc.), add them in the Vercel dashboard under Project Settings → Environment Variables. Assign them to Production or Preview based on the stage.
5. Fine‑Tune Caching Strategy
Edge middleware offers flexibility, but you may need to adjust caching rules as your application grows.
Cache by Query Parameters
If the same page URL returns different data based on query strings (e.g., /search?q=shoes), modify the middleware to include the query string in the cache key:
Replace {deploymentId} and the token with values from your Vercel dashboard. This ensures users see the latest content without waiting for the max-age to expire.
Combine with Incremental Static Regeneration (ISR)
If some pages can be statically generated but need periodic updates, use Next.js ISR (revalidate in getStaticProps) alongside edge caching. The edge layer serves cached HTML quickly, while ISR regenerates the page in the background after the specified interval.
6. Monitor Performance and Debug Edge Behavior
Vercel provides built‑in analytics and logs to help you understand how edge caching impacts latency.
Analytics Dashboard: Displays request counts, cache hit ratios, and geographic distribution.
Edge Function Logs: In the Vercel UI, go to Functions → Edge Middleware to view logs for each request. Add console.log statements in middleware.js for deeper insight.
Real‑User Monitoring (RUM): Integrate a lightweight RUM script (e.g., Vercel’s @vercel/analytics) to capture actual page load times from browsers.
Regularly reviewing these metrics helps you adjust max-age values, add or remove cache tags, and maintain an optimal balance between freshness and speed for your audience.
Conclusion
Deploying a dynamic Next.js application to Vercel is fast, and adding custom Edge Middleware provides fine‑grained control over caching at the CDN edge. In this guide, we:
Set up a Next.js project with dynamic routes and API endpoints.
Implemented middleware to distinguish between HTML and JSON responses, apply appropriate Cache-Control headers, and skip caching for sensitive routes.
Deployed the app to Vercel using Git integration.
Explored advanced caching tweaks, including query‑parameter‑based keys, programmatic purging, and ISR synergy.
Highlighted monitoring tools to keep performance in check.
With these steps, your application can serve dynamic content quickly to users across India and beyond, while still delivering fresh data when it matters most.