2020/12/31

Craft CMS と Gridsome で SSG してみる #craftcms

ぐっちーの本を読み終わって NuxtJS で SSG やるかー、とおもってたのだが。
11ty を途中まで触っててなんか GraphQL 周りうまく出来なかった(js力不足)ながれで Gridsome で静的生成するところを遊んでた。

以前全然動かせなかったのよりは少し進んだ気がする。

ちょうど一年前か。
(成長の程度がミジンコ)


チュートリアルを探してやってみればよかったな、と思いつつドキュメント通りにインストール。

Default starter - Gridsome
https://gridsome.org/starters/...

とりあえず  gridsome develop で見れるところまでを確認。

necco の阿部さんが Shifter と Gridsome でやられてたよなー、というのを拝見しつつ。

Shifter Headless と Gridsome とShopifyでヘッドレスメディアコマースサイトを1日でつくる
https://necco.co/necco-note/20...

GraphQL用のをインストール。

npm install @gridsome/source-graphql

gridsome.config.js に Craft のデータ使う用の設定を追加する。

module.exports = {
  siteName: 'Gridsome',
  plugins: [
    {
      use: '@gridsome/source-graphql',
      options: {
        url: process.env.CRAFT_API_URL,
            fieldName: 'craft',
            typeName: 'craft',
            headers: {
          Authorization: `Bearer ${process.env.CRAFT_API_TOKEN}`,
        }
      }
    }
  ]
}

.env にエンドポイントのURLとかを設定しておく。

CRAFT_API_URL="https://example.com/api"
CRAFT_API_TOKEN="hogehoge"

Collection の概念がよくわかっていないところもあったのだけど。。。

Collections - Gridsome
https://gridsome.org/docs/coll...

GraphQL (Craft CMS )側の命名とか関係するものなのかなぁと思ったけどそういう感じではなさそうな?
そこがよくわかってなくて詳細ページのテンプレートをどう作って、どう設定するのがいいものか??とあれこれ。

ひとまず普通に src/templates/post.vue で作成する。
内容としてはこんな感じで。

<template>
  <Layout>
  <div>
    <h1>{{ $context.title }}</h1>
    <h2>ID: {{ $context.id }}</h2>
    <h2>Slug: {{ $context.slug }}</h2>
    <h2>URI: {{ $context.uri }}</h2>
  </div>
  </Layout>
</template>

詳細ページの方で page-query でクエリ投げて詳細ページつくるのかなぁ、とあれこれやっていたのだけど。
 gridsome.server.js の方でページ生成処理とかを書くっぽい雰囲気だったので、詳細ページの中身は gridsome.server.js で渡した context を使う感じでひとまず。

これが正しいのかどうか。。。。
よくわかってなかったのだけど(ドキュメントちゃんと読もう)gridsome.server.js  は Gatsby でいうところの gatsby-node.js みたいなものっぽい、、、と思っておくことにする。

gridsome.server.js はこんな感じで詳細ページ生成のところを追加する。

module.exports = function (api) {
  api.loadSource(({ addCollection }) => {
  })

  api.createPages(async ({ graphql, createPage }) => {

    const { data } = await graphql(`{
      craft{
        entries {
          id
          title
          uri
          slug
        }
      }
    }`)

    await Promise.all(data.craft.entries.map(async ({ id, slug,title, uri }) => {
      createPage({
        path: `/article/${id}`,
        component: './src/templates/post.vue',
        context: {
          id: id,
          slug: slug,
          uri: uri,
          title: title
        }
      })
    }))
  }) 
}

他のページの出力もここでやるっぽい。

ひとまずこれで詳細ページの方が表示出来た。
出来たといってもタイトルとかテキストを出してるだけだけど。

一覧くらいは作っておこうと思ってトップページの方に追加しておく。

src/pages/Index.vue

<template>
  <Layout>

〜〜略〜〜

    <h1>新着記事</h1>

    <ul>
      <li v-for="entry in $page.craft.entries" :key="entry.id">
        <a v-bind:href="'/article/' + entry.id">{{ entry.title }}</a>
      </li>
    </ul>

〜〜略〜〜

  </Layout>
</template>

<page-query>
query{
  craft {
    entries(limit:10) {
      title
      id
    }
  }
}
</page-query>

こんな感じで一覧も表示出来た。

ここまでやって、開発してるところで vercel って叩くと連携までやってくれるの便利だな。

初回だったからか登録してるメールアドレスを聞かれて答える。
確認メールが届くのでそこで承認。

再度ターミナルで vercel を叩くと色々ときかれるので基本はそのままで対応。

ってやったら

https://gridsomecraft.vercel.a...

で公開までされた。
ほー。。。便利だ。
あとでちゃんとリポジトリも作っておこう。


SSG と CMS 組み合わせる時はプレビューまでちゃんと出来ないことには使い物にはならないが、、、そこはちょっと次の課題、、、ってことで。
Gatsby の方もそこはまだ出来てなかった。

Craft 用の source プラグインがちゃんと動くのかどうかがよくわからないし。。。

@bhws/gridsome-source-craft-graphql - Gridsome
https://gridsome.org/plugins/@...

Next.js / Apollo のとかも途中だからもう少しやっておくかどうするか。。。
年末年始はたまってることを色々やるぞー、っておもえるのは年内のうちで年明けると一瞬だろうな・・・
とりあえず来年に向けて Vue.js / NuxtJS はさわりつつ、 Svelte あたりまで触れれば・・・
(そもそも JavaScript / TypeScript をちゃんと・・・)