iku8blog - 考えない為に考える

Contentfulをtsで使う時にコンテンツの型定義を生成する便利なライブラリ

date: 2023-01-05

Conteful では自分でコンテンツモデルというものが定義でき、自由自在にコンテンツのデータを管理出来ます。 しかし typescript でデータ型を自分で定義しようとすると、どういうデータ構造になっているのかを調べてそれに合う型を作成したり、探したりしないといけなくて不便です。

type セーフで書きたいですよね。

そこで重宝するのが、「contentful-typescript-codegen」です。 https://github.com/intercom/contentful-typescript-codegen

ちなみに自分は Conteful のデータを API で取得して Next.js で SSG してホスティングしています。

型定義生成までに必要なステップは以下の通り

  1. Contetful で Content management tokens を生成(Content delivery/preview tokens じゃないので注意)
  2. 必要ライブラリのインストール
  3. 型定義生成スクリプトの作成

トークン生成

Contetful では 2 種類のトークンが存在しますが、必要なのは Content management tokens の方です。

Contetful のヘッダーメニューより Settings > API keys > Content management tokens > Generate Personal Access Token

ここでトークンに名前をつけて、生成できます。ここのトークンをメモっておきましょう

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

npm install contentful contentful-management contentful-typescript-codegen

型定義生成スクリプトの作成

getContentfulEnvironment.js というファイル名で以下スクリプトを作成しましょう 修正とコメントしている箇所を自身の環境に合わせて設定してください

const contentfulManagement = require("contentful-management");

module.exports = function () {
  const contentfulClient = contentfulManagement.createClient({
    accessToken: "さっき生成したトークン", // 修正
  });

  return contentfulClient
    .getSpace("自分のスペースID") // 修正
    .then((space) => space.getEnvironment("Contentfulの環境")); // 修正 masterとかdevとか。Contentful側で設定してるはずなのでそれを指定
};

これで型定義生成準備は終わりです。

実際に以下のように実行してみましょう

./node_modules/contentful-typescript-codegen/dist/contentful-typescript-codegen.js --output @types/generated/contentful.d.ts

実行成功すると@types/generated/contentful.d.tsというファイルに、自分の定義しているコンテントモデルの TS 型定義が出来ているはずです。 これで type セーフで開発ができます。コンテンツモデルが更新されたら都度型定義を generate すると良いですね。

結果的に以下のような型定義が生成されれば成功です。

その他

自分は next.js を追加っていて、.env.local に諸々の認証情報を定義しています。型定義は開発環境であれば良いので自分は以下のようにスクリプトを書いています

require("dotenv").config({ path: `.env.local` });

const contentfulManagement = require("contentful-management");

module.exports = async function () {
  const contentfulClient = contentfulManagement.createClient({
    accessToken: process.env.CF_MANAGEMENT_ACCESS_TOKEN,
  });
  const space = await contentfulClient.getSpace(process.env.CF_SPACE_ID);
  return await space.getEnvironment(process.env.CF_ENV);
};

npm script に記述しておくと実行が楽です。

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

npm run genCfTypes で generate 出来ます。

date: 2023-01-05