심화 가이드
라우팅

라우팅 규칙 정의하기

라우팅 규칙은 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 './admin-page';

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

팁: 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 문자열에 파라미터를 추가하고 각 파라미터 앞에 콜론(:)을 붙이면 이런 패턴을 정의할 수 있습니다.

중요: 이 파라미터는 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 {Routes} from '@angular/router';
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},
];

이 라우팅 규칙 배열에서는 사용자가 home, user/:id 외의 경로에 방문하면 NotFound 컴포넌트를 표시합니다.

팁: 와일드카드 라우팅 규칙은 일반적으로 라우팅 규칙 배열의 마지막에 배치합니다.

Angular의 URL 매칭 방식

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 {Routes} from '@angular/router';
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 {
    // 라우팅 규칙에 "Title"이 설정되어 있으면 PageTitle은 그 값과 같습니다.
    // 설정되어 있지 않으면 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},
    ],
  },
  // ... 다른 애플리케이션 라우팅 규칙에서는
  //     ADMIN_API_KEY나 AdminService에 접근할 수 없습니다.
];

이 코드에서 admin 경로에는 해당 영역의 자식에서만 사용할 수 있는 ADMIN_API_KEY 데이터 프로퍼티가 있습니다. 따라서 다른 경로에서는 ADMIN_API_KEY로 제공하는 데이터에 접근할 수 없습니다.

Angular의 프로바이더와 의존성 주입에 관한 자세한 내용은 의존성 주입 가이드를 참고하세요.

라우팅 규칙에 데이터 연결하기

라우팅 규칙 데이터를 사용하면 라우팅 규칙에 추가 정보를 연결할 수 있습니다. 이 데이터에 따라 컴포넌트 동작을 설정할 수 있습니다.

라우팅 규칙 데이터에는 값이 바뀌지 않는 정적 데이터와 실행 중 조건에 따라 바뀔 수 있는 동적 데이터가 있습니다.

정적 데이터

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'},
  },
];

이 코드에서는 home과 about 페이지에 각각 analyticsId를 설정합니다. 각 컴포넌트는 이 값을 페이지 추적 분석에 사용할 수 있습니다.

ActivatedRoute를 주입하면 정적 데이터를 읽을 수 있습니다. 자세한 내용은 라우팅 규칙 상태 읽기를 참고하세요.

리소스와 리졸버로 동적 데이터 제공하기

라우팅 규칙에서 데이터를 가져와야 한다면 Angular 라우터가 제공하는 반응형 리소스나 데이터 리졸버를 사용할 수 있습니다.

중첩 라우팅 규칙

중첩 라우팅 규칙은 자식 라우팅 규칙이라고도 하며, 복잡한 내비게이션 경로를 관리할 때 자주 사용하는 방식입니다. 컴포넌트 안의 하위 뷰를 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 사이를 이동할 때 중첩된 아웃렛만 갱신됩니다.

다음 단계