Next.js로 Page라우팅을 하게되면 SSG는 getStaticProps, SSR은 getServerSideProps 함수를 사용하게 된다. 이때 만약 라우팅하는 페이지가 동적 params를 갖는 페이지라면 getStaticProps만으로는 페이지 라우팅을 할 수 없다. 그렇다면 그냥 SSR로 하면 되는 게 아니냐 할 수 있지만, 아무래도 SSR보단 SSG가 페이지 진입에 훨씬 빠른 것은 사실이니, 될 수 있으면 SSG를 최대한 활용해 주는 것이 좋을 것이다.
getStaticProps와 함께 next.js에서 제공하는 getStaticPaths 함수를 사용하면 된다.
만약 params가 어느정도 미리 정해져있다면 getStaticPath의 리턴 객체에 paths 값을 설정해주면 된다.
export const getStaticPaths = async () => {
return {
paths: [{ params: { slug: 'abc' } }, { params: { slug: 'def' } }],
fallback: false
};
};
위 코드와 같은 방식으로 paths값을 설정하게 되면, slug 페이지의 params가 abc, def와 같이 미리 설정되어 있을 때, 해당 페이지로의 라우팅이 가능하다.
그런데 아마 대부분은 동적 params가 미리 정해져 있는 경우가 거의 없을 것이다. 만약 위 코드와 같이 설정한 뒤 'abc'나 'def'같은 경로를 입력하는 것이 아니라, 다른 경로를 입력한다면 당연히 404페이지로 이동하게 된다. 미리 정해져있지 않은 동적 params에 대해서도 404페이지를 띄우는 것이 아니라 내가 만든 페이지를 보여주고 싶다면, fallback 옵션을 사용하면된다.
fallback 옵션은 크게 3가지 옵션이 있다. 각각 false, 'blocking', true가 그것인데, false의 경우, 위와 같이 미리 설정한 경로로 진입하지 않으면 404로 보내버리는 옵션이다.
export const getStaticPaths = async () => {
return {
paths: [{ params: { slug: 'abc' } }, { params: { slug: 'def' } }],
fallback: true
};
};
fallback옵션을 true로 설정하면, staticProps의 값이 설정되지 않은 fallback상태의 페이지 즉, 서버에서 처리되어야 할 데이터가 들어있지 않은 껍데기 페이지가 우선 client로 전송이 되고, 입력된 params를 받아 next 서버에서 데이터를 불러온 후, client에 전송하는 방식으로 화면이 렌더링된다.
이때, 해당 페이지에 누군가가 처음으로 접근할 때에만 위와 같은 흐름을 따라가고, 저렇게 생성된 페이지는 SSG 형태로 next의 서버에 저장된다.
위 사진은 abc나 def가 아닌 123을 params로 입력한 결과인데, next 서버에서 123페이지를 생성했다는 것을 알 수 있고,
다음과 같이 실제 next서버에 해당 페이지에 대한 html파일 및 json파일이 생성된 것을 확인할 수 있다.
export const getStaticPaths = async () => {
return {
paths: [{ params: { slug: 'abc' } }, { params: { slug: 'def' } }],
fallback: 'blocking'
};
};
fallback옵션이 blocking일 때, 미리 설정되어 있지 않은 params경로로 요청이 들어오게 되면, 누군가 처음 진입 했을 때엔 SSR방식으로 페이지가 동작하고, true일 때와 마찬가지로 해당 페이지는 next 서버에 저장되어 그 이후부터는 SSG 방식으로 동작하게 된다.
true와 blocking일 때의 차이는 결국 초기 화면의 렌더링 속도이다.
fallback: true 의 경우, 요청이 들어오면 일단 fallback상태의 페이지가 먼저 전송되므로 사용자 입장에선 흰화면을 보는 시간이 그만큼 짧을 것이고,
fallback: 'blocking' 의 경우, 요청이 들어오면 next서버에서 staticProps의 데이터를 모두 처리해 응답을 주어야 하기 때문에 true에 비해 흰화면을 보는 시간이 더 걸릴 수 밖에 없다.
그리고 true방식을 사용 한 뒤, 데이터를 fetching하는 로직을 next서버에서 처리하는 것이 아니라, 컴포넌트 내부에서 수행해서 CSR과 유사한 방식으로 동작하게 하는 것도 가능하다.