CMS & Framework Routing Changes
Context
When you restructure routes or permalinks during a migration, the redirect logic can live in three very different places depending on the stack: a CMS plugin, a framework config file, or the web server in front of it. WordPress, Next.js, and Nuxt each expose their own redirect mechanism, and each has a server-level fallback that behaves differently for crawl budget, latency, and method preservation. Choosing the wrong layer produces redirect chains, lost query strings, or rules that silently stop firing after a deploy. This section sits under the broader URL Mapping & Redirect Architecture playbook and covers the per-stack decisions that generic server rules cannot make for you.
The teams that hit this hardest are those changing both the routing scheme and the framework at once — for example moving a WordPress blog onto a headless Next.js front end, or migrating a Nuxt 2 site to Nuxt 3 with new route rules. The timing matters: framework-native redirects ship with the application build, so they only take effect after deploy, whereas server rules can be staged ahead of cutover.
Pre-flight Checks
- Confirm which layer terminates TLS and sees the request first (CDN, Nginx, Apache, or the app server) — this is your lowest-latency redirect point.
- Export the complete legacy URL list and the new route scheme into a versioned map before writing any rules.
- Note the current permalink/route format exactly (trailing slashes, case, locale prefixes) so rules match byte-for-byte.
- Verify deploy cadence: framework-native redirects only go live with the next application build.
- Check whether query strings, locale prefixes, or pagination parameters must be preserved or rewritten.
- Have a staging host that mirrors production routing so rules can be tested before cutover.
Execution Steps
1. Decide the Owning Layer Per Rule
For each redirect, pick exactly one layer that owns it — server/edge, framework, or CMS plugin — and never let two layers redirect the same path. Server-level rules win on latency and can be staged before the app deploys; framework-native rules win when the redirect depends on application state. Document the choice in your map so a later deploy does not silently shadow a server rule.
2. Restructure WordPress Permalinks
If WordPress is in scope, change the permalink structure once and generate a deterministic 301 map from old to new slugs rather than relying on the database’s internal guesswork. Decide up front between the Redirection plugin (application layer) and .htaccess/Nginx rules (server layer); see migrating WordPress permalinks without losing rankings for the WP-CLI export and rule generation.
3. Configure Next.js Redirects
For Next.js, prefer the static redirects() array in next.config.js for predictable path changes, and reserve middleware for redirects that need request inspection (cookies, headers, geo). The full breakdown of permanent vs temporary flags and has/missing matchers is in configuring Next.js redirects during domain migration.
4. Handle Nuxt Route Changes
For Nuxt 3, route changes are expressed as routeRules in nuxt.config, executed by the Nitro server, with server middleware available for dynamic cases. See handling Nuxt route changes during site migration for the redirect rule syntax and Nitro middleware patterns.
5. Flatten and Validate Cross-Layer Chains
After wiring framework or plugin rules, re-crawl to catch chains created when an old server rule and a new framework rule both fire on one URL. Apply Redirect Chain Elimination to collapse any multi-hop sequence into a single 301, then confirm with curl -IL.
Configs / Commands
WordPress — flush rewrite rules after a permalink change (WP-CLI):
# Re-write .htaccess / rewrite rules after changing permalink structure in the admin
wp rewrite structure '/%category%/%postname%/' --hard
wp rewrite flush --hard
Next.js — static redirects array (next.config.js):
// Static redirects evaluated at the edge before rendering
module.exports = {
async redirects() {
return [
{ source: '/blog/:slug', destination: '/articles/:slug', permanent: true }, // 308
];
},
};
Nuxt — route-level redirect (nuxt.config):
// Nitro serves these redirects without running the page component
export default defineNuxtConfig({
routeRules: {
'/blog/**': { redirect: { to: '/articles/**', statusCode: 301 } },
},
});
Server fallback — Nginx catch-all for the legacy prefix:
# Lowest-latency layer; stage this before the app deploy if possible
location ^~ /blog/ {
return 301 /articles/$uri$is_args$args;
}
Validation
- Confirm each migrated path returns a single hop:
curl -sIL https://www.example.com/blog/old-post | grep -iE '^HTTP|^location'should show one 301 then the final 200. - Check no path is redirected by two layers — a double
301in thecurl -ILtrace means server and framework rules overlap. - Verify query strings survive: request
/blog/post?utm_source=xand confirmutm_sourceappears on theLocationtarget. - After deploy, watch server logs for 404 spikes on the old route pattern indicating a missing map entry.
Rollback Triggers
- Redirect error rate on migrated paths exceeds 2% of requests over a 15-minute window — revert framework config and re-enable the prior server rules.
- Any redirect chain longer than 1 hop appears on a top-traffic path — disable the conflicting layer immediately.
- 404 rate on the legacy route prefix climbs above 0.5% of total traffic — restore the previous permalink/route scheme and regenerate the map.
- Median redirect latency exceeds 80 ms (indicating app-layer redirects that belong at the edge) — move the affected rules to the server/CDN layer.
FAQ
Should redirects live in the framework or at the web server? Put static, request-independent redirects at the server or edge for lowest latency and so they can be staged before the app deploys. Reserve framework or plugin redirects for rules that need application state such as auth, session, or feature flags.
Will framework redirects work before the new build is live? No. Redirects defined in next.config.js, nuxt.config, or a WordPress plugin only take effect once that application code is deployed. If you need cutover-day coverage, stage the equivalent rules in Nginx or Apache ahead of the deploy.
How do I stop two layers redirecting the same URL?
Assign a single owning layer per rule in your map and remove the duplicate. A double 301 in a curl -IL trace is the signature of an old server rule and a new framework rule both firing on one path.
Related
- Migrating WordPress Permalinks Without Losing Rankings
- Configuring Next.js Redirects During Domain Migration
- Handling Nuxt Route Changes During Site Migration
- Redirect Chain Elimination
- Regex Redirect Rules
← Back to URL Mapping & Redirect Architecture