React+Contentful+Netlify+Google Domainで個人ブログを作る
久しぶりの投稿です。TypeScript+Reactの素振り用に前から気になっていたHeadless CMSのContentfulを使ってブログをNetlifyにホスティングしてみました。今ならCloudflare Pagesとかになるんでしょうか。
Netlifyから提供されるドメインではなく独自ドメインを設定する方法も合わせて追記しています。今回はGoogle Domainを使いました。お名前.comは使いたく無い
NextでもVueでも同じようにできると思うので置き換えてください。
参考になるか分かりませんが、記事の例で使用している自分の実装はこちらです。あくまで参考程度ですが、特にeslintとかprettierとかの設定は参考にしないでください。
話すこと
- Contentfulでの設定方法
- Contentfulのmodelの型定義
- SDKの使い方
- Netlifyでのデプロイ手順
- GitHub Actionsの設定
- Google Domainでのドメイン取得方法
話さないこと
- TypeScript自体
- Reactの環境構築
- 全体の実装
お品書き
Contentful設定
Contentful自体の日本語での説明はこちら(次世代Headless CMS「contentful」事始め)をみてください。
何はともあれログインしてspaceを作成します。基本Freeで大丈夫です。
spaceを作成したらmodelを作成します。これが実際のデータ構造になります。
Contentfulは多くのfieldを用意しています。ReferenceはRDBの外部キーのような使い方ができます。今回はカテゴリとタグを紐づけるのに使用しました。 今回は記事のカテゴリとタグ、記事自体のmodelを用意します。
まずカテゴリのmodelです。 次にtagのmodelです。 最後に記事のmodelにカテゴリとタグを紐付けます。 記事本文は今回はMarkdownを指定してください。描画時にMarkdownをhtmlに変換します。 カテゴリとタグの紐付けはReferencesを選択するとOne ReferencesとMany Referencesが選択できます。カテゴリは記事に対して一対一、タグは一対多で一つの記事に複数紐づくようにしました。
最終的に以下のようになります。
最後に記事を取得するためのAPI keyを生成します。ヘッダーのSettings→API KeysからAdd API Keyを選択して生成します。 後でContentfulのSDKを使いますが、その際にSpace IDとContent Delivery API - access tokenが必要になります。
これでContentfulは終わりです。
SDKの使用方法
Reactの一通りの環境構築が終わっている前提で、SDKのinstallと使い方の説明をします。
SDKをinstallします。
npm install --save contentful
記事一覧を取得する実装です。
createClient
にSpace IDとaccess tokenを渡してContentfulClientApi
のインスタンスを生成します。
その後getEntries
で全体を取得できます。
ここでは実装していませんが、検索条件を付与することも可能です。詳しくはドキュメントを読んでください。
型定義については後で説明します。
import {ContentfulClientApi, createClient, Entry} from 'contentful'; import {Article as ContentfulArticle} from '../domain/contentful/article'; const getClient = (): ContentfulClientApi => { return createClient({ space: process.env.REACT_APP_CONTENTFUL_SPACE_ID as string, accessToken: process.env.REACT_APP_CONTENTFUL_DELIVERY_API as string, resolveLinks: true, }); }; const getContent = async ( contentType: string ): Promise<Entry<ContentfulArticle>[]> => { const client = getClient(); const response = await client.getEntries<ContentfulArticle>({ content_type: contentType, }); return response.items; };
modelの型定義
Contentfulの記事はここをanyにしてごまかしている実装がよく検索でヒットします。JavaScriptではなくTypeScriptを使っているのでanyに逃げずにちゃんと型定義をします。
先ほどのgetEntries
の戻り値の型はPromise<EntryCollection<T>>>
です。
その戻り値のitem
プロパティの型はEntry<T>
でこれがmodelの実体になります。このT
に自分で設定したmodelの型定義をあててあげれば型をつけて取得できます。
Entry
型は以下のようなデータ構造になっています。
export interface Entry<T> { sys: Sys; fields: T; toPlainObject(): object; update(): Promise<Entry<T>>; }
sysはuniqueなidや作成日時、更新日時などのメタデータが定義されています。 fieldsがモデルの定義になります。
よって今回の型定義は以下のようになります。
import {Sys} from 'contentful'; export type Category = { fields: { name: string; }; sys: Sys; }; export type Tag = { fields: { name: string; slug: string; }; sys: Sys; }; export type Article = { category: Category; content: string; tag: Tag[]; title: string; };
Article
型はEntry
型のfields
プロパティの型を定義してsys
プロパティの型定義は不要です。
Netlify設定&デプロイ
NetlifyはGitHub連携でpush時に自動でデプロイするのとSDKでのGitHub Actionsでのデプロイがあります。
starter planではビルドが月300分までなので、頻繁にデプロイしたいならGitHub Actionsでビルドしてデプロイするとお得です。
以下のような.github/workflows/deploy.yaml
を用意してください。
masterブランチへのpush時に以下のworkflowが実行されます。
name: Deploy on: push: branches: - master jobs: build: runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v2 - name: Cache node_modules uses: actions/cache@v1 with: path: node_modules key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.OS }}-build- ${{ runner.OS }} - name: Setup Node uses: actions/setup-node@v1 with: node-version: 14.x - name: npm install and build run: | yarn install yarn build - name: Deploy to netlify run: npx netlify-cli deploy --dir=./build env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
まずAUTH_TOKENとSITE_IDですが、アプリケーション設定画面に遷移するとNew access token
とあるので押下するとAUTH_TOKENが取得できます。
SITE_IDはhttps://app.netlify.com/sites/[自分のサイト名]/settings/general
に遷移するとAPI ID
とあるのでこれがSITE_IDです。
これらをGitHub Actionsで使うために環境変数として登録します。 GitHubのリポジトリのSettingタブからSecretsを選択すると環境変数が登録できます。
Google Domainsでカスタムドメイン設定
Google DomainsはGoogleが提供するドメイン管理サービスです。 日本だとお名前.comがありますが、個人的には使いたくないので今回はGoogle Domainsを使います。
これ読んででいいですか?ダメ?
大切なのは、Google DomainsのカスタムリソースレコードにnetlifyのIPアドレスとwwwつきドメインを追加してください。
NetlifyのDomain ManagementからAdd Custom Domainで以下のような設定されていればおkです。
最後にbaseURLを設定したカスタムドメインにすれば終わりです!
まとめ
覚えてしまえばそんなに難しく無いかなと思います
今度はNext.jsでcloudflare pagesにデプロイしてみたいです。