TwitterFacebookHatena

Next.js対応の海外のヘッドレスCMS比較5選

ヘッドレス CMS とは

ヘッドレス CMS(Content Management System)とは、従来の CMS とは異なり、フロントエンド(表示部分)とバックエンド(データ管理部分)が切り離された設計の CMS です。これにより、コンテンツの管理と表示が独立して行われるため、柔軟な開発が可能になります。

従来の CMS では、テンプレートエンジンやプラグインを使ってデザインや機能を追加・変更していましたが、ヘッドレス CMS では API を通じてデータを取得・送信することで、フロントエンドとバックエンドを自由に組み合わせることができます。これにより、ウェブサイト、モバイルアプリ、IoT デバイスなど、様々なプラットフォームへの対応が容易になります。

また、ヘッドレス CMS は、開発者が選んだフロントエンド技術(React、Angular、Vue.js など)を使用して、自由度の高いデザインや機能を実現できます。これにより、ウェブサイトのパフォーマンスやユーザーエクスペリエンスの向上が期待できます。

ヘッドレス CMS の主な利点は、フロントエンドとバックエンドの独立性、柔軟な開発、プラットフォーム間の互換性、そして高い自由度です。これらの特徴により、現代のウェブ開発においてヘッドレス CMS は非常に重要な役割を果たしています。

ヘッドレス CMS 比較表

ヘッドレスCMS 特徴 価格
Contentful 使いやすいインターフェース、強力なAPI、幅広い機能を備えたオールインワンソリューション。 月額99ドルから
Strapi 柔軟で拡張性の高いオープンソースプラットフォーム。 無料から
ButterCMS 使いやすく、セットアップが簡単な、中小企業向けのCMS。 月額19ドルから
Ghost 高速でスケーラブルな、パーソナライズされた体験を提供するCMS。 月額29ドルから
Directus データベースに直接アクセスできる使いやすい、オープンソースのCMS。 無料から
KeystoneJS カスタマイズ性の高い、モジュール式のCMS。 月額29ドルから
Sanity 使いやすく、スケーラブルな、API駆動型のCMS。 月額79ドルから
Prismic 使いやすく、柔軟な、コンテンツ管理と配信のためのエンタープライズソリューション。 要お問い合わせ
Storyblok 使いやすく、スケーラブルな、カスタマイズ可能なCMS。 月額49ドルから

ヘッドレス CMS を選択する際には、次の要素を考慮することが重要です。

  • 必要な機能
  • 予算
  • 開発者のスキルレベル
  • スケーラビリティ
  • サポート

ヘッドレス CMS は、コンテンツの管理と配信に柔軟性と拡張性を提供したい企業に最適です。また、ヘッドレス CMS は、ユーザーエクスペリエンスを向上させるために、Web サイトやアプリケーションのデザインやレイアウトを自由に制御したい企業にも適しています。

それでは、ヘッドレス CMS の中でも、特に Next.js と相性の良い海外のサービスを 5 つ選び、それぞれを Next.js と TypeScript で使う方法を解説します。

1. Contentful

Contentful は、API ベースのヘッドレス CMS で、Next.js と簡単に統合できます。以下のコードは Contentful からデータを取得して表示する Next.js コンポーネントの例です。

まず、contentful パッケージをインストールします。

npm install contentful

次に、ContentfulClient.ts ファイルを作成し、以下のように記述します。

import { createClient, Entry } from 'contentful'

const space = process.env.CONTENTFUL_SPACE_ID
const accessToken = process.env.CONTENTFUL_ACCESS_TOKEN

const client = createClient({
  space: space,
  accessToken: accessToken,
})

export async function fetchEntries<T>(contentTypeId: string): Promise<Entry<T>[]> {
  const entries = await client.getEntries<T>({ content_type: contentTypeId })
  return entries.items
}

export default client

最後に、pages/index.tsx でデータを取得し、表示します。

import { GetStaticProps } from 'next'
import { fetchEntries } from '../lib/ContentfulClient'

type Post = {
  title: string
  content: string
}

type Props = {
  posts: Post[]
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await fetchEntries<Post>('post')

  return {
    props: {
      posts,
    },
  }
}

