본문 바로가기
Javascript/vue

catchAll 라우트를 활용한 유연한 Vue 페이지 처리

by SANCODE 2025. 6. 2.

Vue Router에서 catchAll 라우트는 사용자가 정의하지 않은 모든 경로를 한 곳에서 처리할 수 있게 해주는 강력한 기능이다. 예를 들어 존재하지 않는 URL에 접근했을 때 404 페이지로 안내하거나, 동적으로 구성된 라우트를 하나의 컴포넌트에서 처리하고 싶을 때 유용하게 사용된다.

 

목차

     


     

    Vue Router란 무엇인가요?

    Vue Router는 Vue.js 공식 라우터 라이브러리로, Vue 앱에서 페이지 전환을 가능하게 해주는 도구다. 일반적으로 웹사이트에서 메뉴를 클릭하면 다른 페이지로 이동하거나, 주소창에 경로를 입력하면 해당 페이지가 열리죠. 이런 기능을 Vue.js 애플리케이션에서도 구현하려면 Vue Router가 필요하다.

    Vue.js는 SPA(Single Page Application) 구조를 기반으로 하기 때문에, 실제로는 한 개의 HTML 파일에서 작동한다. 즉, 화면이 바뀌는 것처럼 보여도 페이지 전체를 다시 불러오는 것이 아니라, 필요한 부분만 동적으로 바꿔주는 방식이다. 이런 구조에서는 사용자가 어떤 URL로 접속했는지에 따라 어떤 화면(컴포넌트)을 보여줄지 결정해주는 장치가 필요한데, 바로 이 역할을 Vue Router가 처리한다.

    Vue Router는 사용자가 브라우저 주소창에 입력한 URL 경로를 감지하고, 미리 정의해놓은 경로 정보와 비교하여 해당 경로에 맞는 화면을 보여준다. 예를 들어 /about이라는 주소를 입력하면 "About 페이지" 컴포넌트를 보여주도록 설정할 수 있다.

    또한, Vue Router는 단순한 경로 매칭을 넘어서 다양한 기능을 제공한다. 예를 들어, 동적으로 경로를 설정할 수 있고, 페이지 이동 전에 특정 조건을 검사하거나(예: 로그인 여부), 페이지 내에서 다시 하위 페이지로 나누는 중첩 라우팅 기능도 지원한다. 또한 깔끔한 URL을 사용할 수 있도록 히스토리 모드도 제공한다.

     


    catchAll 라우트란 무엇인가요?

    catchAll은 말 그대로 모든 경로를 "잡아내는" 라우트를 의미한다. Vue Router에서 사용자가 정의하지 않은 URL 경로로 접근했을 때, 그 요청을 마지막에 한 번 더 "잡아서 처리"할 수 있게 도와주는 기능이다.

    즉, 사용자가 /abc/def 같은 이상한 경로를 입력했을 때도 Vue 앱이 그걸 무시하지 않고, 특별히 지정한 컴포넌트(예: 404 페이지)를 보여줄 수 있게 한다.

     

    {
      path: '/:pathMatch(.*)*',
      name: 'NotFound',
      component: NotFoundPage
    }

     

    :pathMatch는 Vue Router의 동적 경로 변수이며, (.*)*는 정규 표현식처럼 모든 경로를 의미한다.
    그래서 이 라우트는 정의되지 않은 어떤 경로든 모두 매칭한다.

     


    Vue Router catchAll 활용 예제

     

    404 Not Found 페이지 처리

    사용자가 정의되지 않은 경로로 접근했을 때, 사용자에게 404 페이지를 보여준다.

    {
      path: '/:pathMatch(.*)*',
      name: 'NotFound',
      component: NotFoundPage
    }

    이 라우트 설정은 Vue Router에서 존재하지 않는 모든 경로를 마지막에 한 번 더 처리하기 위한 구성이다. 사용자가 정의된 라우트 외의 경로로 접근했을 때, 예를 들어 없는 메뉴를 직접 주소창에 입력하거나, 서버에 잘못된 링크가 저장되어 있거나, 혹은 외부 사이트에서 오타가 포함된 링크를 눌렀을 때, 이 라우트가 동작하여 NotFoundPage 컴포넌트를 대신 렌더링해 준다.
    이를 통해 사용자에게 "404 페이지"처럼 안내 메시지를 제공하고, 애플리케이션이 빈 화면으로 멈추지 않도록 도와주는 중요한 역할을 한다.

     

    글로벌 리디렉션 처리

    목적: 특정 경로 패턴을 모두 잡아서 다른 경로로 리디렉션할 수 있다.

    {
      path: '/old-path/:pathMatch(.*)*',
      redirect: to => {
        return '/new-path/' + to.params.pathMatch;
      }
    }

    이 라우트는 Vue Router에서 기존 URL 구조를 새로운 주소로 리디렉션할 때 사용하는 방식이다. 예를 들어 서비스 리뉴얼 이후 페이지 경로가 변경되었지만, 이전에 저장된 북마크나 외부 링크들이 여전히 /old-path를 참조하고 있을 수 있다. 이럴 때 사용자가 /old-path/something처럼 예전 주소로 접근해도, 자동으로 /new-path/something으로 이동시켜 줄 수 있다.

    또한 마케팅 캠페인 중 임시로 운영하던 페이지의 주소가 바뀌었을 경우에도 이와 같은 리디렉션 처리를 통해 사용자 경험의 연속성을 유지할 수 있다.
    이렇게 함으로써, 페이지 주소가 바뀌어도 SEO 손실을 줄이고, 사용자가 불필요한 404 오류를 겪지 않도록 막을 수 있다.

     

     

    반응형

     

    다국어(i18n) 라우팅 전처리

    모든 경로를 한 번 캐치해서 언어 접두어(/en, /ko, /jp)를 분석한 후 내부 경로로 연결한다.

    {
      path: '/:lang(en|ko|jp)/:pathMatch(.*)*',
      name: 'LocaleWrapper',
      component: LocalePageWrapper
    }

     

     

    위의 라우트 설정은 Vue Router에서 다국어 웹사이트를 구현할 때, 모든 경로를 한 번에 처리하며 언어 접두어를 분석하는 역할을 한다. 사용자가 /en, /ko, /jp와 같은 언어별 접두어가 붙은 URL로 접근하면, 라우터는 route.params.lang 값을 통해 현재 접속한 언어를 인식한다.

    이 정보는 언어별 번역 데이터 로딩에 활용되며, 사용자가 선택한 언어에 맞춰 콘텐츠가 적절히 렌더링된다.
    또한, :pathMatch(.*)*를 통해 언어 접두어 뒤에 오는 모든 하위 경로를 한꺼번에 받아 내부 컴포넌트로 전달하여, 언어별로 분기된 라우팅이나 페이지 렌더링이 가능하도록 설계되었다.

    즉, 이 라우트는 다국어 사이트에서 언어를 구분하고, 공통된 구조로 다양한 경로를 처리하는 중요한 전처리 역할을 수행한다.

     

    CMS 기반 페이지 구성
    미리 정의된 라우트가 아닌, CMS나 백엔드에서 관리하는 경로로 화면을 구성하는 경우에도 catchAll이 유용하게 사용된다.

    {
      path: '/page/:pathMatch(.*)*',
      name: 'CmsPage',
      component: CmsPageRenderer
    }

    이 라우트는 CMS(콘텐츠 관리 시스템)나 백엔드에서 관리하는 페이지 경로를 동적으로 처리하기 위해 사용된다.
    일반적인 Vue Router 라우트처럼 미리 정해진 경로가 아닌, CMS에서 /page/about-us 또는 /page/team/history처럼 다양한 경로를 만들 수 있을 때 유용하다.

    라우터는 :pathMatch(.*)*를 통해 /page 뒤에 오는 모든 하위 경로를 한꺼번에 받아서, 해당 경로를 기준으로 API를 호출하여 필요한 페이지 콘텐츠를 가져온다.
    이후 서버에서 받은 HTML이나 Vue 컴포넌트를 CmsPageRenderer 컴포넌트가 렌더링하여 동적으로 화면을 구성한다.

     


    catchAll 사용시 주의사항

     

    라우트 선언 순서
    catchAll 라우트는 모든 경로와 매칭되므로, 항상 마지막에 선언해야 한다. 그렇지 않으면 정의된 라우트들보다 먼저 매칭되어, 다른 라우트들이 동작하지 않을 수 있다.

    잘못된 순서

    // 잘못된 예시: 모든 라우트가 이 라우트로 매칭됨
    {
      path: '/:pathMatch(.*)*',
      component: NotFoundPage
    },
    {
      path: '/home',
      component: HomePage
    }

     

     

     

     

    올바른 순서

    {
      path: '/home',
      component: HomePage
    },
    {
      path: '/:pathMatch(.*)*',
      component: NotFoundPage
    }

     

    유사 경로와의 충돌 방지

    catchAll 라우트는 정규 표현식처럼 동작하기 때문에, 비슷한 경로를 가진 동적 라우트들과 충돌할 수 있다.
    예를 들어, /user/:id와 /user/:pathMatch(.*)*가 동시에 존재하면 의도치 않은 결과가 발생할 수 있다.


    SEO가 중요한 페이지에서 남용
    catchAll 라우트를 통해 모든 페이지를 하나의 컴포넌트에서 렌더링하면, 각 페이지의 메타 정보(title, description 등)를 개별적으로 관리하기 어려워진다. 특히 정적인 SEO가 중요한 경우에는 정의된 라우트를 우선 사용하고, catchAll은 예외 처리를 위한 용도로 사용하는 것이 좋다.


    리디렉션 루프
    잘못된 리디렉션 설정으로 인해 catchAll 라우트가 자신을 계속 호출하며 무한 루프에 빠지는 경우가 있다.
    예를 들어, /old/:pathMatch(.*)* → /old/다시/path로 리디렉션


    의도치 않은 페이지 노출 주의
    CMS 기반 catchAll 라우트를 사용할 경우, 존재하지 않는 페이지 경로에 대해 빈 페이지나 잘못된 데이터가 노출될 수 있다.

    백엔드에서 페이지 존재 여부를 검증하고, 없으면 명확히 404 처리를 해줘야 한다.

     

     


    마무리

    Vue Router의 catchAll 라우트는 단순히 404 페이지를 처리하는 용도를 넘어, 다국어 라우팅, CMS 기반 페이지 구성, 주소 리디렉션 등 다양한 상황에서 유연하게 활용할 수 있는 강력한 기능이다.

    하지만 모든 경로를 "잡아낸다"는 특성상,
    라우트 선언 순서, 유사 경로와의 충돌, SEO 이슈, 리디렉션 루프 등 꼼꼼하게 설계해야 할 부분도 함께 존재한다.

    핵심이 되는 부분은 catchAll을 남용하지 않고, 필요한 곳에서 정확히 사용하는 것이다.

    단순한 예외 처리를 넘어서 사용자의 다양한 접근 방식에 부드럽게 대응할 수 있는 탄력있는 라우팅 구조를 만들고 싶다면, catchAll을 고려할 가치가 있어보인다.

    반응형