> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/angular/angular/llms.txt
> Use this file to discover all available pages before exploring further.

# Defining Routes

> Learn how to define routes with paths, parameters, children, and redirects in Angular

Routes define the mapping between URL paths and the components that should be displayed. This guide covers all aspects of route configuration.

## The Route Interface

Routes are defined using the `Route` interface from `@angular/router`:

```typescript theme={null}
export interface Route {
  path?: string;
  pathMatch?: 'prefix' | 'full';
  component?: Type<any>;
  loadComponent?: () => Promise<Type<any>>;
  redirectTo?: string | RedirectFunction;
  outlet?: string;
  canActivate?: Array<CanActivateFn>;
  canDeactivate?: Array<CanDeactivateFn>;
  canMatch?: Array<CanMatchFn>;
  children?: Routes;
  loadChildren?: LoadChildren;
  data?: Data;
  resolve?: ResolveData;
  title?: string | ResolveFn<string>;
  providers?: Provider[];
  // ... more properties
}
```

<Info>
  The complete `Route` interface is defined in `packages/router/src/models.ts:567` with extensive documentation for each property.
</Info>

## Basic Route Configuration

### Simple Routes

The most basic route maps a path to a component:

```typescript app.routes.ts theme={null}
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';

export const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'contact', component: ContactComponent }
];
```

### Route Parameters

Define dynamic route segments using the `:paramName` syntax:

```typescript routes.ts theme={null}
import { UserDetailComponent } from './user-detail/user-detail.component';
import { ProductComponent } from './product/product.component';

export const routes: Routes = [
  // Single parameter
  { path: 'user/:id', component: UserDetailComponent },
  
  // Multiple parameters
  { path: 'products/:category/:id', component: ProductComponent },
  
  // Optional segments with empty path children
  { 
    path: 'search/:term',
    component: SearchComponent
  }
];
```

#### Accessing Route Parameters

Use `ActivatedRoute` to access route parameters:

```typescript user-detail.component.ts theme={null}
import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { map, switchMap } from 'rxjs/operators';

@Component({
  selector: 'app-user-detail',
  template: `
    <h2>User Details</h2>
    <p>User ID: {{ userId }}</p>
  `
})
export class UserDetailComponent implements OnInit {
  private route = inject(ActivatedRoute);
  userId: string = '';

  ngOnInit() {
    // Subscribe to parameter changes
    this.route.params.subscribe(params => {
      this.userId = params['id'];
    });
    
    // Or use paramMap for type safety
    this.route.paramMap.subscribe(params => {
      this.userId = params.get('id') || '';
    });
  }
}
```

#### Input Binding (Recommended)

With component input binding enabled, route parameters automatically bind to component inputs:

```typescript main.ts theme={null}
import { provideRouter, withComponentInputBinding } from '@angular/router';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes, withComponentInputBinding())
  ]
});
```

```typescript user-detail.component.ts theme={null}
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-user-detail',
  template: `<h2>User ID: {{ id }}</h2>`
})
export class UserDetailComponent {
  @Input() id!: string; // Automatically populated from route param
  @Input() category?: string; // Query params also work
}
```

## Wildcard Routes

Handle unknown routes with a wildcard route:

```typescript routes.ts theme={null}
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

export const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  
  // Wildcard route - must be last
  { path: '**', component: PageNotFoundComponent }
];
```

<Warning>
  Always place the wildcard route `**` last in your route configuration. Routes are evaluated in order, and the wildcard matches everything.
</Warning>

## Redirects

### Static Redirects

Redirect from one path to another:

```typescript routes.ts theme={null}
export const routes: Routes = [
  // Redirect empty path to home
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  
  // Redirect old URL to new URL
  { path: 'old-about', redirectTo: '/about', pathMatch: 'full' },
  
  // Preserve parameters in redirect
  { path: 'users/:id', redirectTo: '/user/:id', pathMatch: 'full' },
  
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent }
];
```

### Path Matching Strategies

The `pathMatch` property determines how the router matches URLs:

* `'prefix'` (default): Matches if the URL **starts with** the path
* `'full'`: Matches only if the URL **exactly equals** the path

```typescript theme={null}
export const routes: Routes = [
  // Full match required - only matches exactly '/'
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  
  // Prefix match - matches '/team', '/team/11', '/team/11/user', etc.
  { path: 'team', component: TeamComponent, pathMatch: 'prefix' }
];
```

### Dynamic Redirects with RedirectCommand

Create conditional redirects using `RedirectCommand`:

```typescript auth.guard.ts theme={null}
import { inject } from '@angular/core';
import { Router, RedirectCommand } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  const router = inject(Router);
  const authService = inject(AuthService);
  
  if (!authService.isLoggedIn()) {
    const loginUrl = router.parseUrl('/login');
    return new RedirectCommand(loginUrl, {
      skipLocationChange: true,
      state: { returnUrl: state.url }
    });
  }
  
  return true;
};
```

## Child Routes

Create nested route hierarchies with child routes:

```typescript routes.ts theme={null}
import { DashboardComponent } from './dashboard/dashboard.component';
import { OverviewComponent } from './dashboard/overview.component';
import { StatsComponent } from './dashboard/stats.component';
import { SettingsComponent } from './dashboard/settings.component';

export const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    children: [
      { path: '', redirectTo: 'overview', pathMatch: 'full' },
      { path: 'overview', component: OverviewComponent },
      { path: 'stats', component: StatsComponent },
      { path: 'settings', component: SettingsComponent }
    ]
  }
];
```

The parent component needs a `<router-outlet>` for child routes:

