[Next.js] getStaticPaths (Static Generation/fallback/동적 라우팅)

2023. 1. 17. 01:38·Archive
반응형

 

1. getStaticPath 예시
2. fallback

 


 

동적 라우팅 페이지에서의 pre-rendering

 

Next의 pages폴더에서 [대괄호]로 파일명을 생성하면 동적 라우팅을 할 수 있다.

이 때 주의해야 할 점은 Next는 모든 페이지를 사전생성 하지만, 동적 페이지에서는 그렇지 않다는 점이다.

동적 페이지에서 getStaticProps를 사용하여서 페이지에 진입하게 되면 아래와 같은 에러를 만나게 된다.

 

 

대괄호 [ ]로 만든 동적 페이지는 엄밀하게 따져서 하나의 페이지가 아닌 여러 페이지이다.

때문에 Next는 사전에 동적 페이지를 위해서 얼마나 많은 페이지를 미리 생성해야할지 알 수 없다.

이럴 때 비동기 함수 getStaticPaths를 이용하여 Next에게 어떤값에 대한 페이지가 pre-rendering되어야 할 지 지정해준다.

정확히 말해 동적 페이지의 어떤 구체적인 인스턴스를 사전에 생성할지 알려주는 것이다.

Multiple concrete [id] page instances (ex. id=1, id=2 etc) are pre-generated.

 

 

 

 

 


 

 

 

 

getStaticPath 예시

 

 

 

예를들어 getStaticProps에 아래의 코드대로 /p1 /p2 /3의 동적인 페이지를 만든다고 한다면,

// dummy.json
{
  "products": [
    { "id": "p1", "title": "Product 1", "description": "This is product 1" },
    { "id": "p2", "title": "Product 2", "description": "This is product 2" },
    { "id": "p3", "title": "Product 3", "description": "This is product 3" }
  ]
}
export async function getStaticProps(context) {
  const { params } = context;
  const productId = params.pid;

  const filePath = path.join(process.cwd(), 'data', 'dummy.json');
  const jsonData = await fs.readFile(filePath);
  const data = JSON.parse(jsonData);

  const product = data.products.find((product) => product.id === productId);
  return {
    props: {
      product: product,
    },
  };
}

const ProductdatailPage = ({ product }) => {
  return (
    <>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
    </>
  );
};

export default ProductdatailPage;

 

 

 

해당 경로를 반환하는 paths 객체를 getStaticPaths로 지정해준다.

export async function getStaticPaths() {
  // paths가 있는 객체를 반환
  return {
    paths: [
      { params: { pid: 'p1' } },
      { params: { pid: 'p2' } },
      { params: { pid: 'p3' } },
    ],
    fallback: false,
  };
}

 

 

설정 후 다시 앱을  build해보면 getStaticPaths로 지정한 p1/p2/p3 페이지가 pre-rendering 된 것을 확인할 수 있고,

.next/server/pages폴더에도 p1~p3.html 파일이 생성된 것을 확인할 수 있다.

 

 

 

 

 

paths의 id값을 하드 코딩한 부분을 수정

 

 

 

 

 

* context 매개변수
   - params : 경로상의 동적 세그먼트에 대한 구체적인 값을 알 수 있다. {key : 값}
// pages/posts/[slug].js

export function getStaticProps(context) {
  const { params } = context;
  const { pid } = params;
  console.log('🚀 ~ file: [slug].js:21 ~ getStaticProps ~ params', params);

  ...
}

{ key : 값 } 형태로 출력

 

 

 

 

 

 

 

 

fallback

 

fallback: false

  • getStaticPaths에서 리턴하지 않는 페이지는 모두 404로 연결
  • page의 data가 자주 추가되지 않거나, 새로 생성되는 페이지의 수가 적을 때 사용한다.

 

 

fallback: true

  •   데이터에 의존하는 정적 페이지가 많아서 모든 페이지를 pre-rendering 하는것이 무리이고 불필요하다고 생각될 때,
      = 일부 페이지만 pre-rendering 하고 싶을 때 true설정한다.
  •   지정하지 않은 나머지 페이지는 pre-rendering되지 않고 request가 서버에 도달하는 순간 생성된다.
  •   빌드 시간과 사용자들의 응답 속도를 단축할 수 있다

 

