Almost every Angular developer begins with *ngIf and *ngSwitch.
They're simple, intuitive, and they work… until they don't.
As your application grows, you start building heavier features — perhaps a dashboard with a side-panel inspector, or a split-screen comparison tool. You stitch pieces together with boolean flags, if checks, and switch clauses, and the UI slowly starts to feel fragile.
Then the requirements expand.
Users want customizable layouts.
They want their view state preserved.
They want the application to feel consistent, reloadable, and navigable.
Suddenly *ngIf and *ngSwitch stop feeling like the right tools.
- How many components can you manage through a switch statement?
- How do you synchronize state across multiple visible views in a dashboard?
- How do you persist that state across reloads — or expose it in the URL?
Eventually, everything points to routing.
The Realization
When I started with Angular, routing felt messy and overcomplicated.
The thing we need to understand is that if or switch clause are for handling visibility of the component, not the state.
It's not a rigid rule, but by the end of this article, the distinction will feel obvious — and you'll understand why routing solve problems that conditionals simply can't.
Why Experienced Teams Reach for Router Outlets
Engineers reach for *ngIf because it's quick. Experienced teams reach for router outlets because they want the UI to behave like a real application, not a stitched-together widget board.
Conditional Rendering: What If/Switch Really Do
When you use *ngIf or ngSwitch, the UI state:
- disappears on refresh
- isn't linkable
- isn't navigable via back/forward buttons
- can't be restored
- can't be shared through a URL
- isn't synchronized across components
It's just ephemeral UI state.
Great for tiny things. Completely breaks down for structured UIs.
Routing: A URL as a Source of Truth
Routing gives you something conditionals never can: a stable, externalized state machine.
If your dashboard URL looks like:
/dashboard(main:details//left:filters//right:info)
The user can:
- bookmark it
- reload it
- share it
- open it in a new tab
- use the back button
- restore it after browser restart
Try doing that with:
showFilters = true
You can't.
This matters massively for:
- admin dashboards
- analytics tools
- IDE-like applications
- UIs with inspectors, drawers, secondary panels
Anywhere the layout itself matters, routing becomes mandatory.
Routing Makes UI Behavior Deterministic
If the UI is controlled through routes, state transitions look like this:
click → router.navigate() → new URL → new component loads
That chain gives you:
- clean separation between view containers and components
- testability (you can test routing instead of brittle DOM states)
- predictable teardown + instantiate cycles
With *ngIf, components stick around until destroyed manually, and transitions become messy:
- stale subscriptions
- memory leaks
- state leftover from previous view
- components not re-instantiating properly
You've seen these bugs before — they're everywhere in legacy systems.
Routing Gives Independent Lifecycles Per Outlet
Multiple outlets each manage their own component lifecycle.
Example:
<router-outlet name="sidebar"></router-outlet>
<router-outlet name="details"></router-outlet>
Each one:
- resolves guards
- runs resolvers
- loads modules lazily
- handles deactivation/activation
- destroys previous component cleanly
*ngIf can't replicate this without manually re-implementing the router.
Routing Lets Your UI Behave Like a Real Application
Does the user expect browser navigation to work?
If the UI has panels that open/close, details that load, tabs, filters, etc. —
Users expect:
- Ctrl+L → paste URL → exact same state
- Back → previous view
- Forward → next view
- Reload → same data, same layout
An *ngIf-driven UI can't honor these expectations.
The Real Reason People Avoid Routing
Most engineers don't understand auxiliary routes and named outlets.
The moment they learn them, they stop writing giant "HTML Franken-templates" with 15 nested *ngIf conditions.
Routing scales. *ngIf doesn't.
Clean Distinction to Remember
- Use routing when the user's view should be restorable, shareable, navigable, or modular.
-
Use
*ngIfwhen the UI state is unimportant, temporary, or purely local.
This is the same reason VSCode, Figma, Jira, GitHub, and all advanced UIs use router-like state machines — not ad-hoc conditionals.
At this point we've only seen why routing beats conditional rendering for complex UIs. In the next article, I'll go deeper into how to use Angular's outlet contexts and multi-outlet routing to treat the router as a true state-management layer for view composition.
Top comments (0)