이 글은 Next JS의 공식 문서를 읽고 개념을 요약해놓은 글입니다. 자세한 내용은 Next JS 공식홈페이지 참고
CRA처럼 비슷한 템플릿을 제공
npx create-next-app [프로젝트 제목] --use-npm [디렉토리]
npm run dev -> develop server 구동
next js에서 라우팅은 pages
안의 file의 이름을 기반으로 한다. 예를 들어,
pages/index.jsx
=== '/'
routepages/posts/first
=== /posts/first
routepages
폴더 안의 디렉토리에 js파일을 만들면, 해당 디렉토리가 url path가 된다.
client-side navigation은 기존의 browser가 담당하던 페이지 이동을 javascript가 담당한다는 의미.
a
태그를 사용하면 전체 페이지 refresh가 일어남.
react-router-dom
의 link와 같은 역할. 사용자와 상호작용하여 특정 url로 이동시킴
import Link from 'next/link';
<h1 className="title">
Read{' '}
<Link href="/posts/first-post">
<a>this page!</a>
</Link>
</h1>
a
태그를 Link
컴포넌트로 감싸준다.
next js는 각 페이지 별로 자동으로 code splitting을 해준다.
만약 해당 페이지에 Link
가 존재한다면 현재 페이지와 연결된 다른 페이지들을 미리 prefetching해 온다.
next js는 public
폴더에서 static assets들에 접근할 수 있다.
next js는 기본적으로 사진 사용에 대한 optimization을 제공한다. lazy load도 기본 옵션이다. 이미지가 viewport에 들어오면 loading을 시작한다.
import Image from 'next/image'
const YourComponent = () => (
<Image
src="/images/profile.jpg" // Route of the image file
height={144} // Desired size with correct aspect ratio
width={144} // Desired size with correct aspect ratio
alt="Your Name"
/>
)
<head>
태그 대신 <Head>
컴포넌트를 사용해서 metadata를 작성할 수 있다.
<script>
태그 대신 <Script>
컴포넌트를 사용. strategy
와 onLoad
attribute에서 load 전략과 load 직 후 취할 행동을 정할 수 있다.
import Head from 'next/head';
import Script from 'next/script';
export default function FirstPost() {
return (
<>
<Head>
<title>First Post</title>
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
onLoad={() =>
console.log(`script loaded correctly, window.FB has been populated`)
}
/>
</Head>
<h1>First Post</h1>
<h2>
<Link href="/">
<a>Back to home</a>
</Link>
</h2>
</>
)
}
next js는 기본적으로 css-in-js를 built-in으로 제공한다. (styled-components를 사용해도 된다고 한다.) 자동적으로 각 파일마다 임의의 class를 지정해주기 때문에 className 정하는 일로 골치아플 일은 피할 수 있을 듯하다.
import styles from './layout.module.css';
export default function Layout({ children }) {
return <div className={styles.container}>{children}</div>
}
추가로 next js의 code splitting은 스타일 파일에서도 자동으로 적용된다고 한다.
전체 페이지에 적용되는 css 적용을 위해서는 조금 제약이 있다.
pages/_app.js
파일을 생성한 후, 해당 파일에서 css를 load해야 한다. 이 파일은 react에서의 App.js
와 비슷한 역할을 한다. 다른 모든 페이지에 영향을 주는 top-level 컴포넌트 이다.
styles/global.css
파일을 만들고 해당 파일을 pages/_app.js
에서 불러오자.
// _app.js
import '../styles/global.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
next js는 모든 페이지를 기본적으로 pre-rendering한다. 각 페이지 별로 html 파일을 미리 생성해놓는다는 이야기다. 각 페이지가 브라우저에 의해 불러와질 때, js코드가 작동하고 페이지의 빈 부분을 채워넣는다.(hydration)
SG와 SSR은 섞어서 사용할 수 있다. 좀 더 실시간 update가 많은 페이지에는 SSR을 사용하자.
어떠한 page에서는 반드시 외부 데이터가 있어야 html 파일을 생성할 수 있는 경우가 있다. 이러한 경우에는 getStaticProps
를 사용하자.
export default function Home(props) { ... }
export async function getStaticProps() {
// Get external data from the file system, API, DB, etc.
const data = ...
// The value of the `props` key will be
// passed to the `Home` component
return {
props: ...
}
}
getStaticProps
는 next js에게 해당 페이지는 특정 데이터에 의존한다는 것을 알려준다.
export async function getSortedPostsData() {
// Instead of the file system,
// fetch post data from an external API endpoint
const res = await fetch('..')
return res.json()
}
getStaticProps
는 오직 server에서만 작동한다. client쪽에서는 작동하지 않으며, bundle 파일에도 포함되지 않는다.
development 모드에서는 getStaticProps
는 매 요청마다 작동, production 모드에서는 빌드시에만 작동
또한 pages
폴더 안에서는 export 가능하다.
미리 사용자의 요청에 맞는 html 파일을 생성할 수 없을 때
매 요청 때마다 새로 데이터를 fetching해와야 할 때는 SSG를 사용해야 한다.
이 경우에는 getStaticProps
대신 getServerSideProps
를 사용해야한다.
export async function getServerSideProps(context) {
return {
props: {
// props for your component
}
}
}
context는 request에 사용할 parameter
각각의 page path가 fetching하는 데이터에 의존할 때.
pages/posts/<id>
의 id가 외부에서 불러오는 데이터에 있는 경우.
전체 과정은 다음과 같다.
pages/posts
폴더 안에 pages/posts/[id].js
파일 생성. []
는 동적라우팅을 의미한다.getStaticPaths
를 사용해서 id로 사용가능한 값의 배열 returngetStaticProps
로 id에 따른 데이터 fetchingimport Layout from '../../components/layout'
export default function Post() {
return <Layout>...</Layout>
}
export async function getStaticPaths() {
// Return a list of possible value for id
const paths = getAllPostIds()
// Returns an array that looks like this:
// [
// {
// params: {
// id: 'ssg-ssr'
// }
// },
// {
// params: {
// id: 'pre-rendering'
// }
// }
// ]
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
// Fetch necessary data for the blog post using params.id
}
getStaticPaths
의 return 값은 array of objects 여야!! 각 object는 params를 key로 가지고 있어야 한다.
getStaticProps
는 위에서 처럼 page 컴포넌트로 넘길 props를 return하면 된다.
getStaticPaths
는 getStaticProps
와 마찬가지로 dev모드에서는 매 요청마다, prod모드에서는 빌드 시에 작동한다.
fallback이 false 이면 getStaticPaths
의 return에 없는 라우팅은 404페이지를 낸다.
true일 경우, 404 페이지를 내지 않고 Next.js will statically generate the requested path
blocking일 경우, new paths will be server-side rendered with getStaticProps
pages/posts/[...id].js
은 /posts/a
, /posts/a/b
, /posts/a/b/c
모두 catch한다.
이 경우 getStaticPaths
에서 다음과 같이 return 해야 한다.
return [
{
params: {
// Statically Generates /posts/a/b/c
id: ['a', 'b', 'c']
}
}
//...
]
getStaticProps
, getServerSideProps
, getStaticPaths
를 통해서