📝
基礎から始めるNext.js【17SSG & ISR 】
基礎から始めるNext.js【17SSG & ISR】
YouTube: https://youtu.be/z0csydqElog
今回は「ISR」を使用して、「SSG」でデータが追加されない問題を解決します。
ISR: https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration
ISRの実装は
「getStaticProps」のreturnの値に「revalidate: 10」を追加する。
「getStaticPaths」のreturnの値の「fallback: false」を
「fallback: 'blocking'」に変更する。
こちらの2つの設定で実装できます。
ISRの実装後はデータの追加後、
1度目のアクセスでISRによってビルドが実行され、
2度目のアクセスで追加されたデータが表示できるようになります。
1度目のアクセスではデータが追加されていない、
もしくは、データの変更が反映されていない古いデータが表示される点に
注意が必要です。
ビルドコマンド
npm run build
ビルドしたアプリの起動コマンド
npm run start
pages/ssg/index.tsx
import Link from 'next/link'
import Layout from '../../components/Layout'
import { Heading } from '@chakra-ui/react'
import { ListItem, UnorderedList } from '@chakra-ui/react'
import axios from 'axios'
import { GetStaticProps } from 'next'
export const getStaticProps: GetStaticProps = async () => {
const res = await axios.get(`http://localhost:1337/api/posts`)
return {
props: {
posts: res.data.data,
},
revalidate: 10,
}
}
export default function SSGPage({ posts }) {
return (
<Layout title="Next App TopPage" content="Generated by create next app">
<Heading as="h1" size="4xl" mb={2}>
SSG Posts List
</Heading>
<UnorderedList>
{posts &&
posts.map((post) => (
<ListItem key={post.id} fontSize={20} mb={1}>
<Link href={`/ssg/${post.id}`}>{post.attributes.title}</Link>
</ListItem>
))}
</UnorderedList>
</Layout>
)
}
pages/ssg/[id].tsx
import Layout from '../../components/Layout'
import { Heading } from '@chakra-ui/react'
import { ListItem, UnorderedList } from '@chakra-ui/react'
import axios from 'axios'
import { GetStaticPaths, GetStaticProps } from 'next'
import { FC } from 'react'
export const getStaticPaths: GetStaticPaths = async () => {
const res = await axios.get(`http://localhost:1337/api/posts`)
const paths = res.data.data.map((data: Post) => {
return { params: { id: String(data.id) } }
})
return {
paths,
fallback: 'blocking', // can also be true or 'blocking'
}
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
try {
const res = await axios.get(`http://localhost:1337/api/posts/${params.id}`)
return {
props: {
post: res.data.data,
},
revalidate: 10,
}
} catch (err) {
return {
notFound: true,
}
}
}
interface Post {
id: number
attributes: {
title: string
content: string
createdAt: string
}
}
interface Props {
post: Post
}
const SSGDetails: FC<Props> = ({ post }) => {
return (
<Layout title="Next App TopPage" content="Generated by create next app">
<Heading as="h1" size="4xl" mb={2}>
Post Title: {post && post.attributes.title}
</Heading>
<UnorderedList listStyleType="none">
<ListItem fontSize={30} mb={1}>
{post && post.attributes.content}
</ListItem>
</UnorderedList>
</Layout>
)
}
export default SSGDetails
Discussion