Published on

Nextjs Pages Router

Authors
  • avatar
    Name
    Inhwan Cho
    Twitter

설치

일단 프로젝트 설치 시 App Router를 No를 선택해줘야 합니다. -> pages router

npx create-next-app@latest project-name

...
App Router  ->  No
...

Pages Router와 App Router의 차이점

nextjs 12 버전 이하에서는 App Router가 아닌 Pages Router를 사용했습니다.

최상단에 'use server'를 기본값으로 설정되있는게 아니고 'use client'가 기본값으로 설정되있습니다.

그렇기 때문에 사용방법이 App Router와 많이 다릅니다.

일단 layout.tsx대신 _app.tsx를 사용합니다.

아래의 구조가 기본값이며 여기에 layout을 채워주면 됩니다.

pages/_app.tsx
import "../styles/globals.css";

export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

getServerSideProps

기본적으로 page에서 db에서 불러오는 데이터들은 client의 html에서는 비어있습니다. 이때, getServerSideProps을 사용하면, server에서 html을 load를 할 수 있습니다. 데이터가 적을때 사용하면 좋으며, loading이 없이 한 번에 페이지를 불러옵니다. 단, 데이터가 크거나 많다면 페이지에 아무것도 보이지 않을 수 있고, 서버에 부담이 될 수있습니다.

pages/index.tsx
export default function Page({items}) {
  return <div>{items}</div>
}

export async function getServerSideProps(ctx) {
  console.log("SSR")
  console.log(ctx)
  const items =await client.items.findMany({});
  return {
    props: {
      items: items,
},
}
}

getStaticProps

위에서도 언급한것 처럼 기본적으로 만들어진 페이지는 요소검사를 해보면 내부의 content가 비어있습니다. CSR이기 때문에 SEO에서 아무런 이점이 없습니다.

getStaticProps를 사용하면 'use server'와 동일한 효과를 볼 수 있습니다. 즉, getStaticProps는 server에서 미리 랜더링을 하게됩니다.

단, 이렇게 정적(Static)하게 생성된 html 파일은 build시 1회만 생성되며 수정하려면 다시 build해야됩니다. 그렇기 때문에 추가 옵션(ODR 등)을 통해 요청에 따라 html을 생성하는 편입니다.

pages/index.tsx
export default function Page({data}) {
  const first = data[0];
  console.log(first);
  return (<div>{first}</div>)
}

export const getStaticProps = async (context) => {
  const res = await fetch("https://abcde.json");
  const data = await res.json();
  return { props: { data } };
};

getStaticPaths

또한, 동적(다이나믹) 라우팅을 할 경우는 getStaticPaths를 사용합니다.

다이나믹 라이팅은 각각 파일을 생성하여 detail page를 여러개 만들 필요 없이 각각 파일을 생성할 필요 없이, /pages/detail/[id].tsx 파일 하나만으로도 모든 페이지를 생성할 수 있다는 뜻입니다.

pages/person/[id].tsx
export default function Person({person}){
  return (
    <div>
      <h3 >{person.name}</h3>
    </div>
  )
}

export async function getStaticPaths() {
  const res = await fetch('https://abcde/')
  const persons = await res.json()
  const paths = persons.map((person) => ({
    params: { id: person.id },
  }))
  return { paths, fallback: false }
  //fallback은 paths에서 리턴되지 않은 경로에서 404로 전달하는 옵션이 false입니다.
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://abcde/person/${params.id}`)
  const person = await res.json()
  return {
    props: {
      person,
    }
  }
}

getStaticPaths 에서 'https abcde' 저장된 데이터를 불러온 다음 거기에있는 id값만 리턴을 하고, 그 id값을 기반으로 다시 'https abcde person id'의 값을 리턴합니다.