2021.10.25 に更新7 min read

Contentful のレスポンスを TypeScript で取得する方法

サムネイル画像

この記事では Headless CMS として有名な Contentful の TypeScript 用型定義ファイルを自動的に生成する方法と Next.js で Contentful からのレスポンスを受け取る方法についても合わせて紹介します。

Contentful では様々なコンテンツを定義できるため自由度が高く、その反面手動で型定義をするのは大変なのでそれらを自動で生成できると便利です。

準備

ライブラリのインストール

Contentful で自動的に型定義ファイルを生成するには contentful-typescript-codegen というライブラリを使用します。

公式 JavaScript ライブラリの contentfulcontentful-management も使用するため合わせてインストールしてください。

npm install contentful contentful-management contentful-typescript-codegen

もしくは

yarn add contentful contentful-management contentful-typescript-codegen

Contentful のトークンを取得する

インストールが完了したら次は型定義ファイルを生成するための Contentful Management API Token を取得しましょう。

Contentful へログインし、「Settings」から「API keys」を押してトークン一覧画面を開きます。

次に「Content management tokens」のタブを選択し、「Generate Personal token」を押してトークンを作成します。

contentful

トークン名を設定して「Generate」を押すとトークンが表示されるのでメモしてください。
あとから確認することはできず一度忘れてしまうと再度作成する必要があるため注意です。

また、トークンは dotenv を利用して管理すると便利です。

まだインストールしていない場合は以下のコマンドでインストールしておきましょう。

npm install dotenv

もしくは

yarn add dotenv

次に以下のように .env ファイルを作成した上で取得したトークンを CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN へコピペします。

CONTENTFUL_SPACE_ID = ****
CONTENTFUL_ENVIRONMENT = ****
CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN = ****
CONTENTFUL_DELIVERY_TOKEN = ****
CONTENTFUL_PREVIEW_TOKEN = ****

CONTENTFUL_SPACE_ID は「Settings」の「General settings」から、CONTENTFUL_ENVIRONMENT は同じく「Settings」の「Environments」確認することができます。

contentful 2

CONTENTFUL_DELIVERY_TOKEN はコンテンツを取得するためのトークン、CONTENTFUL_PREVIEW_TOKEN はプレビュー機能を利用する場合に使うトークンで、どちらも「Settings」から「API keys」のトークン一覧画面で「Content delivery / preview tokens」のタブから作成します。

「Add API Key」を押すとトークンが作成され、「Content Delivery API - access token」と「Content Preview API - access token」が表示されるためそれぞれ上記の .env ファイルへコピペしてください。

contentful 3

型定義ファイルを生成する

プロジェクトのルートディレクトリに getContentfulEnvironment.js というファイルを以下の内容で作成します。

require('dotenv').config()

const contentfulManagement = require("contentful-management")

module.exports = function() {
  const contentfulClient = contentfulManagement.createClient({
    accessToken: process.env.CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN,
  })

  return contentfulClient
    .getSpace(process.env.CONTENTFUL_SPACE_ID)
    .then(space => space.getEnvironment(process.env.CONTENTFUL_ENVIRONMENT))
}

次に package.jsonscripts へ実行時に型定義ファイルを生成する以下のスクリプトを追加します。

{
  // ...
  "scripts": {
    "contentful-typescript-codegen": "contentful-typescript-codegen --output @types/generated/contentful.d.ts"
  }
}

最後に npm run contentful-typescript-codegen もしくは yarn contentful-typescript-codegen を実行して型定義ファイルを生成します。

これで contentful.d.ts という名前の型定義ファイルが @types/generated に作成されているはずです。

Next.js でレスポンスを受け取る

準備

型定義ファイルを作成できたら、次は Next.js で Contentful からのレスポンスを取得する方法について見ていきましょう。

まずは utils フォルダを作成し、 client.ts というファイルを以下の内容で作成します。

import { createClient } from 'contentful'

const config = {
  space: process.env.CONTENTFUL_SPACE_ID,
  accessToken: process.env.CONTENTFUL_DELIVERY_TOKEN
}

export const client = createClient(config)

client.ts はコンテンツを取得するためだけに使用するので取得用トークンである CONTENTFUL_DELIVERY_TOKEN を使用しています。

コンテンツ一覧を取得する

上記で用意した client.ts を使用して特定のコンテンツ一覧を取得してみます。

また、ここでは一般的にブログを作る場合によく用いられる post という Contentful のコンテンツタイプを作成していることを想定しています。

import { GetStaticProps } from 'next'
import { client } from '../utils/client'
import { Entry, EntryCollection } from 'contentful'
import { IPostFields } from '../@types/generated/contentful'

interface Props {
  posts: EntryCollection<IPostFields>
}

export default function Home({ posts }){
  return (
    <>
      {posts.map((post: Entry<IPostFields>) =>
        <div>
          <h1>{post.fields.title}</h1>
          <p>{post.fields.body}</p>
        </div>
      )}
    </>
  )
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await client.getEntries<IPostFields>({
    content_type: "post",
    order: "-sys.createdAt",
  })

  return {
    props: {
      posts: posts,
    }
  }
}

コンテンツ一覧取得に使われる getEntries() は引数に content_type を指定することで特定のコンテンツタイプのみを取得することが可能です。
また、order でソートすることもでき、今回は createdAt (作成日)の降順でソートをおこなっています。

Entry<IPostFields> にはコンテンツの内容を保持している fields の他にシステム的な情報を保持している sys というプロパティで作成日や更新日などの項目も取得することが可能となっています。

まとめ

今回は Contentful で型定義ファイルを自動的に生成する方法を紹介しました。

ライブラリを利用することで手動で型定義をする必要なく、快適に TypeScript の恩恵を受けることができます。
今回は簡単な例で紹介しましたが、複雑なモデルになっている場合でもエディターの予測変換に従っていけば目的の項目を見つけられるのはとても便利ですね。


SHARE