localhost에서 React Router 를 활용한 프로젝트를 배포 했을 때, 404 에러가 발생한다.
그 원인과 해결방안에 대해서 알아보았다.
사실 다 알고있는 내용이었고, aws 배포시 레퍼런스만 보고 따라했어서 명확한 원인은 이번에 알게 되었다.
React는 기본적으로 CSR이다.
React Router로 path 이동을 시키는 것처럼 보여지지만,
그냥 이름만 지어줄 뿐 그 사실이 변하지 않는다.
사용자가 최초 접속 이후 서버에 요청을 하면, build 된 index.html 을 보내준다.
그 html파일에는 번들링된 js나 css파일이 연결되어있는 상태이다.
html파일이 읽히면서, js와 css 파일이 작동이 된 이후, React-Router가 작동되는 형식이다. 즉, path이동과 routing은 작동을 하지만 모든것이 CSR에서 이뤄지고 서버는 아무런 관계가 없다.
우선 Router라는 것은 어떤 인풋 하나로 다양한 아웃풋으로 나아가게 하는 중계기의 의미이다.
즉, React에서도 Router 라는 것은 index.html에 들어오고 나서 Router를 거침으로서 나머지 페이지로 이동할 수 있게 하는 중계의 역할을 한다.
React SPA(Singl Page Application) 구현의 핵심이며,
기존 방식의 <a href=""></a>
는 url 변경 시 새로고침 되며 모든 페이지를 reload 하여 로드 시간이 걸리게 된다.
'react-router-dom'을 이용해 새로고침 대신 Router를 사용하여 변경된 소스만 바뀌도록 해주기 때문에 속도가 빠르다.
일반적으로 url에서 path가 /
로 나뉘어진다.
그래서 배포 환경에서 새로고침 할 때,
이미 url은 React-Router의 path로 지정 되어 있는 상태이기 때문에,
서버는 그것이 무엇을 반환해달라는 말인지 알 지 못한다.
따라서 404 Not Found 에러를 반환하는것이다.
당연히, 아무런 path가 없는 첫 화면은 ’/’ 상태이기 때문에 index.html을 잘 받아와 에러가 생기지 않는 것이다.
그래서 aws 배포시에는 이에 대응한 다양한 방법이 있지만,
보통 에러가 발생할 때 보여주는 error.html을
index.html로 보여주고 cloud front 에서 404 오류 메세지를 200 ok 로 수정하도록 설정해준다.
-> 서버가 주소의 이동을 모르게 됨 (페이지 존재유무에 대해서 모름)
hash가 뭔지 알아보자면, 일반적으로 url에서 hash는 페이지의 특정 요소를 참조하기 위해 사용한다.
예를 들어,
/document#who-am-i
로 이동하면, 브라우저는 html soqndptj id가 who-am-i인 엘리먼트를 찾아 해당 위치로 스크롤 해준다.
hash는 단순히 internal reference 이기 때문에, hash 값이 바뀌더라도 새로운 페이지를 요청하지 않는다.
예시에서 hash 값을
/document#what-is-this
로 바꿔줘도 엔드포인트는 hash를 제외한 /document 이다.
이러한 특징은 SPA를 만들 때 장점이 된다.
React에서는 만약 다음과 같은 url이라면
http://localhost:3000/#/management/useranalysis
brower는 localhost:3000 까지만 읽는것이다.
그래서 index.html을 잘 받아와 404 에러가 발생하지 않는다.
SEO 에 상관없는 어드민 페이지나 정적 페이지 같은 경우에는
배포시 HashRouter를 사용해도 무방함.
SEO 를 고려해야하고, Router의 다양한 기능을 활용하거나,
동적 페이지 같은 경우에는 배포시 Browser Router 를 사용하자.