詳細ガイド
ルーティング

ルートを定義する

ルートは、Angularアプリケーション内のナビゲーションのための基本的な構成要素として機能します。

ルートとは

Angularでは、ルートは特定のURLパスまたはパターンに対してどのコンポーネントをレンダリングするか、およびユーザーがそのURLにナビゲートしたときに何が起こるかに関する追加の構成オプションを定義するオブジェクトです。

次にルートの基本的な例を示します。

import {AdminPage} from './app-admin';

const adminPage = {
  path: 'admin',
  component: AdminPage,
};

このルートの場合、ユーザーが/adminパスにアクセスすると、アプリケーションはAdminPageコンポーネントを表示します。

アプリケーションでルートを管理する

ほとんどのプロジェクトでは、ファイル名にroutesを含む別のファイルでルートを定義します。

ルートのコレクションは次のようになります。

import {Routes} from '@angular/router';
import {HomePage} from './home-page';
import {AdminPage} from './about-page';

export const routes: Routes = [
  {
    path: '',
    component: HomePage,
  },
  {
    path: 'admin',
    component: AdminPage,
  },
];

Tip: Angular CLIでプロジェクトを生成した場合、ルートはsrc/app/app.routes.tsで定義されます。

アプリケーションにルーターを追加する

Angular CLIなしでAngularアプリケーションをブートストラップする場合、providers配列を含む構成オブジェクトを渡すことができます。

providers配列内で、provideRouter関数呼び出しとルートを追加することで、Angularルーターをアプリケーションに追加できます。

import {ApplicationConfig} from '@angular/core';
import {provideRouter} from '@angular/router';

import {routes} from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    // ...
  ],
};

ルートURLパス

静的なURLパス

静的なURLパスとは、動的なパラメーターに基づいて変化しない、事前に定義されたパスを持つルートを指します。これらはpath文字列に正確に一致し、固定された結果を持つルートです。

例としては次のものがあります。

  • "/admin"
  • "/blog"
  • "/settings/account"

ルートパラメーターでURLパスを定義する

パラメーター化されたURLを使用すると、複数のURLを同じコンポーネントに許可しながら、URL内のパラメーターに基づいてデータを動的に表示する動的なパスを定義できます。

このタイプのパターンは、ルートのpath文字列にパラメーターを追加し、各パラメーターの前にコロン(:)文字を付けることで定義できます。

IMPORTANT: パラメーターは、URLのクエリ文字列内の情報とは異なります。 このガイドでAngularのクエリパラメーターについて詳しく参照してください

次の例は、URLを介して渡されたユーザーIDに基づいてユーザープロファイルコンポーネントを表示します。

import {Routes} from '@angular/router';
import {UserProfile} from './user-profile/user-profile';

const routes: Routes = [{path: 'user/:id', component: UserProfile}];

この例では、/user/leeroy/user/jenkinsなどのURLはUserProfileコンポーネントをレンダリングします。このコンポーネントは、idパラメーターを読み取り、それを使用してデータの取得などの追加作業を実行できます。ルートパラメーターの読み取りの詳細については、ルート状態の読み取りガイドを参照してください

有効なルートパラメーター名は、文字(a-z、A-Z)で始まり、次のもののみを含めることができます。

  • 文字(a-z、A-Z)
  • 数字(0-9)
  • アンダーバー(_)
  • ハイフン(-)

複数のパラメーターを持つパスを定義できます。

import {Routes} from '@angular/router';
import {UserProfile} from './user-profile';
import {SocialMediaFeed} from './social-media-feed';

const routes: Routes = [
  {path: 'user/:id/:social-media', component: SocialMediaFeed},
  {path: 'user/:id/', component: UserProfile},
];

この新しいパスにより、ユーザーは/user/leeroy/youtube/user/leeroy/blueskyにアクセスし、ユーザーleeroyのパラメーターに基づいてそれぞれのソーシャルメディアフィードを見ることができます。

ルートパラメーターの読み取りの詳細については、ルート状態の読み取りを参照してください。

ワイルドカード

特定のパスのすべてのルートをキャッチする必要がある場合、解決策は二重アスタリスク(**)で定義されるワイルドカードルートです。