const IndexPage = ({ posts }: Props) => {
  return (
    <div>
      {posts.map((post) => (
        <div key={post.title}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  )
}

export default IndexPage

2. Strapi

Strapi は、オープンソースで自己ホスト可能なヘッドレス CMS です。以下のコードは、Strapi からデータを取得して表示する Next.js コンポーネントの例です。

まず、axios パッケージをインストールします。

npm install axios

次に、StrapiClient.ts ファイルを作成し、以下のように記述します。

import axios from 'axios'

const api = axios.create({
  baseURL: process.env.STRAPI_API_URL,
})

export async function fetchPosts<T>(): Promise<T[]> {
  const { data } = await api.get<T[]>('/posts')
  return data
}

export default api

最後に、pages/index.tsx でデータを取得し、表示します。

```tsx
import { GetStaticProps } from 'next'
import { fetchPosts } from '../lib/StrapiClient'

type Post = {
  id: number
  title: string
  content: string
}

type Props = {
  posts: Post[]
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await fetchPosts<Post>()

  return {
    props: {
      posts
    }
  }
}

const IndexPage = ({ posts }: Props) => {
  return (
    <div>
      {posts.map((post) => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  )
}

export default IndexPage

3. Sanity

Sanity は、リアルタイム編集機能を持つヘッドレス CMS です。以下のコードは、Sanity からデータを取得して表示する Next.js コンポーネントの例です。

まず、@sanity/client パッケージをインストールします。

npm install @sanity/client

次に、SanityClient.ts ファイルを作成し、以下のように記述します。

import sanityClient from '@sanity/client'

const client = sanityClient({
  projectId: process.env.SANITY_PROJECT_ID,
  dataset: process.env.SANITY_DATASET,
  useCdn: true,
})

export async function fetchPosts<T>(query: string): Promise<T[]> {
  const posts = await client.fetch<T[]>(query)
  return posts
}

export default client

最後に、pages/index.tsx でデータを取得し、表示します。

import { GetStaticProps } from 'next'
import { fetchPosts } from '../lib/SanityClient'

type Post = {
  _id: string
  title: string
  content: string
}

type Props = {
  posts: Post[]
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await fetchPosts<Post>(`*[_type == "post"]{ _id, title, content }`)

  return {
    props: {
      posts,
    },
  }
}

const IndexPage = ({ posts }: Props) => {
  return (
    <div>
      {posts.map((post) => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  )
}

export default IndexPage

4. Prismic

Prismic は、スライス機能を提供するヘッドレス CMS です。以下のコードは、Prismic からデータを取得して表示する Next.js コンポーネントの例です。

まず、prismic-javascript パッケージをインストールします。

npm install prismic-javascript

次に、PrismicClient.ts ファイルを作成し、以下のように記述します。

import Prismic from 'prismic-javascript'

const apiEndpoint = process.env.PRISMIC_API_ENDPOINT
const accessToken = process.env.PRISMIC_ACCESS_TOKEN

const client = Prismic.client(apiEndpoint, { accessToken })

export async function fetchPosts<T>(documentType: string): Promise<T[]> {
  const response = await client.query(Prismic.Predicates.at('document.type', documentType))
  return response.results as T[]
}

export default client

最後に、pages/index.tsx でデータを取得し、表示します。

import { GetStaticProps } from 'next'
import { fetchPosts } from '../lib/PrismicClient'

type Post = {
  id: string
  data: {
    title: string
    content: string
  }
}

type Props = {
  posts: Post[]
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await fetchPosts<Post>('post')

  return {
    props: {
      posts,
    },
  }
}

const IndexPage = ({ posts }: Props) => {
  return (
    <div>
      {posts.map((post) => (
        <div key={post.id}>
          <h2>{post.data.title}</h2>
          <p>{post.data.content}</p>
        </div>
      ))}
    </div>
  )
}

export default IndexPage

5. DatoCMS

DatoCMS は、イタリア発のヘッドレス CMS で、リアルタイムアップデートが可能です。以下のコードは、DatoCMS からデータを取得して表示する Next.js コンポーネントの例です。

まず、graphql-request パッケージをインストールします。

npm install graphql-request

次に、DatoCMSClient.ts ファイルを作成し、以下のように記述します。

import { GraphQLClient } from 'graphql-request'

const client = new GraphQLClient(process.env.DATO_CMS_API_URL, {
  headers: {
    authorization: `Bearer ${process.env.DATO_CMS_API_TOKEN}`,
  },
})

export async function fetchPosts<T>(query: string): Promise<T[]> {
  const data = await client.request<{ posts: T[] }>(query)
  return data.posts
}

export default client

最後に、pages/index.tsx でデータを取得し、表示します。

import { GetStaticProps } from 'next'
import { fetchPosts } from '../lib/DatoCMSClient'

type Post = {
  id: string
  title: string
  content: string
}

type Props = {
  posts: Post[]
}

const query = `
  query {
    posts: allPosts {
      id
      title
      content
    }
  }
`

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await fetchPosts<Post>(query)

  return {
    props: {
      posts,
    },
  }
}

const IndexPage = ({ posts }: Props) => {
  return (
    <div>
      {posts.map((post) => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </div>
      ))}
    </div>
  )
}

export default IndexPage

これで、海外のおすすめのヘッドレス CMS サービス 5 つと、それぞれを Next.js と TypeScript で使う方法を解説しました。ぜひ、参考にしてみてください。

Next.js対応の海外のヘッドレスCMS比較5選