> ## 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.

# Route Configuration

> API reference for configuring routes in Angular - Routes interface, Route object, and routing patterns.

# Route Configuration

Route configuration defines the mapping between URL paths and components in your Angular application. Routes are defined using the `Routes` type and `Route` interface.

## Import

```typescript theme={null}
import { Routes, Route } from '@angular/router';
```

## Routes Type

```typescript theme={null}
type Routes = Route[];
```

An array of `Route` objects that defines the routing configuration for the application.

## Route Interface

```typescript theme={null}
interface Route {
  // Path Configuration
  path?: string;
  pathMatch?: 'prefix' | 'full';
  matcher?: UrlMatcher;

  // Component Configuration
  component?: Type<any>;
  loadComponent?: () => Promise<Type<any>>;
  redirectTo?: string | RedirectFunction;

  // Child Routes
  children?: Routes;
  loadChildren?: LoadChildren;

  // Named Outlets
  outlet?: string;

  // Guards
  canActivate?: Array<CanActivateFn | DeprecatedGuard>;
  canActivateChild?: Array<CanActivateChildFn | DeprecatedGuard>;
  canDeactivate?: Array<CanDeactivateFn<any> | DeprecatedGuard>;
  canMatch?: Array<CanMatchFn | DeprecatedGuard>;
  canLoad?: Array<CanLoadFn | DeprecatedGuard>; // deprecated

  // Data and Resolution
  data?: Data;
  resolve?: ResolveData;
  title?: string | Type<Resolve<string>> | ResolveFn<string>;

  // Additional Options
  runGuardsAndResolvers?: RunGuardsAndResolvers;
  providers?: Array<Provider | EnvironmentProviders>;
}
```

## Route Properties

### Path Configuration

#### path

```typescript theme={null}
path?: string
```

The URL path to match. Supports:

* Static paths: `'home'`, `'about'`
* Dynamic parameters: `'users/:id'`, `'posts/:postId/comments/:commentId'`
* Wildcard: `'**'` (matches any URL)
* Empty path: `''` (matches without consuming URL segments)

**Examples:**

```typescript theme={null}
const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'users/:id', component: UserComponent },
  { path: 'products/:category/:productId', component: ProductComponent },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: '**', component: NotFoundComponent }
];
```

#### pathMatch

```typescript theme={null}
pathMatch?: 'prefix' | 'full'
```

The path matching strategy:

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

**Example:**

```typescript theme={null}
const routes: Routes = [
  // Must match exact empty path for redirect
  { path: '', pathMatch: 'full', redirectTo: '/home' },
  // Prefix match allows child routes
  { path: 'admin', component: AdminComponent, children: [...] }
];
```

<Warning>
  Always use `pathMatch: 'full'` when redirecting from an empty path, otherwise the redirect will apply to all URLs.
</Warning>

#### matcher

```typescript theme={null}
matcher?: UrlMatcher
```

A custom function for URL matching. Cannot be used with `path`.

**Type Definition:**

```typescript theme={null}
type UrlMatcher = (
  segments: UrlSegment[],
  group: UrlSegmentGroup,
  route: Route
) => UrlMatchResult | null;

type UrlMatchResult = {
  consumed: UrlSegment[];
  posParams?: { [name: string]: UrlSegment };
};
```

**Example:**

```typescript theme={null}
import { UrlSegment } from '@angular/router';

// Match URLs ending with .html
export function htmlFilesMatcher(segments: UrlSegment[]) {
  return segments.length === 1 && segments[0].path.endsWith('.html')
    ? { consumed: segments }
    : null;
}

const routes: Routes = [
  { matcher: htmlFilesMatcher, component: HtmlViewerComponent }
];
```

### Component Configuration

#### component

```typescript theme={null}
component?: Type<any>
```

The component to instantiate when the path matches.

**Example:**

```typescript theme={null}
const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'users/:id', component: UserDetailComponent }
];
```

#### loadComponent

```typescript theme={null}
loadComponent?: () => Promise<Type<any> | DefaultExport<Type<any>>>
```

Lazy-load a standalone component.

**Examples:**

```typescript theme={null}
const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () => import('./admin/admin.component').then(m => m.AdminComponent)
  },
  // With default export, .then() can be omitted
  {
    path: 'profile',
    loadComponent: () => import('./profile/profile.component')
  }
];
```

#### redirectTo

```typescript theme={null}
redirectTo?: string | RedirectFunction
```

URL to redirect to when this path matches. Can be:

* Absolute path: `'/home'`
* Relative path: `'../other'`
* Path with parameters: `'/users/:id'`
* Function for conditional redirects: `RedirectFunction`

**Examples:**

```typescript theme={null}
const routes: Routes = [
  // Simple redirect
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  
  // Redirect with parameters
  { path: 'old-users/:id', redirectTo: '/users/:id' },
  
  // Conditional redirect function
  {
    path: 'dashboard',
    redirectTo: (route) => {
      const userService = inject(UserService);
      return userService.isAdmin() ? '/admin-dashboard' : '/user-dashboard';
    }
  }
];
```

