심화 가이드
라우팅

아웃렛으로 라우팅 규칙 표시하기

RouterOutlet 디렉티브는 현재 URL에 해당하는 컴포넌트를 라우터가 렌더링할 위치를 지정합니다.

<app-header />
<!-- Angular는 여기에 라우팅 규칙 내용을 삽입합니다. -->
<router-outlet />
<app-footer />
import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  templateUrl: './app.html',
  styleUrl: './app.css',
})
export class App {}

이 예제의 애플리케이션에 다음 라우팅 규칙이 정의되어 있다고 가정해 보겠습니다.

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

const routes: Routes = [
  {
    path: '',
    component: Home,
    title: 'Home Page',
  },
  {
    path: 'products',
    component: Products,
    title: 'Our Products',
  },
];

사용자가 /products에 방문하면 Angular는 다음과 같이 렌더링합니다.

<app-header />
<app-products />
<app-footer />

사용자가 홈페이지로 돌아가면 다음과 같이 렌더링합니다.

<app-header />
<app-home />
<app-footer />

라우팅 규칙을 표시할 때 <router-outlet> 엘리먼트는 이후 내비게이션의 기준점으로 DOM에 남아 있습니다. Angular는 라우팅된 내용을 아웃렛 엘리먼트 바로 뒤에 형제 엘리먼트로 삽입합니다.

<!-- 컴포넌트 템플릿의 내용 -->
<app-header />
<router-outlet />
<app-footer />
<!-- 사용자가 /admin에 방문했을 때 페이지에 렌더링되는 내용 -->
<app-header />
<router-outlet />
<app-admin-page />
<app-footer />

자식 라우팅 규칙으로 라우팅 규칙 중첩하기

애플리케이션이 복잡해지면 루트 컴포넌트가 아닌 다른 컴포넌트를 기준으로 라우팅 규칙을 구성하고 싶을 수 있습니다. 이렇게 하면 URL이 바뀔 때 전체 페이지가 새로 고쳐지는 느낌 대신 애플리케이션의 일부만 바뀌는 화면을 구성할 수 있습니다.

이런 중첩 라우팅 규칙을 자식 라우팅 규칙이라고 합니다. AppComponent의 <router-outlet>에 더해 애플리케이션에 두 번째 <router-outlet>을 추가하는 방식입니다.

이 예제의 Settings 컴포넌트는 사용자 선택에 따라 원하는 패널을 표시합니다. 자식 라우팅 규칙의 특징 중 하나는 컴포넌트가 자체 <nav>와 <router-outlet>을 갖는 경우가 많다는 점입니다.

<h1>Settings</h1>
<nav>
  <ul>
    <li><a routerLink="profile">Profile</a></li>
    <li><a routerLink="security">Security</a></li>
  </ul>
</nav>
<router-outlet />

자식 라우팅 규칙도 다른 라우팅 규칙과 마찬가지로 path와 component가 필요합니다. 다른 점은 부모 라우팅 규칙의 children 배열에 자식 라우팅 규칙을 배치한다는 것입니다.

const routes: Routes = [
  {
    path: 'settings',
    component: Settings, // 템플릿에 <router-outlet>이 있는 컴포넌트입니다.
    children: [
      {
        path: 'profile', // 자식 라우팅 규칙 경로
        component: Profile, // 라우터가 렌더링하는 자식 라우팅 규칙 컴포넌트
      },
      {
        path: 'security',
        component: Security, // 라우터가 렌더링하는 다른 자식 라우팅 규칙 컴포넌트
      },
    ],
  },
];

routes와 <router-outlet>을 모두 올바르게 설정하면 애플리케이션에서 중첩 라우팅 규칙을 사용할 수 있습니다!

이름이 있는 아웃렛으로 보조 라우팅 규칙 구성하기

페이지에는 여러 아웃렛을 둘 수 있습니다. 각 아웃렛에 이름을 지정하면 어떤 내용을 어느 아웃렛에 표시할지 결정할 수 있습니다.

<app-header />
<router-outlet />
<router-outlet name="read-more" />
<router-outlet name="additional-actions" />
<app-footer />

각 아웃렛의 이름은 고유해야 합니다. 이름을 값에 바인딩할 수 있습니다. 값이 변경되면 아웃렛은 현재 컴포넌트를 제거하고, 새 이름과 일치하는 라우팅 규칙이 있으면 해당 화면을 렌더링합니다. 기본 이름은 'primary'입니다.

Angular는 아웃렛 이름을 각 라우팅 규칙에 정의한 outlet 프로퍼티와 매칭합니다.

{
  path: 'user/:id',
  component: UserDetails,
  outlet: 'additional-actions'
}

아웃렛 라이프사이클 이벤트

라우터 아웃렛은 네 가지 라이프사이클 이벤트를 발생시킬 수 있습니다.

이벤트 설명
activate 새 컴포넌트 인스턴스가 생성될 때 발생합니다.
deactivate 컴포넌트가 종료될 때 발생합니다.
attach RouteReuseStrategy가 아웃렛에 하위 트리를 연결하도록 지시할 때 발생합니다.
detach RouteReuseStrategy가 아웃렛에 하위 트리를 분리하도록 지시할 때 발생합니다.

일반적인 이벤트 바인딩 문법으로 이벤트 리스너를 추가할 수 있습니다.

<router-outlet
  (activate)="onActivate($event)"
  (deactivate)="onDeactivate($event)"
  (attach)="onAttach($event)"
  (detach)="onDetach($event)"
/>

자세한 내용은 RouterOutlet API 문서를 참고하세요.

라우팅된 컴포넌트에 컨텍스트 데이터 전달하기

라우팅된 컴포넌트에 컨텍스트 데이터를 전달하려면 전역 상태나 복잡한 라우팅 규칙 설정이 필요한 경우가 많습니다. 이를 간단하게 처리할 수 있도록 각 RouterOutlet은 routerOutletData 입력 프로퍼티를 지원합니다. 라우팅된 컴포넌트와 그 자식 컴포넌트에서는 ROUTER_OUTLET_DATA 의존성 주입 토큰으로 이 데이터를 시그널 형태로 읽을 수 있습니다. 따라서 라우팅 규칙 정의를 수정하지 않고 아웃렛별로 설정을 전달할 수 있습니다.

import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';

@Component({
  selector: 'app-dashboard',
  imports: [RouterOutlet],
  template: `
    <h2>Dashboard</h2>
    <router-outlet [routerOutletData]="{layout: 'sidebar'}" />
  `,
})
export class Dashboard {}

라우팅된 컴포넌트에서는 ROUTER_OUTLET_DATA로 아웃렛이 제공한 데이터를 주입받을 수 있습니다.

import {Component, inject, Signal} from '@angular/core';
import {ROUTER_OUTLET_DATA} from '@angular/router';

@Component({
  selector: 'app-stats',
  template: `<p>Stats view (layout: {{ outletData().layout }})</p>`,
})
export class Stats {
  outletData = inject(ROUTER_OUTLET_DATA) as Signal<{layout: string}>;
}

Angular가 해당 아웃렛에서 Stats를 활성화하면 { layout: 'sidebar' }가 데이터로 주입됩니다.

참고: routerOutletData 입력 프로퍼티를 지정하지 않으면 주입된 시그널의 기본값은 undefined입니다.


다음 단계

Angular 라우터로 라우팅 규칙 사이를 이동하는 방법을 알아보세요.