Dynamic redirects with Edge Config and Next.js proxy

Learn how to create redirects that update instantly without redeploying by storing rules in Edge Config and reading them from your Next.js proxy.

6 min read
Last updated January 23, 2026

This guide shows you how to create redirects that update instantly without redeploying. Store redirect rules in Edge Config and read them from your Next.js proxy.

You'll need:

  • A Next.js project deployed on Vercel
  • A Vercel account (Edge Config is available on all plans)

Go to your Vercel dashboard and navigate to Storage > Edge Config > Create Edge Config.

Name it something descriptive like redirects or routing-config.

After creation, you'll see your Edge Config ID (starts with ecfg_). You'll need this later.

Reference: Edge Config quickstart

In your Edge Config's settings, click Connect Project and select your Next.js project.

This automatically adds the EDGE_CONFIG environment variable to your project. The variable contains your connection string, which the SDK uses to read data.

For local development, pull the environment variable:

vercel env pull .env.local

This downloads all your project's environment variables, including EDGE_CONFIG, into .env.local.

In the Edge Config dashboard, insert:

{
"redirects": [
{
"source": "/old-blog",
"destination": "/blog",
"permanent": true
},
{
"source": "/docs/v1",
"destination": "/docs/v2",
"permanent": false
}
]
}

The structure is simple: an array of objects with source, destination, and permanent properties.

For now, use exact paths. The Advanced patterns section shows how to add support for wildcards, parameters, and regex matching (like /blog/:slug or /docs/:version/:path*).

npm install @vercel/edge-config

The SDK provides a get() function that reads data from your Edge Config with ultra-low latency.

Reference: @vercel/edge-config SDK