### Child Routes

#### children

```typescript theme={null}
children?: Routes
```

Nested child routes.

**Example:**

```typescript theme={null}
const routes: Routes = [
  {
    path: 'products',
    component: ProductsComponent,
    children: [
      { path: '', component: ProductListComponent },
      { path: ':id', component: ProductDetailComponent },
      { path: ':id/edit', component: ProductEditComponent }
    ]
  }
];
```

**Template for parent component:**

```html theme={null}
<h1>Products</h1>
<router-outlet></router-outlet>
```

#### loadChildren

```typescript theme={null}
loadChildren?: LoadChildren
```

Lazy-load child routes.

**Type Definition:**

```typescript theme={null}
type LoadChildren = () =>
  | Routes
  | Type<any>
  | Observable<Routes | Type<any>>
  | Promise<Routes | Type<any> | DefaultExport<Routes | Type<any>>>;
```

**Examples:**

```typescript theme={null}
const routes: Routes = [
  // Lazy load routes
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES)
  },
  
  // Lazy load NgModule (legacy)
  {
    path: 'legacy',
    loadChildren: () => import('./legacy/legacy.module').then(m => m.LegacyModule)
  },
  
  // With default export
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/routes')
  }
];
```

### Named Outlets

#### outlet

```typescript theme={null}
outlet?: string
```

Name of the RouterOutlet where the component should be rendered.

**Example:**

```typescript theme={null}
const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: 'sidebar', component: SidebarComponent, outlet: 'side' },
  { path: 'popup', component: PopupComponent, outlet: 'popup' }
];
```

**Template:**

```html theme={null}
<router-outlet></router-outlet> <!-- primary outlet -->
<router-outlet name="side"></router-outlet>
<router-outlet name="popup"></router-outlet>
```

**Navigate to named outlet:**

```typescript theme={null}
router.navigate([{
  outlets: {
    primary: 'home',
    side: 'sidebar',
    popup: 'popup'
  }
}]);
```

### Guards

#### canActivate

```typescript theme={null}
canActivate?: Array<CanActivateFn | DeprecatedGuard>
```

Guards that determine if the route can be activated.

**Example:**

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

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true;
  }

  return router.createUrlTree(['/login'], {
    queryParams: { returnUrl: state.url }
  });
};

const routes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [authGuard]
  }
];
```

#### canActivateChild

```typescript theme={null}
canActivateChild?: Array<CanActivateChildFn | DeprecatedGuard>
```

Guards that determine if child routes can be activated.

**Example:**

```typescript theme={null}
const routes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivateChild: [adminGuard],
    children: [
      { path: 'users', component: UsersComponent },
      { path: 'settings', component: SettingsComponent }
    ]
  }
];
```

#### canDeactivate

```typescript theme={null}
canDeactivate?: Array<CanDeactivateFn<any> | DeprecatedGuard>
```

Guards that determine if the route can be deactivated (e.g., unsaved changes).

**Example:**

```typescript theme={null}
import { CanDeactivateFn } from '@angular/router';

export interface CanComponentDeactivate {
  canDeactivate: () => boolean | Promise<boolean>;
}

export const unsavedChangesGuard: CanDeactivateFn<CanComponentDeactivate> = (
  component
) => {
  return component.canDeactivate ? component.canDeactivate() : true;
};

const routes: Routes = [
  {
    path: 'edit',
    component: EditComponent,
    canDeactivate: [unsavedChangesGuard]
  }
];
```

#### canMatch

```typescript theme={null}
canMatch?: Array<CanMatchFn | DeprecatedGuard>
```

Guards that determine if the route configuration can be matched.

**Example:**

```typescript theme={null}
import { inject } from '@angular/core';
import { CanMatchFn } from '@angular/router';
import { FeatureFlagService } from './feature-flag.service';

export const featureGuard: CanMatchFn = (route) => {
  const featureFlags = inject(FeatureFlagService);
  const requiredFeature = route.data?.['feature'];
  return featureFlags.isEnabled(requiredFeature);
};

const routes: Routes = [
  {
    path: 'beta-feature',
    component: BetaComponent,
    canMatch: [featureGuard],
    data: { feature: 'beta-feature' }
  },
  // Fallback if feature not enabled
  { path: 'beta-feature', component: ComingSoonComponent }
];
```

### Data and Resolution

#### data

```typescript theme={null}
data?: Data
```

Static data associated with the route.

**Type:**

```typescript theme={null}
type Data = { [key: string | symbol]: any };
```

**Example:**

```typescript theme={null}
const routes: Routes = [
  {
    path: 'products',
    component: ProductsComponent,
    data: { title: 'Products', breadcrumb: 'All Products', roles: ['user', 'admin'] }
  }
];

