Lang x Lang

Static Site Generation (SSG)

Examples

もしページがStatic Generationを使用している場合、そのページの HTML はbuild 時に生成されます。つまり、production では、next build を実行したときにそのページの HTML が生成されます。この HTML は各々の request で再利用されます。それは CDN によってキャッシュされます。

Next.js では、データがある場合とない場合の両方でページを静的に生成することができます。それぞれのケースを見てみましょう。

データなしの静的生成

default として、Next.js はデータを取得せずに Static Generation を使用してページを事前にレンダリングします。ここに例があります:

function About() {
  return <div>About</div>;
}

export default About;

このページは、fetch という外部データを事前にレンダリングする必要はありません。このような場合、Next.js は build 時間中にページごとに一つの HTML ファイルを生成します。

データを用いた静的生成

一部のページは、事前レンダリングのために外部データのフェッチが require です。2 つのシナリオがあり、1 つまたは両方が適用されるかもしれません。それぞれのケースで、Next.js が提供するこれらの関数を使用できます:

  1. あなたのページのコンテンツは外部データに依存しています:getStaticPropsを使用してください。
  2. あなたのページのpathsは外部データに依存します:getStaticPathsを使用してください(通常はgetStaticPropsと併用)。

シナリオ 1:あなたのページコンテンツは外部データに依存しています

: あなたのブログページは、CMS(コンテンツ管理システム)から fetch を使ってブログ記事のリストを取得する必要があるかもしれません。

// TODO: Need to fetch `posts` (by calling some API endpoint)
//       before this page can be pre-rendered.
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  );
}

このデータをプレレンダリングで fetch するために、 Next.js は同じファイルからexportというasync関数をgetStaticPropsとして出力することができます。この関数は build 時に呼び出され、プレレンダリング時にフェッチしたデータをページのpropsに渡すことができます。

export default function Blog({ posts }) {
  // Render posts...
}

// This function gets called at build time
export async function getStaticProps() {
  // Call an external API endpoint to get posts
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  };
}

getStaticPropsの仕組みについてより詳しく学ぶには、データフェッチングのドキュメンテーションをご覧ください。

シナリオ 2:あなたのページの paths は外部データに依存しています

Next.js は、dynamic routesを持つページを作成できます。例えば、pages/posts/[id].jsと呼ばれるファイルを作成して、idに基づいた単一のブログの post を表示することができます。これにより、posts/1にアクセスすると、id: 1のブログの post を表示できます。

To learn more about dynamic routing, check the Dynamic Routing documentation.

ただし、どの id を build 時に事前レンダリングするかは、外部データによって異なるかもしれません。

: データベースに post (id: 1を持つ)ブログを 1 つだけ追加したと仮定します。この場合、 build 時にはposts/1のみを事前レンダリングすることを望むでしょう。

その後、 id: 2 を持つ second post を追加するかもしれません。その場合、 posts/2 も事前にレンダリングしたいでしょう。

したがって、あらかじめレンダリングされているページのpathsは外部データに依存しています。これを処理するために、Next.js では、exportというasync関数を、今回の例では dynamic なページ(pages/posts/[id].js)からgetStaticPathsという名前で出力することができます。この関数は build 時に呼び出され、どの paths を事前にレンダリングしたいかを指定できます。

// This function gets called at build time
export async function getStaticPaths() {
  // Call an external API endpoint to get posts
  const res = await fetch("https://.../posts");
  const posts = await res.json();

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }));

  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false };
}

また、pages/posts/[id].jsで、このidを使って、post に関するデータを fetch できるように、getStaticPropsを export する必要があります。それによりページを事前にレンダリングできます。

export default function Post({ post }) {
  // Render post...
}

export async function getStaticPaths() {
  // ...
}

// This also gets called at build time
export async function getStaticProps({ params }) {
  // params contains the post `id`.
  // If the route is like /posts/1, then params.id is 1
  const res = await fetch(`https://.../posts/${params.id}`);
  const post = await res.json();

  // Pass post data to the page via props
  return { props: { post } };
}

getStaticPathsの動作について詳しく学びたい場合は、データフェッチングのドキュメンテーションをご覧ください。

私はいつ Static Generation を使うべきですか?

私たちは、ページが一度構築されて CDN によって配信されるため、server render でページを毎回 request するよりもはるかに速くなるので、可能な限り静的生成(データの有無を問わず)を使用することをお勧めします。

あなたは多種多様なページにおいて、Static Generation を使用することができます。これには以下のものが含まれます:

  • マーケティングページ
  • ブログ投稿とポートフォリオ
  • E コマース商品リスト
  • ヘルプとドキュメンテーション

自分自身に問いかけるべきです:「私はこのページをユーザーの Request の前にプリレンダーできるか?」その答えがはいなら、あなたは Static Generation を選択すべきです。

一方で、ユーザーの request に先だってページを事前にレンダリングできない場合、Static Generation はあまり良い考えではありません。おそらくあなたのページは頻繁に更新されるデータを表示しており、ページの内容は request ごとに変わるでしょう。

このような場合、次のいずれかを行うことができます:

  • Static Generation を Client-side data fetchingとともに使用してみてください。ページの一部を事前レンダリングしないで、Client 側の JavaScript を用いてそれらを補完することができます。この手法について詳しくは、Data Fetching documentationをご覧ください。
  • Server-Side レンダリングを使用する: Next.js は、各 request でページを事前にレンダリングします。ページは CDN にキャッシュできないため、速度は遅くなりますが、事前にレンダリングされたページは常に最新のものになります。このアプローチについては以下で話し合います。

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use