# Incremental Migration / Strangler Fig > Replace a legacy frontend route-by-route behind a shared proxy. Frontend architecture guidance from fearchitect, written by Abas Turabli and last reviewed 2026-06-21. Source: https://fearchitect.com/topics/incremental-migration-strangler-fig Use it as reference for the task at hand. Before changing code, check this guidance against the codebase: where the code already makes a different, deliberate choice, flag the conflict instead of rewriting it. Library APIs move faster than this guide, so confirm exact signatures in the official docs linked at the end. ## Summary The Strangler Fig pattern lets you migrate a legacy frontend without a big-bang rewrite: a router or proxy sits in front of both apps and forwards each path to whichever app owns it. New routes go to the modern app; old routes stay on the legacy app until you port them. The surface exposed to users never changes. ## Strangler Fig A strangler fig vine grows around an existing tree, eventually replacing it. Applied to frontends, a **proxy layer** — Next.js rewrites, a CDN rule, or a reverse proxy — routes each URL to one of two apps in parallel: the legacy app and the replacement. Migrate one route at a time. The legacy app never knows it lost a path. Once every route is migrated, remove the proxy and shut it down. **Multi-Zones** is the Next.js multi-app variant: each zone is a separate Next.js deployment with its own `assetPrefix`. The primary zone proxies others via rewrites — used when teams own distinct path prefixes and need independent deployments. ## Route-by-route migration ### 1. Stand up the new app with a fallback rewrite Deploy the new Next.js app with a `fallback` rewrite pointing to the legacy origin. All traffic passes through to legacy — no visible change yet. ### 2. Build pages in the new app Each page file you add automatically shadows the fallback. Next.js checks its own filesystem before running fallback rewrites — no rule update needed. ### 3. Track progress objectively Compare the `next build` route manifest against the legacy sitemap. The ratio gives a percentage complete. Set a hard deadline or migration stalls. ### 4. Cut over and decommission Once every route is migrated, remove the proxy config and shut down the legacy origin. Rollback at any point is a one-line rewrite change. ## Diagram ```mermaid flowchart LR Browser -->|"GET /any-path"| Proxy["Next.js (new app) next.config.js rewrites"] Proxy -->|"Route exists in new app"| NewApp["New app handler"] Proxy -->|"fallback: /:path*"| Legacy["Legacy origin"] ``` The new Next.js app acts as a proxy: owned routes are served locally; unported routes fall through to the legacy origin. ## Next.js fallback rewrite to legacy origin Add this to `next.config.js` in the new app. Owned pages shadow the fallback automatically. ```js // next.config.js module.exports = { async rewrites() { return { // Checked only after Next.js finds no matching page fallback: [ { source: "/:path*", destination: `${process.env.LEGACY_ORIGIN}/:path*`, }, ], }; }, }; ``` Add a page file and that route is migrated — no rule update needed. Remove the fallback config once legacy is decommissioned. ## Watch out: Multi-Zones: two gotchas Use `` not `` for cross-zone navigation — Next.js tries client-side routing across zone boundaries and fails. Set `assetPrefix` in each zone or zones collide on `/_next/static` paths. ## Key terms - **Strangler Fig**: Migration pattern where new code wraps and gradually replaces a legacy system route by route. - **fallback rewrite**: Next.js rewrite checked last — after filesystem and dynamic routes — used to proxy unported paths to a legacy origin. - **Multi-Zones**: Next.js approach for running multiple independent Next.js apps under one domain, each owning distinct path prefixes. - **assetPrefix**: Next.js config option that namespaces a zone's `/_next/static` assets to prevent collisions with other zones. - **big-bang rewrite**: Replacing an entire app in one release; high risk because the new app must be feature-complete before any cutover. ## Related topics - [Microfrontends & Module Federation](https://fearchitect.com/topics/microfrontends-module-federation.md): Independently deployable frontends composed at runtime in the browser. - [Monorepos (Turborepo / Nx)](https://fearchitect.com/topics/monorepos.md): One git repo, many packages, shared tooling and task caching. - [Deployment Strategies & Feature Flags](https://fearchitect.com/topics/deployment-strategies-feature-flags.md): Decouple deploy from release using blue-green, canary, and flags. - [Backend for Frontend (BFF)](https://fearchitect.com/topics/backend-for-frontend.md): A per-client server layer that shapes and aggregates APIs for one frontend. - [API Gateway (for Frontends)](https://fearchitect.com/topics/api-gateway.md): Single entry point that routes, authenticates, and rate-limits across services. - [Component Architecture & Project Structure](https://fearchitect.com/topics/component-architecture.md): Structuring components so composition beats configuration. ## Further reading - [Next.js docs — Rewrites (incremental adoption)](https://nextjs.org/docs/app/api-reference/config/next-config-js/rewrites) - [Next.js docs — Multi-Zones](https://nextjs.org/docs/app/guides/multi-zones) - [Martin Fowler — Strangler Fig Application](https://martinfowler.com/bliki/StranglerFigApplication.html)