- HOME >
- Jamstack用語集 >
- getStaticPaths
getStaticPaths
ゲットスタティックパス
getStaticPaths を分かりやすく?
getStaticPaths
は、Next.js で静的なページを生成するための機能の 1 つです。静的なページを生成する場合、通常、全ての URL を手動で記述する必要がありますが、getStaticPaths
を使うことで、動的な URL を指定することができます。
たとえば、ブログサイトで各記事を動的に生成する場合、記事の ID を URL に含める必要があります。例えば、/posts/1
、/posts/2
というように、/posts/:id
という形式の URL が生成されます。
この場合、getStaticPaths
を使って、どの記事の URL を生成するかを指定することができます。
// pages/posts/[id].tsx
export const getStaticPaths: GetStaticPaths = async () => {
const res = await fetch('https://my-blog.com/api/posts')
const posts = await res.json()
const paths = posts.map((post: any) => ({
params: { id: post.id },
}))
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const res = await fetch(`https://my-blog.com/api/posts/${params.id}`)
const post = await res.json()
return { props: { post } }
}
上記の例では、getStaticPaths
で、記事の一覧を取得し、それぞれの記事の ID を含んだパスを生成しています。これにより、/posts/1
、/posts/2
など、記事ごとに URL を動的に生成することができます。
fallback
オプションについて
getStaticPaths
には、fallback
というオプションがあります。これは、動的に生成するページが存在しない場合にどうするかを指定するためのものです。
fallback: false
と指定した場合、存在しないページにアクセスした際に 404 エラーが返されます。
fallback: true
と指定した場合、存在しないページにアクセスした際に、ページが動的に生成されます。ただし、初回アクセス時には生成されないため、表示に時間がかかる可能性があります。
fallback: 'blocking'
と指定した場合、ページが動的に生成されるまでの間、表示されるコンテンツを指定することができます。fallback: true
と同様に、初回アクセス時にはページが生成されないため、表示に時間がかかる可能性があります。
// pages/posts/[id].tsx
import { GetStaticProps, GetStaticPaths } from 'next'
import { getAllPostIds, getPostData } from 'lib/posts'
import { PostData } from 'types/post'
import Layout from 'components/layout'
type Props = {
postData: PostData
}
const Post = ({ postData }: Props) => {
return (
<Layout>
{postData.title}
<br />
{postData.id}
<br />
{postData.date}
</Layout>
)
}
export default Post
export const getStaticPaths: GetStaticPaths = async () => {
const paths = getAllPostIds()
return {
paths,
fallback: false,
}
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const postData = await getPostData(params.id as string)
return {
props: {
postData,
},
}
}
getStaticPaths
は GetStaticPaths
型を持ち、関数の中身は async
を使って非同期的に処理します。この関数は、動的なページを作成するときに、その動的なページのパラメータを含んだ静的なファイルを事前に生成するために使われます。
例えば、[id].tsx
という動的なページがあったとします。このページは /posts/1
や /posts/2
のように、URL の最後に数字がついたページを表示します。このとき、getStaticPaths
はどの数字のページが生成されるべきかを決定します。getAllPostIds
関数は、実際に生成されるページの ID のリストを返します。
getStaticPaths
の戻り値は、以下のように paths
と fallback
から成り立ちます。
return {
paths,
fallback,
}
paths
は、動的なページのパラメータを含んだ静的なファイルのパスのリストです。今回は getAllPostIds
から ID のリストを取得して、そのリストを paths
として返しています。fallback
は、false
にすると存在しないパスへのアクセスがあった場合に 404 エラーを返します。
サブパスの配列を返す関数
fallback: false
を指定している場合、getStaticPaths
はサブパスの配列を返す関数になります。次の例は、getStaticPaths
が['/posts/1', '/posts/2']
を返す場合の例です。
export async function getStaticPaths() {
return {
paths: ['/posts/1', '/posts/2'],
fallback: false,
}
}
この例では、'/posts/1'
と'/posts/2'
の 2 つのサブパスを持つ配列を返しています。
ダイナミックルーティング
getStaticPaths
はダイナミックルーティングと組み合わせて使用されることがよくあります。例えば、/posts/[id].tsx
という名前のページがある場合、getStaticPaths
はこのように実装できます。
export async function getStaticPaths() {
const res = await fetch('https://example.com/posts')
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return { paths, fallback: false }
}
この例では、外部 API から投稿のリストを取得し、それぞれの投稿に対応するパラメータ付きのサブパスを生成しています。例えば、投稿が{ id: 1 }
と{ id: 2 }
の場合、/posts/1
と/posts/2
のサブパスが生成されます。
fallback: false
を指定しているため、生成されたすべてのサブパスが事前に生成され、次にアクセスされるときにはすべてのページの HTML が事前に生成された静的ファイルとして提供されます。
パラメータの検証
getStaticPaths
は、不正なパラメータをブロックするために、パラメータの検証にも使用できます。次の例では、params.id
が数字であることを確認しています。
export async function getStaticPaths() {
const paths = [{ params: { id: '1' } }, { params: { id: '2' } }]
for (const path of paths) {
const id = path.params.id
if (isNaN(+id)) {
throw new Error(`Invalid id: ${id}`)
}
}
return { paths, fallback: false }
}
この例では、'1'
と'2'
という文字列で初期化された 2 つのパラメータを持つ配列を返し、isNaN()
関数を使用して文字列が数値であるかどうかを確認しています。パラメータが数値ではない場合、エラーがスローされます。
getStaticPaths の代わり
Next.js 13 の新機能として、React Suspense を利用した app/ディレクトリでは、getStaticProps や getServerSideProps といったこれまでの Next.js API を置き換える新しい usehook が導入されています。この新しい方法を利用すると、データをフェッチすることができます。以下は、getStaticProps の代わりに fetchData 関数を使用する例です。
// app/post/[id]/page.tsx
export async function generateStaticParams() {
return [{ id: "1" }, { id: "2" }]
}
async function fetchPost (params) {
const response = await fetch('https://.../${params.id}`)
const data = await response.json()
return data.post
}
export default async function Post({ params }) {
const post = await fetchPost (params)
return <Post post={post} />
}