Angular routing maps URL paths to components, enabling navigation in a single-page application without full page reloads. Routes are defined as an array of Route objects and registered with RouterModule.forRoot(routes) in module-based apps or provideRouter(routes) in standalone apps. The router-outlet directive marks where routed components render, and a wildcard path handles unmatched routes. Lazy loading delays the loading of a feature module until the user navigates to its route, configured with loadChildren or loadComponent, which reduces the initial bundle size. The forRoot method is used once in the root module to register the Router service, while forChild is used in feature modules to register additional routes without re-providing the service.
Route guards control whether navigation to or from a route is allowed. CanActivate runs before a route is activated and returns a boolean, UrlTree, or an Observable or Promise that resolves to one, with false cancelling navigation, making it ideal for checking authentication. CanDeactivate guards leaving a route, useful for warning about unsaved changes. CanLoad controls whether a lazy-loaded module loads. CanMatch runs before route matching and is preferred over CanActivate for feature flags and role-based route selection because returning false lets the router try the next route definition. Resolve pre-fetches data before a route is activated, ensuring the component has its required data before rendering and avoiding empty states. Modern Angular favors functional guards that are plain functions using inject() instead of class-based services.
The ActivatedRoute service provides information about the current route. Its params and queryParams are Observables that emit on every change, while snapshot is a non-Observable static value. Prefer paramMap over params for type safety because paramMap returns a strongly typed object with get() and getAll() methods. The runGuardsAndResolvers route property controls when guards and resolvers re-run on the same component, with options including 'paramsChange', 'paramsOrQueryParamsChange', 'always', and 'pathParamsChange'. NavigationExtras configure router.navigate() with options like queryParams, queryParamsHandling ('merge' or 'preserve'), fragment, state, replaceUrl, and relativeTo. RouterLinkActive applies a CSS class when the link is active and should be combined with [routerLinkActiveOptions]="{ exact: true }" for the root path. The router emits events during navigation, including NavigationStart, GuardsCheckStart, RoutesRecognized, ResolveStart, NavigationEnd, NavigationCancel, and NavigationError, which can be observed for loading indicators or analytics. Other advanced options include PreloadingStrategy for background loading of lazy modules, HashLocationStrategy for hash-based URLs that avoid server-side rewrites, and RouteReuseStrategy for tab-like component persistence.