Feature flags and route switches in an incremental migration
A migrated screen should reach production behind a switch. If something is wrong, you turn it off and users are back on the old version in minutes. Here is how to set that up and keep it tidy.
What the switch does
During an incremental migration, the old and the new version of a screen exist at the same time for a short period. A switch decides which one a user gets. You deploy the code first, turn it on for a few people, watch, and widen the audience when you are satisfied.
There are two common forms:
- Route switch. The router decides whether a URL is handled by the new screen or falls through to the legacy one.
- Feature flag. A named setting, evaluated per user or per customer, that the route switch reads.
In practice you use both together: a flag per migrated screen or module, read by the router.
A minimal route switch
In Angular, a route can be made conditional with a canMatch guard. If the guard returns false, the router continues to the next matching route, which is the legacy fallback.
export const routes: Routes = [
{
path: 'invoices',
canMatch: [() => inject(FlagService).isOn('invoices-v2')],
loadComponent: () => import('./invoices/invoices.component')
.then(m => m.InvoicesComponent),
},
// anything not matched above is rendered by the legacy app
{ path: '**', component: LegacyHostComponent },
];
FlagService and LegacyHostComponent are example names for your flag reader and for the component that hosts the legacy application. The URL is the same in both cases, so bookmarks and links keep working whichever version is active.
Where the flags live
You do not need a paid product to start.
| Option | How it works | Good for |
|---|---|---|
| Config endpoint | The app loads a small JSON with the flags at startup | Most migrations with one team |
| Per-user or per-customer setting | The backend returns flags together with the user profile | Rollout by customer or role |
| Flag platform | A dedicated service with targeting rules and a dashboard | Several teams, percentage rollouts, audit trail |
The essential property is that a flag can change without a new deployment. A flag compiled into the bundle only helps during development.
A rollout sequence
- Deploy dark. The new screen is in production with its flag off. Nothing changes for users.
- Internal users. Turn the flag on for the team and for QA. Run the end-to-end tests against both versions.
- A small real group. A few friendly customers or one office. Watch errors and support tickets.
- Everyone. Turn the flag on for all users.
- Soak. Keep the legacy version available for a fixed period that you agreed beforehand.
- Delete. Remove the legacy screen and the flag itself.
What makes rollback safe
A rollback only works if the old screen can still handle the data the new screen produced.
- Keep the same API during the switch. If both versions call the same endpoints with the same payloads, a user can move between them freely.
- Do not change the data model in the same release. Backend changes that the legacy screen cannot read make the switch one-way.
- Keep the URL identical. Same path and same query parameters.
- Share the session. Turning a flag off must never sign anyone out.
If a migrated screen needs a backend change, release the backend change first, in a form both versions can use. Then switch the screen. Two changes behind one flag cannot be rolled back independently.
Watch both versions
A flag is only useful if you can see what happens after you turn it on.
- Tag frontend errors with the screen and the version that produced them.
- Compare the error rate of the new version with the legacy one for the same screen.
- Track the key action of the screen, for example orders submitted. A drop is a signal even when no error is logged.
- Agree in advance who can turn a flag off and under which conditions. During an incident nobody should have to ask for permission.
Flag hygiene
Migration flags are temporary. Left alone, they pile up and turn into a second kind of legacy.
- Give each flag an owner and a removal date when you create it.
- Use a naming rule, for example a
migration-prefix, so they are easy to list. - Make flag removal part of the definition of done. A screen is finished when the legacy code and the flag are both gone.
- Report the number of open migration flags each month. It should stay low and stable. See measuring migration progress.
How this fits the larger pattern
Flags are the release mechanism of the strangler fig pattern. The pattern says which piece moves next. The flag decides who sees it and gives you the way back. Together they address the regression risk described in migration risks and how to reduce them. The step-by-step migration itself is in How to migrate AngularJS to Angular without downtime.
More in this section
- Leaving AngularJS: Angular or React?
- Migrating a jQuery-heavy app to a component framework
- Migrating Backbone, Knockout and old Ember applications
- Migrating AngularJS that lives inside ASP.NET MVC
Planning a migration or a micro-frontend platform?
In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.
Message me on LinkedIn