React 화면 새로고침 할 때 404 Not Found

문제의 핵심 원인: “서버는 /about이라는 파일을 모른다”

  1. 클라이언트 사이드 라우팅 (React Router의 작동 방식):
    • 사용자가 웹사이트에 처음 접속하면 (http://example.com/), 서버는 index.html 파일 하나만 보내줍니다.
    • 이후 사용자가 메뉴를 클릭하여 /about 페이지로 이동하면, React Router는 브라우저의 주소창만 /about으로 바꾸고, 서버에 새로운 요청을 보내지 않습니다. 대신, 미리 로드된 JavaScript가 화면 내용만 /about에 해당하는 컴포넌트로 교체해 줍니다. 이것이 ‘클라이언트 사이드 라우팅’입니다.
  2. 서버 사이드 라우팅 (새로고침 또는 직접 주소 입력 시):
    • 사용자가 주소창에 http://example.com/about을 직접 입력하거나, /about 페이지에서 새로고침(F5)을 누르면, 브라우저는 서버에 “/about이라는 파일을 주세요!”라고 직접 요청을 보냅니다.
    • 하지만 서버(Nginx, Apache 등) 입장에서는 /about이라는 이름의 파일이나 폴더가 존재하지 않습니다. 서버가 아는 파일은 오직 index.html static 폴더 안의 CSS/JS 파일뿐입니다.
    • 따라서 서버는 “요청하신 /about 파일을 찾을 수 없습니다”라는 의미로 404 Not Found 에러를 응답하는 것입니다.

해결 방법: “모든 경로 요청을 index.html로 보내라”

해결책은 간단합니다. 서버에게 “어떤 경로로 요청이 들어오든(예: /, /about, /users/123), 일단 무조건 index.html 파일을 먼저 보내줘. 라우팅은 그 안에 있는 React Router가 알아서 할 거야.” 라고 알려주는 것입니다.

사용하고 계신 웹 서버에 맞춰 아래 설정을 적용하시면 됩니다.


1. Nginx 사용 시 (가장 일반적인 경우)

Nginx 설정 파일 (/etc/nginx/sites-available/your-config 등)의 server 블록 안에 있는 location / 부분을 수정합니다.

try_files 지시어를 사용하는 것이 핵심입니다.


2. Apache 사용 시

Apache에서는 mod_rewrite 모듈을 사용하여 모든 요청을 index.html로 리디렉션합니다.

React 프로젝트의 **루트 디렉토리(보통 build 폴더 안)**에 .htaccess 파일을 생성하고 아래 내용을 추가합니다.

.htaccess

설명:

  • RewriteCond %{REQUEST_FILENAME} !-f: 요청된 경로가 실제 파일이 아니면
  • RewriteCond %{REQUEST_FILENAME} !-d: 그리고 실제 디렉토리가 아니면
  • RewriteRule . /index.html [L]: 모든 요청을 /index.html로 보낸다.

이를 통해 실제 존재하는 CSS, JS 파일 등은 직접 제공되고, /about과 같은 가상 경로는 index.html로 처리됩니다.


3. Firebase Hosting 사용 시

firebase.json 설정 파일에 rewrites 규칙을 추가합니다.

firebase.json

"source": "**"는 모든 경로를 의미하며, 이를 모두 /index.html로 보내도록 설정합니다.


4. Netlify / Vercel 등 정적 호스팅 플랫폼 사용 시

이런 최신 호스팅 플랫폼들은 React 같은 SPA 프레임워크를 자동으로 감지하여 이 설정을 알아서 적용해 줍니다. 특별히 설정할 필요가 없는 경우가 대부분입니다. 만약 문제가 발생한다면, 각 플랫폼의 리디렉션 및 재작성(Redirects & Rewrites) 규칙 문서를 참고하여 위와 동일한 원리의 규칙을 추가해주면 됩니다.

요약

문제 상황 원인 해결책
React Router 페이지에서 새로고침/직접접근 시 404 발생 서버가 React Router가 만든 가상 경로(/about 등)를 모르기 때문 Nginx 등 웹 서버 설정에서 모든 경로 요청을 **index.html**로 보내도록 설정

Nginx를 사용하고 계신다면, 위 Nginx 설정 예시를 적용하는 것만으로 문제가 바로 해결될 것입니다.