Gatsby.js で記事の URL のみカスタマイズする

September 08, 2020

Gatsby.js で記事の URL をカスタマイズする方法です。 これを使うと、すべての記事の URL が変更されるので注意が必要です。

もっとスマートな方法があったら教えていただけると嬉しいです。

結論

gatsby-node.js のこれを

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

こうします

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    console.log(node)
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value: `/posts${value}`, // ここでカスタマイズします
    })
  }
}

メモ

そもそも私自身 Gatsby.js を始めて日が浅いので、今回の方法がベストプラクティスではない可能性がありますのでご容赦ください。

gatsby-source-filesystem を使用している前提です。 これは gatsby-starter-blog にデフォルトで採用されてるやつです。

記事は登録した Node をもとに生成されています。 その Node を登録するときに onCreateNode が呼ばれています。

https://www.gatsbyjs.com/docs/node-apis/#onCreateNode

gatsby-source-filesystem だとその中で createFilePath にて生成されるパスをそのまま設定しているのがデフォルトになっています。 value というやつですね。 value には例えば /2020-09-08T21:24:43.098Z/ みたいな文字列が入ってます。

https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#createfilepath

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

こいつを書き換えることで URL を変化させることが出来ます。 今回ですと value/2020-09-08T21:24:43.098Z/ みたいな文字列が入っていたら、/posts/2020-09-08T21:24:43.098Z/ にすれば良さそうです。 そのため value`/posts${value}` に書き換えればいいというわけです。

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    console.log(node)
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value: `/posts${value}`,
    })
  }
}

ドキュメントのここらへんにも書き換えてるサンプルがありますね。 https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/#example-usage

そもそもなぜ URL をカスタマイズするかという話です。

URL から「記事」「記事ではないページ」を判定できることはとても大きなメリットです。 記事のみ移管するときにリダイレクト等の差し込みが楽になります。

URL を変更する際には「パスを切る」ほうが「パスを切るのをやめる」より難しいです。 つまり、 /2020-09-08T21:24:43.098Z/posts/2020-09-08T21:24:43.098Z のように変えるのはとてもコストが掛かるのです。

なぜか、それはその記事がリンクされた場合とかを想定すると容易です。 記事の URL を変更したなら、親切なら変更後の URL にリダイレクトしたいところです。 しかし、例えばタグ一覧ページ( /tags )みたいなのがあったとして、そういった「記事ではないページ」はリダイレクトしないようにする必要があります。 「記事ではないページ」も「記事」も同じように / 以下直接にしてしまうと、あとから判別が難しくなりそうです。

しかし、逆は簡単です。 /posts/2020-09-08T21:24:43.098Z/2020-09-08T21:24:43.098Z にする場合ですね。 その場合は「/post以下に来たアクセスを/以下にリダイレクトする」という処理で終わります。 別のフレームワークに移行するときなんかも可搬性は高いと思います。

今回はブログを始めて作ったので、早めに URL 移行することにした次第です。 /posts 以下にするのが微妙だったらもとに戻そうと思います。


© takanakahiko 2024, Built with Gatsby
This site uses Google Analytics.