Configuring routes is the process of defining the map of your application. It's where you declare which URL leads to which piece of content.
1The Importance of Order
Angular's router uses a 'First-Match Wins' strategy. When the URL changes, it starts at the top of your routes array and checks each path sequentially. This is why more specific routes (like /users/profile) must come BEFORE more general routes (like /users). Most importantly, the wildcard route (**) must always be the last entry, otherwise it will intercept every navigation attempt before they can match your intended paths.
2Redirection Logic
Redirects are essential for a good UX. Instead of leaving the user on a blank screen at the root domain, use redirectTo to guide them to your primary feature. The pathMatch: 'full' property is critical here: without it, the empty string '' would technically match every URL (since every string starts with an empty string), potentially causing infinite redirection loops.
3Step-by-Step Breakdown
Configuration is where we map paths to components. This is usually done in a dedicated file called app-routing.module.ts.
Routes are an array of objects. Each object needs a 'path' (the URL segment) and a 'component' to display.
We initialize this array in the imports of our module using RouterModule.forRoot(routes). This registers the routes globally.
Checkpoint: Which method is used to initialize the main application routes in the root module?
- βRouterModule.forRoot(routes)
- βRouterModule.forChild(routes)
What about the base URL (empty path)? We can use 'redirectTo' to send users from the root to a default page like '/home'.
When using an empty path, 'pathMatch: full' is required. It tells Angular to only redirect if the ENTIRE URL is empty.
Checkpoint: When redirecting from an empty path (''), which property must be set to 'full'?
- βstrategy
- βpathMatch
Finally, the Wildcard route '**'. It matches everything. Use it at the VERY END of your array to handle 404 errors.
Order matters! Angular matches from top to bottom. If you put the wildcard first, no other routes will ever be reached.
Next, we'll look at how to trigger these routes programmatically inside your components.
Level Up π
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1A Wildcard 404 Route Needs to Be a Genuinely Usable Page, Not a Dead End
The `path: '**'` catch-all route should render real, navigable content β a heading, an explanation, and a link back to a working page β rather than a blank component, since users who land there via a broken or outdated link need a way forward.
2Route `data` Properties Are a Clean Place to Attach Per-Route Accessibility Metadata
Attaching a `data: { pageTitle: '...' }` property to each route definition gives you a single, centralized place to drive both the document title and any route-change announcement text, rather than duplicating that string inside each routed component.
SEO Implications
- 1
Route Order Matters β a Greedy Route Can Shadow More Specific Ones
Angular matches routes in the order they're defined; a broadly matching route (or the wildcard `**`) placed too early in the array can intercept requests meant for a more specific route defined after it, effectively hiding that page from ever being reached, including by crawlers following internal links.
- 2
Every Meaningful Route Should Set Its Own Title via Route `data` or a Resolver
Centralizing per-route title logic (often combined with Angular's `Title` service in a route-change subscription) ensures every indexable page gets a distinct, descriptive `<title>` rather than inheriting one generic app-wide title.
Best Practices
Always Place the Wildcard (`**`) Route Last in the Routes Array
Since Angular matches routes top-to-bottom and stops at the first match, the catch-all wildcard route must be the final entry β placing it earlier would cause it to match and shadow every subsequent route definition.
Use Route Guards for Access Control, Not Just Conditional Rendering Inside Components
A `CanActivate` guard prevents a route from resolving at all when access should be denied, which is more robust than letting the route load and then conditionally hiding content inside the component β the guard-based approach also avoids briefly flashing protected content before a component-level check catches up.
Frequent Bugs
A specific route (like `/users/new`) unexpectedly renders the component meant for a dynamic parameter route (like `/users/:id`).
The dynamic `/users/:id` route is defined before the more specific `/users/new` route in the routes array β Angular matches top-to-bottom and treats 'new' as a value for the `:id` parameter. Reorder the array so more specific static routes come before dynamic parameter routes that could otherwise match them.
The wildcard 404 route intercepts navigation to a route that should otherwise exist and work.
The `path: '**'` route was accidentally placed before other route definitions in the array β since it matches literally everything, any route listed after it becomes unreachable. Move the wildcard route to the very end of the array.
Real-World Examples
Correctly Ordered Route Configuration With a Real 404 Page
A routing module lists static routes before dynamic parameter routes, with the wildcard catch-all last, ensuring every route is reachable and unmatched URLs land on a genuinely useful 404 page.
const routes: Routes = [
{ path: 'users/new', component: NewUserComponent },
{ path: 'users/:id', component: UserDetailComponent },
{ path: '**', component: NotFoundComponent }
];