```typescript dashboard.component.ts theme={null}
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';

@Component({
  selector: 'app-dashboard',
  standalone: true,
  imports: [RouterOutlet, RouterLink],
  template: `
    <h1>Dashboard</h1>
    <nav>
      <a routerLink="overview">Overview</a>
      <a routerLink="stats">Statistics</a>
      <a routerLink="settings">Settings</a>
    </nav>
    <router-outlet></router-outlet> <!-- Child routes render here -->
  `
})
export class DashboardComponent {}
```

## Componentless Routes

Group routes without specifying a component:

```typescript routes.ts theme={null}
export const routes: Routes = [
  {
    path: 'admin',
    canActivate: [adminGuard], // Guard applies to all children
    data: { role: 'admin' }, // Data shared with children
    children: [
      { path: 'users', component: AdminUsersComponent },
      { path: 'settings', component: AdminSettingsComponent },
      { path: 'reports', component: AdminReportsComponent }
    ]
  }
];
```

## Route Data and Title

### Static Data

Pass static data to routes:

```typescript routes.ts theme={null}
export const routes: Routes = [
  {
    path: 'profile',
    component: ProfileComponent,
    data: {
      title: 'User Profile',
      animation: 'ProfilePage',
      breadcrumb: 'Profile'
    }
  }
];
```

```typescript profile.component.ts theme={null}
import { Component, OnInit, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-profile',
  template: `<h1>{{ title }}</h1>`
})
export class ProfileComponent implements OnInit {
  private route = inject(ActivatedRoute);
  title = '';

  ngOnInit() {
    this.route.data.subscribe(data => {
      this.title = data['title'];
    });
  }
}
```

### Page Titles

Set page titles for better SEO and user experience:

```typescript routes.ts theme={null}
export const routes: Routes = [
  { 
    path: 'home', 
    component: HomeComponent,
    title: 'Home - My App' 
  },
  { 
    path: 'about', 
    component: AboutComponent,
    title: 'About Us - My App' 
  },
  {
    path: 'user/:id',
    component: UserComponent,
    title: userTitleResolver // Dynamic title
  }
];
```

```typescript user-title.resolver.ts theme={null}
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { UserService } from './user.service';

export const userTitleResolver: ResolveFn<string> = (route, state) => {
  const userService = inject(UserService);
  const userId = route.paramMap.get('id');
  return `User ${userId} - My App`;
};
```

## Custom URL Matchers

For complex URL patterns, use custom matchers:

```typescript file-matcher.ts theme={null}
import { UrlSegment, UrlMatchResult } from '@angular/router';

export function fileUrlMatcher(segments: UrlSegment[]): UrlMatchResult | null {
  // Match URLs ending with .html
  if (segments.length === 1 && segments[0].path.endsWith('.html')) {
    return {
      consumed: segments,
      posParams: {
        filename: new UrlSegment(segments[0].path, {})
      }
    };
  }
  return null;
}
```

```typescript routes.ts theme={null}
export const routes: Routes = [
  {
    matcher: fileUrlMatcher,
    component: FileViewerComponent
  }
];
```

<Info>
  URL matchers provide flexibility for routes that can't be expressed with standard path syntax. See `packages/router/src/models.ts:181` for the `UrlMatcher` type definition.
</Info>

## Route Providers

Provide services scoped to a route and its children:

```typescript routes.ts theme={null}
import { provideHttpClient } from '@angular/common/http';
import { DataService } from './data.service';

export const routes: Routes = [
  {
    path: 'feature',
    component: FeatureComponent,
    providers: [
      DataService,
      provideHttpClient()
    ],
    children: [
      // Children can inject DataService
    ]
  }
];
```

## Complete Example

Here's a comprehensive route configuration:

```typescript app.routes.ts theme={null}
import { Routes } from '@angular/router';
import { authGuard } from './guards/auth.guard';
import { adminGuard } from './guards/admin.guard';

export const routes: Routes = [
  // Root redirect
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  
  // Simple routes
  { path: 'home', component: HomeComponent, title: 'Home' },
  { path: 'about', component: AboutComponent, title: 'About' },
  
  // Route with parameters
  { 
    path: 'user/:id', 
    component: UserDetailComponent,
    title: userTitleResolver
  },
  
  // Protected routes
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [authGuard],
    children: [
      { path: '', component: DashboardHomeComponent },
      { path: 'profile', component: ProfileComponent },
      { path: 'settings', component: SettingsComponent }
    ]
  },
  
  // Admin routes with guard
  {
    path: 'admin',
    canActivate: [adminGuard],
    data: { role: 'admin' },
    children: [
      { path: 'users', component: AdminUsersComponent },
      { path: 'reports', component: AdminReportsComponent }
    ]
  },
  
  // Lazy loaded feature
  {
    path: 'products',
    loadChildren: () => import('./products/products.routes')
      .then(m => m.PRODUCTS_ROUTES)
  },
  
  // Wildcard route
  { path: '**', component: PageNotFoundComponent, title: '404 Not Found' }
];
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Order Matters" icon="list">
    Define routes from most specific to least specific. The router uses first-match-wins strategy.
  </Card>

  <Card title="Use pathMatch: 'full'" icon="bullseye">
    Always use `pathMatch: 'full'` with redirects from empty path to avoid infinite loops.
  </Card>

  <Card title="Type-Safe Parameters" icon="shield">
    Use `paramMap.get()` instead of direct `params` access for better type safety.
  </Card>

  <Card title="Centralize Route Data" icon="database">
    Use the `data` property to store route metadata like titles, breadcrumbs, and permissions.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Route Guards" icon="lock" href="/routing/route-guards">
    Learn how to protect routes and control navigation with guards
  </Card>

  <Card title="Lazy Loading" icon="download" href="/routing/lazy-loading">
    Optimize your app by lazy loading feature modules
  </Card>
</CardGroup>
