Docs / tech

Next.js と Sanity を使用したブログ構築

2025-11-16 2025-11-29 |

この記事では新しいプロジェクトを作成して、Next.js で Sanity で管理しているコンテンツを取得する手順を紹介します。

Next.js から Sanity のコンテンツを取得する

このコースでは、Next.js を使用してSanity からコンテンツを取得する方法を学びます。

前提条件

すでに Sanity に関するサンプルを起動できている基本的な部分を理解していることを前提とします。このサイトでは以下のガイドで簡単に紹介をしています。

Sanity 概要
doc

Sanity 概要

Sanity は、高い柔軟性を持つヘッドレスCMSで、構造化コンテンツの管理に優れています。カスタムスキーマを TypeScript で定義でき、リアルタイムな共同編集や豊富なAPI連携が可能です。このコースでは、Sanity のチュートリアルを参考にしながら、どのような製品か紹介をしていきます。

また、Wordpress からコンテンツの移行をしたプロジェクトをベースに紹介を進めて行きます。

WordPress からの移行について
doc

WordPress からの移行について

このシリーズでは Wordpress のサイトのコンテンツを Sanity に移行する手順を紹介していきます。まず最初のステップとして、今回は作業をする環境を紹介していきます。

新しいリポジトリの作成

今回はブログサイトのために、Wordpress のプロジェクトからのコードをそのまま引き継いで進めます。同じリポジトリで Sanity Studio のコードを、また合わせて Next.js のコードを管理するために、以下のような構成とします。

- apps
  - studio Wordpress から移行したプロジェクト
  - nextjs Next.js の新しいプロジェクト

apps/studio のフォルダには、以下のリポジトリからのコードを利用しています。

すでに studio のフォルダには必要なファイルが準備できている状態です。

Next.js のプロジェクトの作成

続いて、Next.js のプロジェクトを作成します。コマンドラインで以下のコマンドを実行します。

npx create-next-app

プロジェクトの名前、そして推奨の設定を利用するかの確認が表示されます。今回は以下のように選択しました。

しばらくするとフォルダが作成されます。

プロジェクトのディレクトリに入って、 npm run dev を実行して Next.js のプロジェクトが起動することを確認します。

これで準備ができました。

コンテンツを表示する

パッケージの追加

Next.js から Sanity に対してコンテンツを取得するためのパッケージを追加いていきます。以下のコマンドを nextjs のフォルダの中で実行します。

npm install --legacy-peer-deps next-sanity @sanity/image-url

Sanity Client ファイルの追加

コンテンツにアクセスするための Sanity Client のファイルを追加します。サンプルのコードは以下のようになります。YOUR-PROJECT-ID に関しては、Sanity のプロジェクトの ID を利用してください。

apps/nextjs/sanity/client.ts
import { createClient } from "next-sanity";

export const client = createClient({
  projectId: "YOUR-PROJECT-ID",
  dataset: "production",
  apiVersion: "2024-01-01",
  useCdn: false,
});

ページの更新

実際の Next.js のトップページにあるファイルを以下のように書き換えます。なお、Sanity のサイトで公開しているコードとはことなり、公開日のパラメーターを date に変更してあります。

apps/nextjs/app/page.tsx
import Link from "next/link";
import { type SanityDocument } from "next-sanity";

import { client } from "@/sanity/client";

const POSTS_QUERY = `*[
  _type == "post"
  && defined(slug.current)
]|order(date desc)[0...12]{_id, title, slug, date}`;

const options = { next: { revalidate: 30 } };

export default async function IndexPage() {
  const posts = await client.fetch<SanityDocument[]>(POSTS_QUERY, {}, options);

  return (
    <main className="container mx-auto min-h-screen max-w-3xl p-8">
      <h1 className="text-4xl font-bold mb-8">Posts</h1>
      <ul className="flex flex-col gap-y-4">
        {posts.map((post) => (
          <li className="hover:underline" key={post._id}>
            <Link href={`/${post.slug.current}`}>
              <h2 className="text-xl font-semibold">{post.title}</h2>
              <p>{new Date(post.date).toLocaleDateString()}</p>
            </Link>
          </li>
        ))}
      </ul>
    </main>
  );
}

反映ができたところで、Next.js のサイトを起動してください。コンテンツの取得ができていることを確認できました。

環境変数

今の段階では、Sanity Client の中にプロジェクト ID などがハードコーディングされている形です。このため、以下のように変更して行きます。

apps/nextjs/sanity/client.ts
import { createClient } from "next-sanity";

export const client = createClient({
  projectId: process.env.SANITY_STUDIO_PROJECT_ID || "your_project_id",
  dataset: process.env.SANITY_STUDIO_DATASET || "production",
  apiVersion: process.env.SANITY_API_VERSION || "2024-01-01",
  useCdn: false,
});

上記のコードとあわせて、.env.sample のファイルを作成しておきました。

apps/nextjs/.env.example
SANITY_STUDIO_PROJECT_ID=your_project_id
SANITY_STUDIO_DATASET=production
SANITY_API_VERSION=2024-01-01

私は Vercel と連携させて環境変数を管理するため、上記のファイルを参考にしつつ、.env.local のファイルを作成して運用しています。

まとめ

Next.js のトップページとなる apps/nextjs/app/page.tsx のファイルでは、GROQ というクエリー言語でコンテンツを取得、その結果を利用してページを作成していることを確認することができました。まずデータの取得ができたので、これをベースにブログの構築を進めて行きます。

ここまでのコードは以下のブランチで公開しています。