如果想要 Next.js 在 server 端就產出網頁內容,並且又想使用 dynamic routes 的話,除了使用 getStaticProps
之外,還必須搭配 getStaticPaths
,如此一來 Next.js 才會預先在 server 端就把畫面渲染出來。
那麼,在什麼樣的情況下會需要使用 getStaticPaths
呢?部落格就是一個很好的例子,我們將文章寫好後,透過 getStaticPaths
產生出所有文章的 paths,接著在 getStaticProps
就可以根據 path 去 render 不同的頁面。Next.js也有列出一些應該使用 getStaticPaths
的情況,有興趣的讀者可以點擊連結去看看。
本篇文章不會介紹什麼是 Next.js,而會著重在如何使用 getStaticPaths
,所以如果讀者不知道什麼是 Next.js 的話,推薦先去 Next.js 的 Learn Course 學習。
檔案結構
接下來會以部落格做為例子來講解,以下是專案的檔案結構:
- pages
- [post].tsx
- index.tsx
- posts
- foo.md
- bar.md
- 其餘資料夾及檔案
[post].tsx
在[post].tsx 中除了要 export page component 之外,還需要 export getStaticPaths
以及 getStaticProps
。
type Props = {
metadata: PostMetadata;
content: string;
};
type Query = {
post: string;
};
export const getStaticPaths: GetStaticPaths<Query> = async () => {
// ...
};
export const getStaticProps: GetStaticProps<Props, Query> = async ({ params }) => {
// ...
};
const Post: NextPage<Props> = ({ metadata, content }) => {
// ...
};
export default Post;
getStaticPaths
getStaticPaths
需要回傳一個 object,這個 object 需要包含 paths
和 fallback
,其中 paths
是用來決定哪些 paths 會 pre-rendered,而 fallback
則是用來決定那些沒有 pre-rendered 的 path 要如何顯示。
export const getStaticPaths: GetStaticPaths<Query> = async () => {
return {
paths: [{ params: { post: 'foo' } }, { params: { post: 'bar' } }],
fallback: false,
};
};
由於 dynamic routes 的檔案名稱叫做[post].tsx,在 params
中就一定要有 post
這個 property,否則 dynamic routes 就會失效。至於 fallback
總共有三種值可以傳入,true
, false
和 'blocking'
,這邊傳入 false
代表任何不是從 getStaticPaths
回傳的 paths 都會被導向 404 page,如果有讀者想更深入了解 fallback
的話,可以到這裡看看。
getStaticProps
接著我們就可以依據在 getStaticPaths
中獲得的 params
來回傳 page component 所需要的 Props。
export const getStaticProps: GetStaticProps<Props, Query> = async ({ params }) => {
if (!params) return { notFound: true };
const post = params.post;
const { metadata, content } = getPostData(post);
return {
props: {
metadata,
content,
},
};
};
上面的 getPostData
會回傳 posts/foo.md
或是 posts/bar.md
中的 metadata 以及內容,由於本篇文章的主題是介紹 getStaticProps
,所以就不多做贅述。
Post
最後就是 Post
component 根據 getStaticProps
回傳的 props 來去渲染畫面。
const Post: NextPage<Props> = ({ metadata, content }) => {
const { title, description } = metadata;
return (
<div>
<Head>
<title>{title}</title>
<meta name='description' content={description} />
</Head>
<Markdown>{content}</Markdown>
</div>
);
};
結語
由於這篇文章只是想用來記錄怎麼使用 getStaticPaths
,所以省略了很多東西。例如在 getStaticPaths
中應該是不太會把所有 paths 都寫死,以部落格為例子的話,通常是讀取 posts 資料夾中所有的檔案,接著去掉副檔名後用檔案名稱來當作 path。
另外,其實這個網站就是用 Next.js 寫的,部落格的部分也有使用 getStaticPaths
,雖然寫得可能沒有很好,但如果讀者有興趣的話可以到這裡看看。