// Access in component
import { Component, inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({ /* ... */ })
export class ProductsComponent implements OnInit {
  private route = inject(ActivatedRoute);

  ngOnInit() {
    const data = this.route.snapshot.data;
    console.log(data['title']); // 'Products'
  }
}
```

#### resolve

```typescript theme={null}
resolve?: ResolveData
```

Data resolvers that pre-fetch data before route activation.

**Type:**

```typescript theme={null}
type ResolveData = {
  [key: string]: ResolveFn<any> | DeprecatedResolve;
};

type ResolveFn<T> = (
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => MaybeAsync<T | RedirectCommand>;
```

**Example:**

```typescript theme={null}
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { UserService, User } from './user.service';

export const userResolver: ResolveFn<User> = (route) => {
  const userService = inject(UserService);
  return userService.getUser(route.params['id']);
};

const routes: Routes = [
  {
    path: 'users/:id',
    component: UserDetailComponent,
    resolve: { user: userResolver }
  }
];

// Access resolved data in component
@Component({ /* ... */ })
export class UserDetailComponent implements OnInit {
  private route = inject(ActivatedRoute);

  ngOnInit() {
    const user = this.route.snapshot.data['user'];
    console.log(user);
  }
}
```

#### title

```typescript theme={null}
title?: string | Type<Resolve<string>> | ResolveFn<string>
```

Page title for the route.

**Examples:**

```typescript theme={null}
const routes: Routes = [
  // Static title
  { path: 'home', component: HomeComponent, title: 'Home' },
  
  // Dynamic title with resolver
  {
    path: 'users/:id',
    component: UserComponent,
    title: (route) => `User ${route.params['id']}`
  }
];
```

### Additional Options

#### runGuardsAndResolvers

```typescript theme={null}
runGuardsAndResolvers?: RunGuardsAndResolvers
```

Defines when guards and resolvers should run.

**Type:**

```typescript theme={null}
type RunGuardsAndResolvers =
  | 'pathParamsChange'
  | 'pathParamsOrQueryParamsChange'
  | 'paramsChange'
  | 'paramsOrQueryParamsChange'
  | 'always'
  | ((from: ActivatedRouteSnapshot, to: ActivatedRouteSnapshot) => boolean);
```

**Example:**

```typescript theme={null}
const routes: Routes = [
  {
    path: 'search',
    component: SearchComponent,
    runGuardsAndResolvers: 'paramsOrQueryParamsChange',
    resolve: { results: searchResolver }
  }
];
```

#### providers

```typescript theme={null}
providers?: Array<Provider | EnvironmentProviders>
```

Dependency injection providers for this route and its children.

**Example:**

```typescript theme={null}
import { Routes } from '@angular/router';
import { UserService } from './user.service';

const routes: Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    providers: [UserService],
    children: [
      // Child routes can inject UserService
      { path: 'users', component: UsersComponent }
    ]
  }
];
```

## Common Route Patterns

### Basic Routes

```typescript theme={null}
const routes: Routes = [
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
  { path: 'contact', component: ContactComponent },
  { path: '**', component: NotFoundComponent }
];
```

### Parameterized Routes

```typescript theme={null}
const routes: Routes = [
  { path: 'users/:id', component: UserDetailComponent },
  { path: 'posts/:postId/comments/:commentId', component: CommentComponent },
  { path: 'products/:category', component: ProductListComponent }
];
```

### Nested Routes

```typescript theme={null}
const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    children: [
      { path: '', component: DashboardHomeComponent },
      { path: 'stats', component: StatsComponent },
      { path: 'reports', component: ReportsComponent }
    ]
  }
];
```

### Lazy Loading

```typescript theme={null}
const routes: Routes = [
  {
    path: 'admin',
    loadChildren: () => import('./admin/admin.routes').then(m => m.ADMIN_ROUTES),
    canMatch: [adminGuard]
  },
  {
    path: 'profile',
    loadComponent: () => import('./profile/profile.component'),
    canActivate: [authGuard]
  }
];
```

### Protected Routes

```typescript theme={null}
const routes: Routes = [
  {
    path: 'admin',
    component: AdminLayoutComponent,
    canActivate: [authGuard, adminGuard],
    canActivateChild: [adminGuard],
    children: [
      { path: 'users', component: UsersComponent },
      { path: 'settings', component: SettingsComponent }
    ]
  }
];
```

### Routes with Resolvers

```typescript theme={null}
const routes: Routes = [
  {
    path: 'product/:id',
    component: ProductComponent,
    resolve: {
      product: productResolver,
      reviews: reviewsResolver
    }
  }
];
```

## See Also

<CardGroup cols={2}>
  <Card title="Router Class" icon="code" href="/api/router/router-class">
    Router service API
  </Card>

  <Card title="Route Guards" icon="shield" href="/api/router/guards">
    Guard functions and interfaces
  </Card>

  <Card title="Routing Guide" icon="book" href="/routing/router-overview">
    Complete routing guide
  </Card>

  <Card title="Lazy Loading" icon="bolt" href="/routing/lazy-loading">
    Lazy loading feature modules
  </Card>
</CardGroup>