Create a proxy.ts file in /src or the root of your project (if you don't have a /src directory):

import { get } from '@vercel/edge-config';
import { NextRequest, NextResponse } from 'next/server';
// Define the shape of your redirect rules
type Redirect = {
source: string;
destination: string;
permanent: boolean;
};
export const config = {
// Skip static files
matcher: '/((?!_next/static|_next/image|favicon.ico).*)',
};
export default async function proxy(request: NextRequest) {
try {
// Read redirect rules from Edge Config
const redirects = await get<Redirect[]>('redirects');
if (!redirects) {
return NextResponse.next();
}
// Check if the current path matches any redirect rule
const redirect = redirects.find(
(r) => r.source === request.nextUrl.pathname
);
if (redirect) {
return NextResponse.redirect(
new URL(redirect.destination, request.url),
redirect.permanent ? 308 : 307
);
}
return NextResponse.next();
} catch (error) {
// If Edge Config fails, continue without redirecting
console.error('Edge Config error:', error);
return NextResponse.next();
}
}

What this does:

  1. Reads the redirects array from Edge Config on every request
  2. Checks if the current URL path matches any source path (exact match only)
  3. If matched, redirects to the destination with the appropriate status code
  4. If anything fails, the request continues normally

This basic example uses exact path matching. See the Advanced patterns section to add support for wildcards (:slug*), parameters (:id), and regex patterns.

File naming: Use proxy.ts for Next.js 16+, or middleware.ts for Next.js 15 and earlier.

Reference: Next.js proxy

Deploy your project:

vercel --prod

Then test your redirects:

  1. Visit your old URL (e.g., https://your-site.vercel.app/old-blog)
  2. You should be redirected to the new URL (/blog)
  3. Check the network tab: you'll see a 307 or 308 status code

This is where Edge Config shines. To add, modify, or remove redirects:

  1. Go to your Edge Config in the Vercel dashboard
  2. Edit the redirects item
  3. Save your changes

Changes propagate globally in under a second. No redeploy needed.

You can also update redirects programmatically using the Vercel API:

const response = await fetch(
`https://api.vercel.com/v1/edge-config/${EDGE_CONFIG_ID}/items`,
{
method: 'PATCH',
headers: {
Authorization: `Bearer ${VERCEL_API_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [
{
operation: 'update',
key: 'redirects',
value: [
// Your updated redirect rules
{ source: '/new-campaign', destination: '/landing', permanent: false }
],
},
],
}),
}
);

This is useful for building admin interfaces or integrating with CMS webhooks.

Reference: Edge Config API

The basic example uses exact path matching. For advanced patterns like wildcards, parameters, and regex matching, update your proxy.ts to use path-to-regexp (the same library that powers next.config.js redirects).

First, install path-to-regexp version 6.3.0 (the same version Next.js uses):

npm install path-to-regexp@6.3.0

This ensures your redirect patterns work identically to next.config.js redirects. At runtime, your code still uses Next.js's bundled version (no duplication in your bundle).

Then update your proxy.ts:

proxy.ts
import { get } from '@vercel/edge-config';
import { NextRequest, NextResponse } from 'next/server';
import { match } from "path-to-regexp";
type Redirect = {
source: string;
destination: string;
permanent: boolean;
};
export const config = {
matcher: '/((?!_next/static|_next/image|favicon.ico).*)',
};
export default async function proxy(request: NextRequest) {
const redirects = await get<Redirect[]>('redirects');
if (!redirects) return NextResponse.next();
const pathname = request.nextUrl.pathname;
for (const redirect of redirects) {
// Use Next.js's path matching - same as next.config.js
const matcher = match(redirect.source, { decode: decodeURIComponent });
const result = matcher(pathname);
if (result) {
// Build destination with captured params
let destination = redirect.destination;
if (result.params) {
for (const [key, value] of Object.entries(result.params)) {
// Handle array params (wildcards)
const param = Array.isArray(value)
? value.join("/")
: (value as string);
destination = destination.replace(`:${key}*`, param);
destination = destination.replace(`:${key}`, param);
}
}
return NextResponse.redirect(
new URL(destination, request.url),
redirect.permanent ? 308 : 307
);
}
}
return NextResponse.next();
}

This approach supports all the same patterns as next.config.js redirects:

Named parameters:

{
"source": "/blog/:slug",
"destination": "/articles/:slug",
"permanent": true
}

Wildcard matching:

{
"source": "/docs/:version/:path*",
"destination": "/documentation/:version/:path*",
"permanent": false
}

Regex patterns:

{
"source": "/user/:id(\\\\d+)",
"destination": "/profile/:id",
"permanent": true
}

Optional segments:

{
"source": "/posts{/:year}{/:month}",
"destination": "/archive/:year/:month",
"permanent": false
}

Why this works: Next.js bundles path-to-regexp internally, so you don't need to install any additional dependencies. You get the exact same path matching that next.config.js uses, but with the ability to update rules via Edge Config.

Reference: Next.js path-to-regexp patterns

Edge Config has size limits per plan:

  • Hobby: 8 KB
  • Pro: 64 KB
  • Enterprise: 512 KB

For most redirect use cases, 8 KB is plenty. A simple redirect rule is about 100 bytes, so you can fit roughly 80 rules in the Hobby plan limit.

If you need thousands of redirects, use Bulk Redirects instead.

Reference: Edge Config limits

The matcher config determines which requests trigger your proxy. Be specific to avoid unnecessary Edge Config reads:

export const config = {
// Only run on specific paths that might have redirects
matcher: ['/old-blog/:path*', '/docs/v1/:path*', '/legacy/:path*'],
};

Reference: Next.js proxy matcher

Edge Config reads are globally distributed and have no rate limits. However, reading on every request does add latency (typically 1-5ms). For most sites, this is negligible. For extremely high-traffic sites, consider using Bulk Redirects for static rules.

Make sure:

  1. Your Edge Config is connected to your project
  2. The EDGE_CONFIG environment variable exists in your project settings
  3. You've deployed after connecting the Edge Config

Edge Config changes should propagate in under a second. If they don't:

  1. Check the Edge Config dashboard to confirm your changes saved
  2. Verify you're hitting the production deployment (not a preview)
  3. Clear your browser cache (browsers cache 307/308 redirects)

Check your matcher config. Make sure your redirect paths aren't accidentally excluded. The default excludes _next, api, and static files.

You now have redirects that update instantly without redeploying:

  1. Store redirect rules in Edge Config
  2. Read them from Next.js proxy on each request
  3. Update rules via dashboard or API, changes propagate globally in under a second

Was this helpful?

supported.
Dynamic redirects with Edge Config and Next.js proxy | Vercel Knowledge Base