본문 바로가기
Recap/에러 해결 기록

vercel로 배포 후 새로고침 시 404 이슈와 클라이언트 사이드 라우팅

by yerin.dev 2024. 3. 1.

문제 상황

 

bookshelf 프로젝트 배포 후 크고 작은 에러를 모두 해결하고, 이젠 다 됐겠지 하는 마음으로 사이트를 확인하는데 새로고침만 하면 갑자기 404가 등장했다.

 

 

 

 


또 구글에 쳐봤다. vercel 404 when refresh
나온 스택 오버 플로우 글

 

 

해결방법

// vercel.json

{ "routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }] }

 

 

처음에 이걸로 설정했는데 git push하고 나니 자동으로 되던 배포가 안 되는거다. 이유는 vercel.json에 'routes'와 "redirect"를 동시에 사용할 수 없어서였다.


그래서 아래처럼 다시 설정해주었다.

 

 

// vercel.json

{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}

 

 

 

이 코드의 의미:
'rewrites': 서버에게 들어오는 요청을 어떻게 처리하고 리다이렉트 해야하는지 알려주는 것.
"source": "/(.*)" : /로 시작하는 모든 요청을
"destination": "/index.html" }]: index.html로 보내주는 것.

 

들어오는 모든 요청을 index.html로 연결해주는 것이다. SPA 어플리케이션에서 주로 이런 식의 방법을 사용한다.
이렇게 리다이렉트 해주지 않으면 특정한 루트에 직접 접근하거나 페이지를 새로고침했을 때 서버가 그 루트에 맞는 파일을 찾지 못해서 404 에러가 발생할 수 있다.

 

 

위의 설정을 해주지 않았을 경우 SPA에서 일어나는 일 ~

 

  1. 사이트의 루트 url에 들어갔을 때는 당연히 화면이 제대로 보인다. index.html이 제대로 내려오고 있기 때문.
  2. 루트에 직접 접근하거나 새로고침을 하면 (예를 들어, https://your-app.vercel.app/about에 접근) 서버가 루트에 대응되는 파일을 찾지 못해서(실제로 없으므로) 404 에러가 일어난다.

 

 

저렇게 rewrites 설정을 해줌으로써 모든 요청에 대해서, 어떤 루트에서 요청되든지간에 index.html을 보내주게 되고, 그 다음에는 리액트 라우터 돔에서 루트에 맞는 적절한 컴포넌트를 보여주게 된다.

 

 

Client Side Routing

 

 

그냥 버튼을 클릭해서 이동할 때는 페이지가 제대로 이동되었던 것은 react-router-dom 덕분이었던 것.

페이지를 처음 열거나 새로고침하면 요청은 서버로 간다. 이때 루트 페이지에 접근한 것이라면 상관이 없겠지만 다른 루트로 접근한 거라면 404 에러가 난다.


최초로 페이지를 연 그 이후에는 브라우저가 서버에 요청을 보내는 것이 아니라, 클라이언트 사이드 라우팅이 이루어지기 때문이다. 주소창의 주소는 바뀌고, 페이지 내의 컨텐츠는 계속 바뀌지만 새로 요청을 보내서 페이지가 리로드 되고, 컨텐츠가 변경된 것이 아니다.

그렇다면 클라이언트 사이드 라우팅(리액트 라우터 돔 같은)이 하는 일은? 링크를 클릭하면 브라우저의 주소창의 주소를 업데이트 하고, 맞는 컴포넌트를 보여준다. 한 마디로, 페이지 이동과 렌더링을 클라이언트 측에서 하는 것!

 

따라서, csr 없이 직접 주소에 접근할 때도 제대로 요청이 index.html로 들어가도록 하기 위해서 저렇게 rewrites 설정을 해 준 것이다.