GatsbyJSには様々なスターターが用意されており、gatsby-starter-netlify-cmsもその一つです。 このブログもgatsby-starter-netlify-cmsをカスタムして作られています。 基本的に痒いところに手が届く作りにはなっていますが、気になる箇所もいくつかあります。 今回は「gatsby-starter-netlify-cmsでブログ記事のURL」を自由に指定できるようにする方法を紹介します。
gatsby-starter-netlify-cms
で作られた環境があること記事URLは、個々の記事に割り当てられるURLのことです。 gatsby-starter-netlify-cms
で環境を一通り作った場合、記事の投稿はCMS
の投稿画面から行う(≒自分で記事のmd
ファイルを作らない)わけですが、そうした場合に記事URLは「記事のmd
ファイル名」となります。
記事のmd
ファイル名はCMS
の投稿作成画面で入力した「TITLE」になります。
つまり、デフォルトのままではこの記事のURLは"https://nekoniki.com/gatsby-starter-netlify-cmsのブログ記事のURLを指定できるようにする"になるということです。
記事URLに日本語が入ってしまう点について、SEO
的には問題ないのですが、エンコードされた時の見栄えが美しくない。
※SNS
に記事を投稿した際にエンコードされてるっぽいリンクが入るのが個人的にはどうも好かないです。
まず始めに取り掛かるのは、CMS
の投稿画面で編集できる項目を増やすことです。
今回はQiita | Gatsby.js + NetlifyCMSのデータの流れまとめ(+投稿画面、URLのカスタマイズ)の記事を参考にsrc/statc/admin/config.yml
を修正しました。
少し解説をすると、collections
というのがCMS
で編集可能なページ区分一覧(デフォルトではpages
とblog
がある)で、その中のfields
が対象ページを編集した際に画面から編集可能な項目です。
今回はblog
のfields
にurl
を追加しています。
collections:
- name: "blog"
label: "Blog"
folder: "src/pages/blog"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "blog-post"}
- {label: "URL", name: "url", widget: "string"} // これを追加
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Description", name: "description", widget: "text"}
- {label: "Featured Post", name: "featuredpost", widget: "boolean"}
- {label: "Featured Image", name: "featuredimage", widget: image}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Tags", name: "tags", widget: "list"}
正常に適用されればCMS
の投稿画面にURL
の項目が追加されています。
そもそも記事URLがどこで設定されているかという話になるのですが、大元はgatsby-node.js
にあります。
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
fmImagesToRelative(node) // convert image paths for gatsby images
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode }) createNodeField({
name: `slug`,
node,
value, })
}
}
createFilePath
で取得した値をslug
という名前で作成しており、これがURLになっています。
なのでmd
ファイル名が記事URLになっているというわけです。
今回はgatsby-node.js
を修正し、先ほどCMS
で設定できるようになったURL
を使うようにしました。
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
fmImagesToRelative(node) // convert image paths for gatsby images
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
const url = node.frontmatter.url // URLを取得 createNodeField({
name: `slug`,
node,
// value,
value: url? url : value // URLがあればそちらを使う })
}
}
これでCMS
で設定したURL
が記事URLに反映されるようになりました。
今回はCMS
の投稿作成画面でURL
を自由に入力し、それが記事URLに反映されるようにしました。
当然ですが、このURL
は一意である必要があるため、このブログでは基本的に「YYYYMMDD_xxx」の形式とするようルールを設けています。
この辺りは管理人の好みな部分も大きいので、ご自身のスタイルに合わせてご利用ください。