개발

Vercel + React Router (CSR) 환경에서 정적 호스팅 라우팅 문제 해결

sjindev 2025. 9. 15. 16:15

 

- 문제 배경

Vercel + React Router (CSR- Client Side Rendering) 환경에서 Vercel 로 배포한 

"https://프로젝트명.vercel.app/" 배포주소에서 발생하는 오류가 하나 있다.

 

프로젝트를 하며 작성하는 Router.tsx 파일의 path가 localhost 에서는 잘 작동하지만 배포도메인에서는 맨 뒤에 path를 입력했을 때 404 not found 오류가 발생한다. 


- 문제 요약

"https://프로젝트명.vercel.app/" : 해당 URL 접속은 잘 됨!

"https://프로젝트명.vercel.app/signin" : 이처럼 서브 라우트로 직접 접근하면 404 Not Found 발생하는 문제.


- 원인: CSR(클라이언트 사이드 라우팅)과 정적 호스팅의 충돌

React Router는 브라우저 내에서 라우팅을 처리하는 CSR 방식이다. 그런데 Vercel이나 Netlify 같은 정적 서버는 기본적으로

요청된 경로에 실제 HTML 파일이 없으면 404 에러를 띄운다. 

즉, 예시와 같이 "/signin" 라는 URL로 직접 접속하면 Vercel은 "/signin/index.html " 같은 정적 파일을 찾으려고 시도하며 없다면 404 에러 가 발생한다.


- 해결 방법: 모든 경로를 index.html로 리디렉션하기

Vercel의 경우 vercel.json 설정으로 해결 가능하다. 아래와 같이 작성한다.

참고로 vercel.json 의 파일 경로는 아래와 같이 작성한다.

your-project/
├── public/
├── src/
├── package.json
├── vite.config.ts
├── tsconfig.json
├── vercel.json ← ✅ 이 위치!
{
  "rewrites": [
    { "source": "/(.*)", "destination": "/" }
  ]
}

 

 

Vite 사용 시 추가 설정이 필요하며 아래와 같다. 

vite.config.ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});

근데 위와같은 설정은 기존에 프로젝트 코드를 보면 기본으로 되어있을 것이고, 그렇지 않다면 위와같이 작성해주면 된다.

 

위 코드에 대해 조금더 설명하자면, 

alias: { '@': path.resolve(__dirname, './src') } : @/components/Button 이런 식으로 절대 경로 import 가능하다.

이는, 프로젝트 규모 커질수록 유지보수에 유리하고, 최근 대부분의 Vite/Next.js 프로젝트에서 사용하는 방식이다.

 

ex) 위 코드에서 사용한 alias 문 사용에 관하여 예시를 들면 아래와 같다.

// 기존 상대경로
import Button from '../../components/Button';

// alias 적용 후
import Button from '@/components/Button';

 

결론

Vercel + React Router (CSR- Client Side Rendering) 환경에서 vercel.json 파일에서 설정을 통하여 

모든 경로를 index.html로 리디렉션하는 방식으로 문제를 해결할 수 있다.