Parameters are the variables of your URL. They allow a single component to handle an infinite number of unique data points.
1The ParamMap
Angular provides parameters through the paramMap. It's a specialized object that makes it easy to retrieve values by key. Whether you use the snapshot for a quick initialization or subscribe to the paramMap observable for reactive updates, this service is your gateway to the URL's data. It ensures that your components are decoupled from specific hard-coded paths and can instead react to whatever information is provided in the URL segments.
2Snapshot vs. Observable
Choosing between snapshot and observable is a critical design decision. If you are certain a component will always be destroyed before its parameters change (like navigating from a List to a Detail view), snapshot is simpler and cleaner. However, if your UI allows the user to jump between items (like a 'Next Product' button), you must use the Observable approach. This allows Angular to reuse the same component instance while still updating the data on the screen as the ID changes.
3Step-by-Step Breakdown
Dynamic routes allow you to use a single component to display data for many different items. We do this with parameters.
In your config, use a colon ':' to mark a segment as dynamic. This creates a variable in the URL.
Inside the component, we need to read that ':id'. We inject the 'ActivatedRoute' service to get information about the current route.
Checkpoint: Which service do we inject to access the current URL's parameters?
- →Router
- →ActivatedRoute
We can get a 'snapshot' of the route data. This is a one-time read of the parameters when the component is first created.
If the URL changes from /user/1 to /user/2 while the component is still visible, the snapshot won't update. You'd need an Observable for that!
Checkpoint: Does the 'snapshot' property automatically update if the URL parameter changes while the user is still on the same page?
- →Yes, it's reactive
- →No, it's a one-time static read
Dynamic routing is the key to building scalable applications like dashboards and profile pages. Incredible progress!
Next, we'll learn about Child Routes and Lazy Loading for advanced architectures.
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)
1Reused Components Across Param Changes Need Focus Management Too
Angular can reuse the same component instance when only a route parameter changes (e.g., navigating from `/product/1` to `/product/2`) — since there's no fresh component creation, no focus change happens automatically, so screen reader users may not realize the content actually changed.
2Update the Document Title on Every Param Change, Not Just Route Change
If a component is reused across parameter changes, remember to explicitly update the page `<title>` via Angular's `Title` service inside your param-subscription logic — it won't update on its own just because the URL segment changed.
SEO Implications
- 1
Each Unique Dynamic Route Should Be an Independently Indexable, Linkable URL
A product page at `/product/42` with real content specific to that ID is exactly the kind of dynamic route search engines can index individually — this only works if the content is actually present in server-rendered HTML for that specific parameter, which requires SSR/prerendering per param value.
- 2
Prerendering Every Possible Dynamic Route Value Usually Isn't Feasible — Plan for SSR Instead
For routes with parameters pulled from a large or changing dataset (like product IDs), build-time prerendering of every possible URL doesn't scale — Angular Universal's on-demand server-side rendering per request is the practical approach for this pattern.
Best Practices
Subscribe to `ActivatedRoute.paramMap` Rather Than Snapshotting Once
`route.snapshot.params` only captures the value at the moment the component was created — if Angular reuses the component instance across a param change (a common optimization), a one-time snapshot read will silently miss the update. Subscribing to `paramMap` reacts correctly every time.
Validate and Type-Convert Route Parameters Before Using Them
Route params always arrive as strings, even for what's conceptually a numeric ID — explicitly parse and validate them (`Number(id)`, checking for `NaN`) before using them in API calls or comparisons, rather than assuming they're already the right type.
Frequent Bugs
Navigating from one product detail page to another (e.g., `/product/1` to `/product/2`) doesn't update the displayed content.
The component read the route parameter once via `route.snapshot.params` in `ngOnInit`, but Angular reused the same component instance across the param change (since it's the same route, just a different parameter), so `ngOnInit` never re-ran. Subscribe to `route.paramMap` instead, which emits on every change.
A route parameter used directly as a numeric value causes unexpected string concatenation or NaN errors.
Route parameters are always extracted as strings from the URL, regardless of what they conceptually represent. Explicitly convert with `Number(param)` (and validate the result isn't `NaN`) before using it in arithmetic or type-sensitive comparisons.
Real-World Examples
Reactive Product Detail Page
A product detail component correctly reacts to param changes even when Angular reuses the component instance across navigations between different product IDs.
ngOnInit() {
this.route.paramMap.subscribe(params => {
const id = Number(params.get('id'));
this.productService.getProduct(id).subscribe(p => this.product = p);
});
}