심화 가이드
라우팅

라우팅 규칙 사이 이동하기

RouterLink 디렉티브는 Angular에서 선언적으로 내비게이션을 구성하는 방식입니다. 표준 앵커 엘리먼트(<a>)를 Angular 라우팅 시스템과 자연스럽게 연결해서 사용할 수 있습니다.

href 어트리뷰트가 있는 일반적인 앵커 엘리먼트 <a> 대신 RouterLink 디렉티브에 경로를 지정하면 Angular 라우팅을 사용할 수 있습니다.

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

@Component({
  template: `
    <nav>
      <a routerLink="/user-profile">User profile</a>
      <a routerLink="/settings">Settings</a>
    </nav>
  `,
  imports: [RouterLink],
  ...
})
export class App {}

절대 링크와 상대 링크 사용하기

Angular 라우팅의 상대 URL을 사용하면 현재 라우팅 규칙 위치를 기준으로 이동할 경로를 정의할 수 있습니다. 프로토콜(예: http://)과 루트 도메인(예: google.com)을 포함한 전체 경로를 지정하는 절대 URL과는 다릅니다.

<!-- 절대 URL -->
<a href="https://www.angular.dev/essentials">Angular Essentials Guide</a>

<!-- 상대 URL -->
<a href="/essentials">Angular Essentials Guide</a>

첫 번째 예제는 핵심 가이드 페이지의 전체 경로에 프로토콜(https://)과 루트 도메인(angular.dev)을 명시합니다. 반면 두 번째 예제는 사용자가 이미 /essentials에 해당하는 올바른 루트 도메인에 있다고 가정합니다.

일반적으로 상대 URL을 권장합니다. 라우팅 계층에서 절대 위치를 알 필요가 없기 때문에 여러 애플리케이션에서 유지보수하기 쉽습니다.

상대 URL의 동작 방식

Angular 라우팅에서는 문자열과 배열, 두 가지 문법으로 상대 URL을 정의할 수 있습니다.

<!-- 사용자를 /dashboard로 이동시킵니다. -->
<a routerLink="dashboard">Dashboard</a>
<a [routerLink]="['dashboard']">Dashboard</a>

참고: 상대 URL을 정의할 때는 문자열을 전달하는 방식이 가장 흔합니다.

상대 URL에 동적 파라미터를 지정해야 한다면 배열 문법을 사용하세요.

<a [routerLink]="['user', currentUserId]">Current User</a>

Angular 라우팅에서는 상대 경로 앞에 슬래시(/)가 있는지에 따라 현재 URL을 기준으로 할지, 루트 도메인을 기준으로 할지도 지정할 수 있습니다.

예를 들어 사용자가 example.com/settings에 있다면 상황에 따라 다음과 같이 상대 경로를 정의할 수 있습니다.

<!-- /settings/notifications로 이동합니다. -->
<a routerLink="notifications">Notifications</a>
<a routerLink="/settings/notifications">Notifications</a>

<!-- /team/:teamId/user/:userId로 이동합니다. -->
<a routerLink="/team/123/user/456">User 456</a>
<a [routerLink]="['/team', teamId, 'user', userId]">Current User</a>

코드로 라우팅 규칙 사이 이동하기

RouterLink는 템플릿에서 선언적으로 내비게이션을 처리합니다. 로직, 사용자 동작, 애플리케이션 상태에 따라 이동해야 하는 경우에는 Angular가 제공하는 코드 기반 내비게이션을 사용할 수 있습니다. Router를 주입하면 TypeScript 코드에서 동적으로 라우팅 규칙 사이를 이동하고, 파라미터를 전달하고, 내비게이션 동작을 제어할 수 있습니다.

router.navigate()

router.navigate() 메서드에 URL 경로 배열을 지정하면 코드로 라우팅 규칙 사이를 이동할 수 있습니다.

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

@Component({
  selector: 'app-dashboard',
  template: ` <button (click)="navigateToProfile()">View Profile</button> `,
})
export class AppDashboard {
  private router = inject(Router);

  navigateToProfile() {
    // 기본 내비게이션
    this.router.navigate(['/profile']);

    // 라우팅 규칙 파라미터 사용
    this.router.navigate(['/users', userId]);

    // 쿼리 파라미터 사용
    this.router.navigate(['/search'], {
      queryParams: {category: 'books', sort: 'price'},
    });

    // 매트릭스 파라미터 사용
    this.router.navigate(['/products', {featured: true, onSale: true}]);
  }
}

router.navigate()는 간단한 라우팅부터 복잡한 라우팅까지 지원합니다. 라우팅 규칙 파라미터와 쿼리 파라미터를 전달하고 내비게이션 동작을 제어할 수 있습니다.

relativeTo 옵션을 사용하면 라우팅 트리에서 컴포넌트가 있는 위치를 기준으로 동적 이동 경로를 구성할 수도 있습니다.

import {Router, ActivatedRoute} from '@angular/router';
import {Component, inject} from '@angular/core';

@Component({
  selector: 'app-user-detail',
  template: `
    <button (click)="navigateToEdit()">Edit User</button>
    <button (click)="navigateToParent()">Back to List</button>
  `,
})
export class UserDetail {
  private route = inject(ActivatedRoute);
  private router = inject(Router);

  // 형제 라우팅 규칙으로 이동합니다.
  navigateToEdit() {
    // 출발: /users/123
    // 도착:   /users/123/edit
    this.router.navigate(['edit'], {relativeTo: this.route});
  }

  // 부모로 이동합니다.
  navigateToParent() {
    // 출발: /users/123
    // 도착:   /users
    this.router.navigate(['..'], {relativeTo: this.route});
  }

  navigateToList() {
    // Angular는 명령 배열을 현재 라우팅 규칙 기준의 단일 이동 경로로 해석합니다.
    // 출발: /users/123
    // 결과: /users/list
    this.router.navigate(['..', 'list'], {relativeTo: this.route});
  }
}

여러 단계 위로 이동할 때는 모든 .. 세그먼트를 명령 배열의 첫 번째 항목에 넣어야 합니다. 라우터는 첫 번째 명령 문자열에서만 ..를 해석하며, 그 뒤의 배열 항목은 일반 경로 세그먼트로 처리합니다.

권장
// 출발: /team/123/users/456
// 결과: /team/123/settings
this.router.navigate(['../../settings'], {relativeTo: this.route});

relativeTo를 사용할 때는 첫 번째 명령 앞에 /를 붙이지 마세요. 맨 앞에 /가 있으면 절대 경로 내비게이션이 되며 relativeTo는 완전히 무시됩니다.

권장
// 출발: /team/123/users/456
// 결과: /team/123/users/456/edit
this.router.navigate(['edit'], {relativeTo: this.route});
권장하지 않음
// 출발: /team/123/users/456
// 맨 앞에 '/'가 있으면 절대 경로로 이동하며 relativeTo는 무시됩니다.
// 결과: /edit
this.router.navigate(['/edit'], {relativeTo: this.route});

router.navigateByUrl()

router.navigateByUrl() 메서드는 세그먼트 배열 대신 URL 경로 문자열로 직접 내비게이션을 실행합니다. 전체 URL 경로가 있고 절대 경로로 이동해야 할 때 적합하며, 특히 외부에서 받은 URL이나 딥 링크를 처리할 때 유용합니다.

// 기본 라우팅 규칙 내비게이션
router.navigateByUrl('/products');

// 중첩 라우팅 규칙으로 이동합니다.
router.navigateByUrl('/products/featured');

// 파라미터와 프래그먼트가 있는 전체 URL
router.navigateByUrl('/products/123?view=details#reviews');

// 쿼리 파라미터와 함께 이동합니다.
router.navigateByUrl('/search?category=books&sortBy=price');

// 매트릭스 파라미터 사용
router.navigateByUrl('/sales-awesome;isOffer=true;showModal=false');

히스토리의 현재 URL을 교체해야 한다면 navigateByUrl에 replaceUrl 옵션이 있는 설정 객체를 전달할 수도 있습니다.

// 히스토리의 현재 URL을 교체합니다.
router.navigateByUrl('/checkout', {
  replaceUrl: true,
});

주소 표시줄에 다른 URL 표시하기

navigateByUrl에 browserUrl 옵션을 전달하면 라우팅 규칙 매칭에 사용하는 URL과 다른 URL을 브라우저 주소 표시줄에 표시할 수 있습니다.

사용자가 처음 방문하려던 URL을 유지하면서 다른 라우팅 규칙(예: 오류 페이지)으로 리다이렉트하고 싶을 때 유용합니다.

router.navigateByUrl('/not-found', {browserUrl: '/products/missing-item'});

Angular는 /not-found 라우팅 규칙으로 이동해서 렌더링하지만, 브라우저 주소 표시줄에는 /products/missing-item이 표시됩니다.

참고: browserUrl은 브라우저 주소 표시줄에 표시되는 내용에만 영향을 줍니다.

RouterLink로 브라우저 URL 조정하기

RouterLink 디렉티브도 browserUrl 입력 프로퍼티를 지원합니다. 따라서 링크를 클릭했을 때 Angular가 이동하는 라우팅 규칙과 별개로 브라우저 주소 표시줄에 표시할 URL을 제어할 수 있습니다.

<!-- /dashboard로 이동하지만 주소 표시줄에는 /home을 표시합니다. -->
<a [routerLink]="['/dashboard']" [browserUrl]="'/home'">Go to Dashboard</a>

더 동적인 처리가 필요하면 UrlTree를 바인딩할 수도 있습니다.

import {Component, inject} from '@angular/core';
import {Router, RouterLink, UrlTree} from '@angular/router';

@Component({
  template: `
    <a [routerLink]="['/products', product.id]" [browserUrl]="displayUrl">
      {{ product.name }}
    </a>
  `,
  imports: [RouterLink],
})
export class ProductList {
  private router = inject(Router);

  product = {id: 42, name: 'Widget'};

  // 주소 표시줄에 표시할 UrlTree를 생성합니다.
  displayUrl: UrlTree = this.router.createUrlTree(['/products', 'widget']);
}

다음 단계

라우팅 규칙 상태를 읽는 방법을 알아보고, 변화와 컨텍스트에 반응하는 컴포넌트를 만들어 보세요.