一般的な例は、ページが見つかりませんコンポーネントの定義です。

import {Home} from './home/home';
import {UserProfile} from './user-profile';
import {NotFound} from './not-found';

const routes: Routes = [
  {path: 'home', component: Home},
  {path: 'user/:id', component: UserProfile},
  {path: '**', component: NotFound},
];

このルート配列では、ユーザーがhomeuser/:id以外のパスにアクセスすると、アプリケーションはNotFoundコンポーネントを表示します。

Tip: ワイルドカードルートは通常、ルート配列の最後に配置されます。

AngularがURLを照合する方法

ルートを定義する際、Angularは最初の一致が優先される戦略を使用するため、順序が重要です。これは、AngularがURLをルートpathと照合すると、それ以上ルートの確認を停止することを意味します。結果として、常に、より具体的なルートを、より具体的でないルートの前に配置してください。

次の例は、最も具体的なものから最も具体的でないものへと定義されたルートを示しています。

const routes: Routes = [
  {path: '', component: Home}, // 空のパス
  {path: 'users/new', component: NewUser}, // 静的、最も具体的
  {path: 'users/:id', component: UserDetail}, // 動的
  {path: 'users', component: Users}, // 静的、具体的でない
  {path: '**', component: NotFound}, // ワイルドカード - 常に最後
];

ユーザーが/users/newにアクセスした場合、Angularルーターは次の手順を実行します。

  1. ''をチェック - 一致しません
  2. users/newをチェック - 一致します!ここで停止します
  3. 一致する可能性があるにもかかわらず、users/:idには到達しません
  4. usersには到達しません
  5. **には到達しません

リダイレクト

コンポーネントをレンダリングする代わりに、別のルートにリダイレクトするルートを定義できます。

import {Blog} from './home/blog';

const routes: Routes = [
  {
    path: 'articles',
    redirectTo: '/blog',
  },
  {
    path: 'blog',
    component: Blog,
  },
];

ルートを変更または削除した場合でも、一部のユーザーは古いリンクやブックマークをクリックしてそのルートにアクセスする可能性があります。そのようなユーザーを「見つかりません」ページではなく、適切な代替ルートに誘導するためにリダイレクトを追加できます。

ページタイトル

各ルートにはタイトルを関連付けることができます。ルートがアクティブになると、Angularはページタイトルを自動的に更新します。アクセシブルな体験を作成するためにこれらのタイトルが必要となるため、アプリケーションに適切なページタイトルを常に定義してください。

import {Routes} from '@angular/router';
import {Home} from './home';
import {About} from './about';
import {Products} from './products';

const routes: Routes = [
  {
    path: '',
    component: Home,
    title: 'Home Page',
  },
  {
    path: 'about',
    component: About,
    title: 'About Us',
  },
];

ページの title プロパティは、ResolveFnを使用してリゾルバー関数に動的に設定できます。

const titleResolver: ResolveFn<string> = (route) => route.queryParams['id'];
const routes: Routes = [
  ...{
    path: 'products',
    component: Products,
    title: titleResolver,
  },
];

ルートタイトルは、TitleStrategy 抽象クラスを継承するサービスを介しても設定できます。デフォルトでは、AngularはDefaultTitleStrategyを使用します。

ページタイトルのためのTitleStrategyの使用

ドキュメントタイトルの構成方法を一元的に制御する必要がある高度なシナリオでは、TitleStrategyを実装します。

TitleStrategyは、Angularが使用するデフォルトのタイトル戦略をオーバーライドするために提供できるトークンです。カスタムのTitleStrategyを提供して、アプリケーションのサフィックスの追加、パンくずリストからのタイトルのフォーマット、ルートデータからのタイトルの動的生成などの規約を実装できます。

import {inject, Injectable} from '@angular/core';
import {Title} from '@angular/platform-browser';
import {TitleStrategy, RouterStateSnapshot} from '@angular/router';

@Injectable()
export class AppTitleStrategy extends TitleStrategy {
  private readonly title = inject(Title);

