On this page ▾
Router
The Routes tab reads the running app's Router. The top section, Live router, has five views. The bottom section, Source route config, lists the routes your files declare. When more than one page is connected, a Page picker chooses which one you see.
What it shows
Current
The route the page is on:
- The URL, and the browser URL when the two differ.
- The navigation in flight, with an Abort button.
- The document title, query params and fragment.
- Active routes: each active route with its component, params, data, and guards and resolvers. Tags mark lazy routes, inherited params, and whether a data value is static, resolved or inherited. The title row says when the title is inherited.
- Outlets: the outlet tree, with the inputs the router binds to each component and the
routerOutletDataeach outlet passes (what the routed component reads withinject(ROUTER_OUTLET_DATA)). The data shows as a redacted preview of at most 300 characters.
Navigations
Every navigation as one story:
- Where it came from, and who started it: a
RouterLink, the code that callednavigate, or back and forward. - The extras, redirect chains and loops.
- A phase bar: recognize, guards, resolve, activate.
- Guards and resolvers, lazy loads, reused components, HTTP requests, scroll, and the title afterwards.
- Router warnings, and the cancel or error reason. The tab explains NG04xxx errors.
- When the navigation error handler redirects, the navigation names the error handler as the cause and keeps the error that triggered it, with its error code.
Filter by URL, or check Only problems to keep the navigations that did not succeed and the ones in a loop. Each row has Replay and Copy repro (a markdown repro). Replay is off for a navigation whose URL is redacted or not relative, and a note under the row says why. Export JSON saves the list.
Loop detection
The Navigations view looks for loops in the recorded navigations. A loop is a chain that comes back to a URL it already visited:
| Loop | What the view detects |
|---|---|
| redirect loop | A chain of redirects returns to an earlier URL. The chain follows canMatch, guard, resolver and error handler redirects from one navigation to the next, plus the redirectTo inside each navigation. |
| navigation loop | Your code calls navigate or navigateByUrl within 500 ms of the previous navigation ending, and the chain returns to an earlier URL. |
redirect loop (NG04016) |
Angular stops a navigation with NG04016 because redirectTo entries of the config form a cycle. |
To see one, open the Routes lab of the demo app (/examples/routes). Guard loop makes two guards redirect to each other five times, then to Summary (a redirect loop). Navigation ping-pong navigates between Details and Summary from code (a navigation loop).
When the view finds a loop, a Loop detected section appears above the list. It shows the cycle of URLs, such as /account → /login → /account. Under it, each hop names its cause: the guard, the redirectTo entry or the navigate call. A last line lists the navigation ids, how many times the chain came back, how it ended and the guards involved.
Each navigation in a loop gets a loop badge and a red edge. Its details gain a Loop row with the cycle and the hop this navigation caused.
Routes
The live route config. The tab merges lazy children in once they load, and marks the active branch.
- Test a URL and click Predict to see which route matches it, or the nearest ones.
- Probe in app runs the real matcher without navigating.
- Fill in the params of a route and click Go to navigate to it. With a param left empty, Go marks the empty field and names the params to fill in.
- Read lazy reads the routes of a lazy route that has not loaded.
The result of Go and Read lazy shows under the row you clicked.
Setup
How the router is set up: provideRouter or forRoot, the effective options with set or default badges, the enabled features, the strategies, the base href and hydration.
initialNavigation shows the mode that withEnabledBlockingInitialNavigation(), withDisabledInitialNavigation() or the forRoot option sets. The features map to these router features:
| Feature | Source |
|---|---|
componentInputBinding |
withComponentInputBinding() or bindToComponentInputs |
viewTransitions |
withViewTransitions() or enableViewTransitions |
navigationErrorHandler |
withNavigationErrorHandler() |
routerResources |
Router resources |
injectorCleanup |
withExperimentalAutoCleanupInjectors() |
preloading |
withPreloading() or preloadingStrategy, with the strategy name |
scroller |
withInMemoryScrolling() or the forRoot scrolling options |
debugTracing |
withDebugTracing() or enableTracing |
platformNavigation |
withExperimentalPlatformNavigation() (Angular 21.1 and later) |
Lint
Route config mistakes, each with a fix:
- Unreachable routes after
**, and duplicate paths. - A
:paramthat shadows a literal path. - Empty-path redirects without
pathMatch: 'full', and redirect cycles. - Redirect loops seen at runtime (rule
redirect-loop), with the hops and the guards involved. - Deprecated class guards and
canLoad. - Lazy chunks downloaded before a rejecting
canActivate. - Missing or duplicate titles, and param or input typos.
routerLinkActivewithoutariaCurrentWhenActive.- Emails in URLs, and return URLs taken from query params.
Each finding says whether Angular throws, warns or does not warn. The lint skips lazy routes that have not loaded. It runs again after each navigation and config change, and keeps the current findings on screen while it does. Click Check again to rerun it.
If no check could run, the view says No checks ran and why: the page runs in events-only mode, or it has not reported its route config yet. If the DevTools server does not answer, the view shows an error with Retry.
Source route config
The routes declared in your files: *.routes.ts and *routing.module.ts files, the files they lazy load, and Analog pages. Each row shows the path, the component or target, guards and resolvers, the title and the declaring file. Once the live config is available, the tab collapses this table. Show table opens it.
Components rendered by the router show their route and outlet in the Components tab.
Where the data comes from
*.routes.server.ts for render modes.
Finding the Router
The overlay reads the helper provideRouter() publishes (ng.ɵgetRouterInstance). For RouterModule.forRoot() apps, and on Angular 20.0 to 20.3.4 (which lack the helper), it looks for the Router token in the injectors instead. With several app roots, the router that has routes or has navigated wins.
Development builds
The live views need window.ng, so they need a development build. In a production build the overlay finds no Router, and Current says This page reports no Router.
When the debug API exists but lacks the provider helpers, the tab runs in events-only mode. The Setup view says so, and the config, lint and actions are limited.
Guard verdicts
The router reports one result for all the guards of a navigation. To see each guard's verdict and time, the devtools wrap every guard and resolver in the live config. Each row shows the guard, the route, its result (such as UrlTree /login) and its time.
Without that recording, the guards listed for a navigation are candidates: the canDeactivate guards of the page being left, and the canActivate and canActivateChild guards of the target.
How to use it
Find out why a navigation failed
false or a UrlTree.
Check which route a URL hits
canMatch and may load lazy chunks.
Clean up the config
Agent tools
| Tool or resource | What it does |
|---|---|
ng-devtools:explain-navigation |
Why a navigation failed or redirected, with any loop and the cause of each hop. Pass url or id to narrow it, limit for more than the last 5, or perf for the slowest ones. |
ng-devtools:inspect-route |
The route the page is on. Pass selector (a component class, tag or link text) for the route a component was rendered for, or a link state. |
ng-devtools:list-routes |
The live config with source files and example URLs. match predicts a URL, audit lists the guards of each page. |
ng-devtools:lint-routes |
The lint findings, including redirect loops seen at runtime. |
ng-devtools:router-config |
The setup, including whether guard recording is on. |
ng-devtools:export-navigation |
A markdown repro, with any loop the navigation is part of. Defaults to the latest navigation that did not succeed. |
ng-devtools:explain-render-mode |
Which render mode a URL gets, from *.routes.server.ts. |
ng-devtools:get-routes |
Routes from your source files. |
ng-devtools:navigate |
Acts on the router: navigate, abort, replay, probe, instrument and resolve-lazy. |
ng-devtools:router (resource) |
The active route tree and recent navigations of each page. |
navigate only accepts same-origin relative URLs that start with /. resolve-lazy needs a routeId. With actions.router set to false, the tool refuses navigate, abort, replay and probe, and keeps instrument and resolve-lazy. See Tools.
Limits and gotchas
Guard recording is on by default
Record each guard and resolver in the Navigations view starts checked. Uncheck it to stop. Turning it off puts every original guard and resolver back. The page keeps the choice per browser tab, in sessionStorage, so it survives a reload. If the page does not answer, the checkbox returns to its previous state and the view shows the error. Agents use navigate with action: "instrument" and on.
Setup kind on Angular 20.0 to 20.3.4
Set up with tells provideRouter from forRoot by the ng.ɵgetRouterInstance helper. Angular 20.0 to 20.3.4 never publish it, so on those versions the row shows unknown.
Abort and probe need Angular 20.2
Aborting and probing use the currentNavigation signal and Navigation.abort(), which older versions lack. On those versions the action returns an error.
Navigations before the devtools connected
The tab lists only the last one, marked before DevTools connected, without timing or guard details. It also lists a navigation still running at that moment.
Redaction
The devtools replace query, matrix and fragment values with secret-looking keys with [redacted]. They also redact tokens, Bearer values, and route params with secret-looking names such as :token. You can't replay a navigation with a redacted URL. See what the devtools redact.
History and config caps
The page keeps the last 50 navigations and 50 preloads. Set the navigation count with limits.navigations. Once older navigations are dropped, the Navigations view and explain-navigation say how many. The live config lists at most 200 routes per level (a route's children and its loaded lazy routes count as one level) and 1000 routes in total. The Routes view and ng-devtools:list-routes say how many routes were left out.
FAQ
skipLocationChange and stops after recognition. canActivate, canDeactivate and resolvers do not run. If a canMatch guard or the navigation error handler redirects, the probe stops the redirected navigation too and names its target.
canMatch guards, so actions.router set to false turns it off, along with Go, Abort and Replay. Record each guard and resolver and Read lazy stay on.