diffeasyアドベントカレンダー16日目の記事です。
最近開発しているアプリケーションのLPサイトを作るのに、お知らせ機能を作りたいという話がでていました。
ただ、お知らせ機能を追加するにあたって、
- LPサイトは静的で書き出したい(SEO対策とかで)
- アプリケーションAPI側にトピックスやブログコンテンツを持ちたくない
- だからといって、Wordpressはサーバー運用だったりバージョンアップデート等で今後の辛みもあるから個人的に使いたくない
ということで、静的サイトジェネレーター&Headless CMSを使ってみました!
やっていくこと
- フロントをGridsomeで作る
- Contentfulでお知らせ内容を書く
- Github Actionsを使って更新を検知し、Firebase Hostingに自動デプロイする
です!
ホスティング先が、なぜよくHeadless CMSを使うときによく勧められてるNetlifyではなくFirebase Hositngかというと、単に自分が使い慣れているというのと、あんまりFirebase Hostingで使ってるって記事を見かけなかったので使ってみました。
また、書いている途中で膨大な量になりそうだなと思ったので【前編】と【後編】に分けることにしました!
- 前編ではContentfulとGridsomeを使ってローカルで動きを確認するところまで
- 後編ではFirebase Hostingにデプロイ&Github Actionsでのデプロイの設定
を書いていこうと思います💪
Gridsomeとは
GridsomeはVue.js製の静的サイトジェネレーターで、
- いろんなCMSと繋ぐためのプラグインがある
- GraphQLを使ってデータ成型できる
- Vue製なので、Vueに慣れてたら結構簡単に扱える
ことができます。
ちなみに、React製の静的サイトジェネレーターにGatsby.jsというのがあるのですが、GridsomeはGatsby.jsを参考にして作られたそうです。
また、弊社ではフロントエンドにNuxt.jsを採用しているので、Generateしたら静的吐き出しできるし、これでいいじゃんって思うかもしれないですが、新しいものを使いたかったっていうのと、データをGraph QLで整形できるのめちゃんこ便利じゃんって思ったので、今回使ってみました。
Contentful
ContentfulはHeadless CMSの話題が出てきたときから結構有名どころ(だと思ってる)のCMSです。
英語版しかないですが、一回設定したら基本はコンテンツを追加するだけなのでそんなに困らないかなと思います(英語の勉強にもなるし)。
英語慣れしていない人でも更新できるよう、日本製Headless CMSのmicroCMSとも迷ったのですが、WebhookがmicroCMSだとSlack or Netlifyに対して、ContentfulだとTravisCIやCircleCIなどにも飛ばせるほか、カスタムWebhookを作成できるので、設定次第で色んなことができそうなContentfulを選びました。
Contentfulのセットアップ
Content modelを作成する
Contentfulでは、お知らせページやブログの内容を構成する情報のことをContent model
と言います。
まずはContentfulにログインし、Content modelタブに移動します。
次に、「Add content type」を選択し、Content modelを作っていきます。
ここで注意すべき点は、下の画像のように、名前は英語で入力してください。
Gridsome側のプラグインで読み込む際、Nameが日本語だと読み込めません。
次に、サイドバーにある「Add field」を選択し、お知らせページを構成する要素を追加していきます。
内容(Articles)については、Rich Text
or Text
が選択できると思いますが、僕はText
のLong text
を選択することをおすすめします。
理由は
- Long textだとMarkdownで書けるから
- Rich Textだとコードブロックが置けない?(自分が分かってないだけかも…)
- Rich Textは公式が@contentful/rich-text-html-rendererを提供しているけど、コードをまとめれなかったり(一行ずつに分割される)、Vueだと拡張が結構大変に感じた
からです。
Rich Textも全然悪くはないと思うし、Wordpressで慣れてる人とかはこっちのほうがいいって人もいるかもなので、今後のアップデートには期待しています🎉
設定し終わったら、右上のsaveを押して保存してください。
投稿する
次に、お知らせの投稿を1つしておきましょう。
Content modelタブの右横にあるContentタブから投稿を追加できます。
内容を書き終わったら、サイドバーにあるPublishボタンを押して、公開状態にしましょう!
APIキーを作成する
最後に、Gridsome側でコンテンツを取得する際に必要となるAPIキー
を作成します。
SettingsタブからAPI keysを選択し、次の画面でAdd API keyを選択します。
ここのNameは好きな名前をつけてください。
必要になるのは、Space ID
とContentful Delivery API - access token
の2つです。
次にやるGridsomeの設定で使うので、画面をそのままにするか、どこかにコピーしておいてください。
Gridsomeのセットアップ
必要なものをインストールする
$ npm i -g @gridsome/cli
$ gridsome create lp-site && cd $_
$ npm i @gridsome/source-contentful markdown-it
Contentful pluginの設定
プロジェクトルートにあるgridsome.config.js
を編集します。
公式に載っているものそのままですが、YOUR_SPACE
の部分にさっき出したSpace ID
を、YOUR_ACCESS_TOKEN
の部分にaccess_token
を置きます。
しかし、そのまま置くと環境ごとに分けられなかったり、Githubのpublicリポジトリなんかにpushしたときには全世界の人に見られたりするのでenv
ファイルに書いて読み込ませたりしたいと思います。
幸いなことに、Gridsomeではdotenvを使って対応しています。
また、Gridsomeでは.env.production
または.env.development
をルートディレクトリに配置することで、環境別の変数を用意できます。最高ですね!
module.exports = {
plugins: [
{
use: '@gridsome/source-contentful',
options: {
space: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
host: 'cdn.contentful.com',
environment: 'master',
typeName: 'Contentful'
}
}
]
}
CONTENTFUL_SPACE_ID=YOUR_SPACE
CONTENTFUL_ACCESS_TOKEN=YOUR_ACCESS_TOKEN
GraphQL explorerでデータ構造をチェックする
Gridsomeをdevelopで起動すると、GraphQL explorerを開けるようになります。
これを使えば、Gridsomeを起動した時点でContentfulから情報を取得してきて、その構造を確認することができます。
表示方法は、npm run develop
コマンドを打つと下のような表示が出てくるので、ブラウザでhttp://localhost:8080/___explore
を開くだけです!
$ npm run develop
Site running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.86:8080/
Explore GraphQL data at: http://localhost:8080/___explore
するとこんな画面が開かれると思います
これは、GraphQLのクエリを試しに打ってみて実行して確認ができる画面になります。
使えるクエリを見るには、右側のDOCSタブをクリックしてみるといいです。
実行できるクエリたちが並んでいるので、それを左側の画面に入力して再生ボタンをクリックすれば動かすことができます!
このエディタ上だと入力補完が効くので、すごく便利です✨
試しに、一覧情報を取得するクエリを書いてみます。
コードは上画像の構造を元に書いていくので、分からなかったら照らし合わせてみてください!
# queryには自由な名前を定義できます
#(主に再生ボタンを押したときに、どのクエリを実行するかに使用したりします)
query getAllTopics {
allContentfulTopics {
edges {
node {
id
title
article
createdAt
updatedAt
}
}
}
}
書けたら、真ん中の再生ボタンを押して、実行してみてください。
Contentfulの設定のときに書いた内容が取得できていると思います!(こうなれば成功です)
まずは一覧ページを作ってみる
Contentfulから情報を取得できていることが確認できたので、ページを作っていきましょう。
ページの作り方は、Nuxt.js
を使っている人は親近感が湧く作り方になると思いますが、pages
ディレクトリ内に作っていきます。
まずは、お知らせページの一覧画面を作ってみましょう!
$ touch src/pages/Topics.vue
<template>
<Layout>
<h1>Topics</h1>
<ul>
<li v-for="topics in $page.allTopics.edges" :key="topics.node.id">
<g-link :to="`/topics/${topics.node.id}`">{{ topics.node.title }}</g-link>
</li>
</ul>
</Layout>
</template>
<page-query>
query getAllTopics {
allTopics: allContentfulTopics {
edges {
node {
id
title
}
}
}
}
</page-query>
ちょっと独特な書き方をしていますが、分解すると
-
src/main.js
に書いてありますが、Layout
コンポーネントがグローバルコンポーネントとして登録されています。これは全体的なレイアウトを統一するために存在しています - GraphQLクエリは
<page-query>
タグで囲って記述します。この中に先程書いたクエリを転記します -
allContentfulTopics
クエリの前にallTopics
と書いてありますが、これはコンポーネント内でクエリの実行結果を使うときの名前です。つけない場合はallContentfulTopics
の名前で取り扱います -
page-query
での実行結果をコンポーネント内で使うときはthis.$page
を使います。ここに実行結果が入ってきます
という感じになります。
詳細ページを作ってみる
次に詳細ページを作っていきましょう。
詳細ページを作るときはカスタムルートを作る必要があるので、pagesディレクトリにファイルを置くだけでは作れません。
カスタムルートの作り方は
-
gridsome.config.js
にカスタムルートを作成する -
src/templates
に、設定したカスタムルートに訪問した時表示するコンポーネントを作成する
という流れになります。
まずはgridsome.config.js
に下を追記します。
module.exports = {
plugins: [
...
],
// ここから追記
templates: {
// ここは "Contentful + Content model名" になる
ContentfulTopics: [
{
path: '/topics/:id',
component: './src/templates/TheTopics.vue',
},
],
},
}
次に、src/templates
にTheTopics.vue
を作り、追記します。
<template>
<Layout>
<h1>{{ $page.topics.title }}</h1>
<main>
<div v-html="article"></div>
</main>
</Layout>
</template>
<page-query>
query topics($id: ID!) {
topics: contentfulTopics(id: $id) {
title
article
}
}
</page-query>
<script>
import markdownIt from 'markdown-it'
export default {
computed: {
article() {
const md = new markdownIt()
return md.render(this.$page.topics.article)
}
}
}
</script>
ここでは以下の動きをしています
- queryの
$id
でカスタムルートに指定した/:id
の値を取得し、ID型で定義します。それを使ってcontentfulTopics(id: $id)
でコンテンツの指定を行います。 - articleはMarkdownを使っているので、Markdown parser(今回は
markdown-it
を使っています)を使ってHTMLに変換し、v-html
に流しています
ここでnpm run develop
をして/topics
からリンクを踏めば、詳細画面が開けることが確認できると思います!やったね!
このようにして、フロント側を作っていきます。
もっと詳しいことを学習されたい方は、ぜひ公式ドキュメントを!
少し前と比べたらドキュメント量も増えてて、デザインも新しくなって見やすくなったので、一通りわかればサクサク進められると思います✨
前編はここまでです。最後まで見てくださり、ありがとうございます!
前編の終わりに
いかがでしたか?
ちょっと癖がありますが、慣れたら結構簡単に画面を作っていけるので、個人的にはGridsomeおすすめです!
後編はこちらです!よかったら見てください😆
【後編】GridsomeとContentfulを使って、簡単に更新できる静的LPページを作ってみる