  updateTitle(snapshot: RouterStateSnapshot): void {
    // PageTitleは、ルートの"Title"が設定されている場合はそれと等しくなります
    // 設定されていない場合は、index.htmlで指定された"title"を使用します
    const pageTitle = this.buildTitle(snapshot) || this.title.getTitle();
    this.title.setTitle(`MyAwesomeApp - ${pageTitle}`);
  }
}

カスタム戦略を使用するには、アプリケーションレベルでTitleStrategyトークンを使用してそれを提供します。

import {provideRouter, TitleStrategy} from '@angular/router';
import {AppTitleStrategy} from './app-title.strategy';

export const appConfig = {
  providers: [provideRouter(routes), {provide: TitleStrategy, useClass: AppTitleStrategy}],
};

依存性の注入のためのルートレベルプロバイダー

各ルートには、依存性の注入を介してそのルートのコンテンツに依存性を提供するprovidersプロパティがあります。

これが役立つ一般的なシナリオには、ユーザーが管理者であるかどうかに基づいて異なるサービスを持つアプリケーションが含まれます。

export const ROUTES: Route[] = [
  {
    path: 'admin',
    providers: [AdminService, {provide: ADMIN_API_KEY, useValue: '12345'}],
    children: [
      {path: 'users', component: AdminUsers},
      {path: 'teams', component: AdminTeams},
    ],
  },
  // ... other application routes that don't
  //     have access to ADMIN_API_KEY or AdminService.
];

このコードサンプルでは、adminパスにはADMIN_API_KEYという保護されたデータプロパティが含まれており、そのセクション内の子にのみ利用できます。結果として、他のパスはADMIN_API_KEYを介して提供されるデータにアクセスできません。

Angularのプロバイダーと注入に関する詳細については、依存性の注入ガイドを参照してください。

ルートにデータを関連付ける

ルートデータを使用すると、ルートに追加情報を付加できます。このデータに基づいてコンポーネントの動作を設定できます。

ルートデータを扱う方法は2つあります。定数として保持される静的データと、実行時の条件に基づいて変化する動的データです。

静的データ

dataプロパティを介して任意の静的データをルートに関連付けることで、ルート固有のメタデータ(例: 分析トラッキング、権限など)を一元化できます。

import {Routes} from '@angular/router';
import {Home} from './home';
import {About} from './about';
import {Products} from './products';

const routes: Routes = [
  {
    path: 'about',
    component: About,
    data: {analyticsId: '456'},
  },
  {
    path: '',
    component: Home,
    data: {analyticsId: '123'},
  },
];

このコードサンプルでは、ホームページとアバウトページが特定のanalyticsIdで構成されており、それぞれのコンポーネントでページトラッキング分析に使用されます。

この静的データはActivatedRouteを注入することで読み取ることができます。詳細については、ルート状態の読み取りを参照してください。

データリゾルバーによる動的データ

ルートに動的データを提供する必要がある場合は、ルートデータリゾルバーに関するガイドを参照してください。

ネストされたルート

ネストされたルートは、子ルートとも呼ばれ、URLに基づいてサブビューが変化する、より複雑なナビゲーションルートを管理するための一般的な手法です。

ネストされたルートを示す図

childrenプロパティを使用して、任意のルート定義に子ルートを追加できます。

const routes: Routes = [
  {
    path: 'product/:id',
    component: Product,
    children: [
      {
        path: 'info',
        component: ProductInfo,
      },
      {
        path: 'reviews',
        component: ProductReviews,
      },
    ],
  },
];

上記の例では、ユーザーがURLに基づいて製品情報またはレビューのどちらを表示するかを変更できる製品ページのルートを定義しています。

childrenプロパティはRouteオブジェクトの配列を受け入れます。

子ルートを表示するには、親コンポーネント(上記の例ではProduct)に独自の<router-outlet>を含めます。

<!-- Product -->
<article>
  <h1>Product {{ id }}</h1>
  <router-outlet />
</article>

設定に子ルートを追加し、コンポーネントに<router-outlet>を追加すると、子ルートに一致するURL間のナビゲーションは、ネストされたアウトレットのみを更新します。

次のステップ