home / skills / hoangnguyen0403 / agent-skills-standard / routing

routing skill

/skills/angular/routing

This skill guides Angular routing best practices by enforcing lazy loading, functional guards, and route data binding for robust apps.

npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill routing

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
1.1 KB
---
name: Routing
description: Standards for Angular Router, Lazy Loading, and Guards.
metadata:
  labels: [angular, routing, guards, lazy-loading]
  triggers:
    files: ['*.routes.ts']
    keywords: [angular router, loadComponent, canActivate, resolver]
---

# Routing

## **Priority: P0 (CRITICAL)**

## Principles

- **Lazy Loading**: Use `loadComponent` for standalone components and `loadChildren` for route files.
- **Functional Guards**: Use function-based guards (`CanActivateFn`) instead of class-based guards (Deprecated).
- **Component Inputs**: Enable `withComponentInputBinding()` to map route params directly to component inputs.

## Guidelines

- **Title Strategy**: Use `TitleStrategy` service to auto-set page titles from route data.
- **Resolvers**: Use `resolve` to pre-fetch critical data before navigation completes, but avoid blocking UI for too long.

## Anti-Patterns

- **Logic in Routes**: Keep route definitions clean. Move logic to Guards or Resolvers.
- **Eager Loading features**: Never direct import feature components in root routes.

## References

- [Routing Patterns](references/routing-patterns.md)

Overview

This skill documents routing standards for Angular projects, focusing on lazy loading, functional guards, and clean route definitions. It prescribes patterns that improve load performance, maintainability, and predictable navigation behavior. The guidance targets TypeScript-based Angular apps and standalone component patterns.

How this skill works

The skill inspects route configuration and recommends using loadComponent or loadChildren to enable lazy loading and avoid eager imports. It enforces function-based guards (CanActivateFn and related APIs) and suggests withComponentInputBinding() to map route params to component inputs. It also recommends TitleStrategy for automatic titles and resolve for essential pre-fetching.

When to use it

  • When defining feature module or standalone component routes to minimize initial bundle size.
  • When replacing deprecated class-based guards with functional guard APIs.
  • When route parameters should be passed directly into component inputs.
  • When page titles need to reflect route metadata consistently.
  • When critical data must be fetched before navigation completes.

Best practices

  • Use loadComponent for standalone component lazy loading and loadChildren for module-level routes.
  • Prefer functional guards (CanActivateFn / CanLoadFn) over class-based guards to align with modern Angular APIs.
  • Enable withComponentInputBinding() to bind route params to @Input properties and simplify component logic.
  • Implement TitleStrategy to set document titles from route data rather than in components.
  • Use resolve for short, essential prefetching; avoid long-running resolvers that block UI.
  • Keep route definitions declarative: move any business logic into guards, resolvers, or services.

Example use cases

  • Lazy-load a large admin feature module with loadChildren to reduce initial load time.
  • Replace an AuthGuard class with a CanActivateFn that calls an authentication service.
  • Bind :id route param directly to a ProductDetailComponent input using withComponentInputBinding().
  • Use a resolver to fetch a small user profile before activating a settings route.
  • Set titles in route data and let TitleStrategy compose page titles consistently across routes.

FAQ

When should I use loadComponent vs loadChildren?

Use loadComponent for lazy-loading standalone components. Use loadChildren when lazy-loading an NgModule or a route file that exports multiple routes or providers.

Are class-based guards still supported?

They may still work in older code, but prefer functional guards (CanActivateFn, CanLoadFn) because class-based guards are deprecated and functional APIs are simpler and tree-shakable.