[Next.js] catch-all Routing

이동명·2025년 3월 6일
1

NEXT.js

목록 보기
4/8
post-thumbnail

Catch-all 라우팅

Next.js의 Catch-all 라우팅은 동적 라우팅의 한 형태로, 특정 경로 아래의 모든 하위 경로를 하나의 페이지에서 처리할 수 있게 해주는 기능입니다. 이는 다양한 깊이의 경로를 가진 콘텐츠를 관리하거나, 사용자 정의 경로를 처리해야 할 때 유용합니다.

Catch-all 라우팅의 특징

동적 경로 처리

  • 대괄호([]) 안에 점 세 개(...)를 사용하여 Catch-all 세그먼트를 정의합니다.

  • 예를 들어, [...slug].js 또는 [...path].js와 같은 파일 이름을 사용합니다.

모든 하위 경로 매칭

  • 정의된 세그먼트 아래의 모든 하위 경로를 매칭합니다.

  • 매칭된 경로는 배열 형태로 페이지 컴포넌트의 params prop으로 전달됩니다.

유연성

  • 다양한 깊이의 경로를 가진 콘텐츠를 하나의 페이지에서 처리할 수 있습니다.

  • 사용자 정의 경로, 블로그 카테고리, 문서 시스템 등에 유용합니다.

Catch-all 라우팅 예시

파일 구조: app/blog/[[...slug]]/page.js

URL 경로:

  • /blog/category/article

  • /blog/2024/01/01/my-article

  • /blog/any/number/of/segments

'use client';

export default function BlogCatchAll({ params }) {
    const { slug } = params;

    return (
        <div>
            <h1>Blog Catch-all</h1>
            <p>Slug: {slug.join('/')}</p>
        </div>
    );
}
  • 위 코드에서 /blog/category/article 경로로 접속하면 params.slug는 ['category', 'article'] 배열이 됩니다.

  • /blog/2024/01/01/my-article 경로로 접속하면 params.slug는 ['2024', '01', '01', 'my-article'] 배열이 됩니다.

주의사항

  • Catch-all 라우팅은 모든 하위 경로를 매칭하므로, 특정 경로를 제외해야 하는 경우 조건부 로직을 추가해야 합니다.

  • 과도한 Catch-all 라우팅 사용은 URL 구조를 복잡하게 만들 수 있으므로, 적절한 수준에서 사용하는 것이 좋습니다.

예제

http://localhost:3000/archive/2024/3 의 예시로 접근해서 해당하는 URL의 연도와 월에 해당하는 news 기사를 가져 오는 로직

export default function FilteredNewsPage({params}) {
    const filter = params.filter;
    const selectedYear = filter?.[0];
    const selectedMonth = filter?.[1];

    let news;
    let links = getAvailableNewsYears();

    // 년도만 존재 할 때 ..
    if (selectedYear && !selectedMonth) {
        news = getNewsForYear(selectedYear);

        // 년도에 해당하는 월 뽑아오기
        links = getAvailableNewsMonths(selectedYear);
    }

    // 둘다 존재 할 때..
    if (selectedYear && selectedMonth) {
        news = getNewsForYearAndMonth(selectedYear, selectedMonth);
      
        // 링크 비워주기
        links = [];
    }

    let newsContent = <p>No news found for the selected period.</p>

    if (news && news.length > 0) {
        newsContent = <NewsList news={news} />
    }

    // 지정하지 않은 path 및 slug가 들어올 때
    if (
        selectedYear &&
        !getAvailableNewsYears().includes(+selectedYear) ||
        selectedMonth &&
        !getAvailableNewsMonths(selectedYear).includes(+selectedMonth)
    ) {
        throw new Error('Invalid Error');
    }

    return (
        <>
            <header id="archive-header">
                <nav>
                    <ul>
                        {links.map((link) => {
                            const href = selectedYear
                                ? `/archive/${selectedYear}/${link}`
                                : `/archive/${link}`;
                            
                            return (
                                <li key={link}>
                                    <Link href={href}>{link}</Link>
                                </li>
                            );
                        })}
                    </ul>
                </nav>
            </header>
            {newsContent}
        </>
    );
}

https://github.com/dongmyoungLee/NextParallelRouting

profile
Web Developer

0개의 댓글