fallback: true is useful if your app has a very large number of static pages that depend on data (such as a very large e-commerce site). If you want to pre-render all product pages, the builds would take a very long time.

 

 

* 주의해야 할 점은 pre-rendering하지 않은 나머지 path들이 로딩되는 순간(=props로 아직 아무값도 view로 넘어오지 않은 단계)을

고려해야한다. router.isFallback이 true일 때 혹은 props이 아직 넘어오지 않아서 false일 때로 조건을 준다.

export async function getStaticPaths() {
  return {
    paths: [{ params: { pid: 'p1' } }],
    fallback: true,
  };
}
import { useRouter } from 'next/router';
const ProductdatailPage = ({ product }) => {
  const router = useRouter();
  //isFallback 상태일 때
  if (router.isFallback) {
    return <p>Loading...<p>;
  }
  
  return (
    <>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
    </>
  );
};

export default ProductdatailPage;
const ProductdatailPage = ({ product }) => {
  //props이 아직 들어오지 않음
  if (!product) {
    return <p>Loading...<p>;
  }
  ...

paths로 지정한 p1을 제외한 p2-p3의 html파일은 사라진 것을 확인할 수 있다.

 

 

 

 

 

fallback : 'blocking'

  • 최초 만들어놓지않은 path에 대한 요청이 들어온 경우 fallback 상태를 보여주지 않고 SSR로 동작 (서버에서 완전히 pre-rendering된 후 html이 생성되면) 한다.
  • SSR로 동작하기 때문에 loading/fallback 상태가 필요없다.
  • 한 번 방문한 경로는 pre-rendered pages 목록에 추가되어, 최초 build타임에 pre-rendering 되어진 경로와 동일하게 동작한다.
  • next export 사용 시 'blocking'은 지원되지 않는다.

 

 

 

 

 

* fallback : true 일 때, 사전에 정의되지 않은 경로로 진입 시  에러가 발생할 수 있으므로

   지정된 경로가 아닐 시 notFound : true로 404 페이지로 이동하도록 한다.

 

 

 
반응형

'Archive' 카테고리의 다른 글

[Frontend] 프론트엔드 주니어 개발자 면접 질문 (기술/인성)  (1) 2025.04.08
[Next.js] Pre-rendering 개념 & Static Generation(getStaticProps)  (1) 2023.01.08
[Regex] 정규 표현식 기초 (2) - 대괄호 / 부정부호 / 꺽쇠  (0) 2022.12.05
[JS] JavaScript 개념 (자바스크립트 엔진, 원시형/참조형, Stack/Heap)  (0) 2022.11.28
[JS] JavaScript ES6 - var / let / const  (0) 2022.11.25
'Archive' 카테고리의 다른 글
  • [Frontend] 프론트엔드 주니어 개발자 면접 질문 (기술/인성)
  • [Next.js] Pre-rendering 개념 & Static Generation(getStaticProps)
  • [Regex] 정규 표현식 기초 (2) - 대괄호 / 부정부호 / 꺽쇠
  • [JS] JavaScript 개념 (자바스크립트 엔진, 원시형/참조형, Stack/Heap)
manon_e
manon_e
  • manon_e
    개발 블로그
    manon_e
  • 전체
    오늘
    어제
    • 💻 (103)
      • Frontend (10)
        • React | Next.js (6)
        • Memo (4)
      • CS (2)
        • 네트워크 (0)
        • 자료구조 + 알고리즘 (0)
        • 컴퓨터 구조 + 운영체제 (2)
      • Cloud & Infra (0)
      • Project (4)
      • Archive (87)
  • 인기 글

  • 태그

    axios
    useEffect
    vscode
    State
    정규표현식
    티스토리챌린지
    JavaScript
    비동기
    getstaticprops
    git
    Node
    pre-rendering
    ES6
    오블완
    node.js
    Next.js
    Prisma
    REACT
    typeScript
    Component
  • hELLO· Designed By정상우.v4.10.3
manon_e
[Next.js] getStaticPaths (Static Generation/fallback/동적 라우팅)
상단으로

티스토리툴바