Posted at

Gatsbyを利用したブログでパーマリンクを自由に設定できるようにする方法


はじめに

これまで Gatsby と Netlify CMS でブログの構築をしてきました。

Netlify CMSとGatsbyのTypescript Starterを使ってブログを構築

それでいざブログを公開してみて気付いたのがリンクが日本語になっている...エンコードのせいでめっちゃ長い...ということです。


https://www.boholabo.com/blog/typography-js%E3%81%AB%E3%82%88%E3%82%8B%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%BE%E3%81%A8%E3%82%81


これは非常に良くないですし何のページなのか分からないので変えることにしました。今回はその修正を記録に残したいと思います。


理想のパーマリンク構造

今回私が理想のパーマリンクとして考えているのは以下のような設定になります。


http://example.com/カテゴリー名/パーマリンク


全てアルファベットにしてカテゴリ以下に記事を置くことでより何の記事なのかが分かりやすく、SEO 対策にもなります。

ただし、残念なことにパーマリンクの設定により SEO の評価が上がるといったことはないようです。

ですが URL が日本語のままでエンコーディングされた、長い意味不明の文字列のままだと Google のクローラーがページを判断できなかったりとネガティブな影響を及ぼすことがあるということは広く知られています。

特に私の場合はリンクを別の場所に貼って公開をしたいので、リンクをシンプルにするということは非常に重要だと感じています。


パーマリンクの設定

それでは実際にパーマリンクの設定をできるようにしていきましょう。

まず各々の CMS にパーマリンクを設定するためのフォームを設定していきます。

私は Netlify CMS を利用しているので static/admin フォルダ内の config.yml ファイルへパーマリンクとカテゴリ欄を設定します。

デフォルトではユニークキーに title が設定されていますが、URL が被るとまずいので permalink を identifier_field に設定します。

Fields 内に permalink のフォームを設定します。これで文字列を入力するためのフォームを CMS 側に生成することができました。

slug は permanent の値が入るように修正しておきます。これで CMS 側の設定は完了です。


static/admin/config.yml

collections:

- name: 'blog'
identifier_field: 'permalink'
label: 'Blog'
folder: 'src/pages/blog'
create: true
slug: '{{permalink}}'
fields:
- { label: 'Template Key', name: 'templateKey', widget: 'hidden', default: 'blog-post' }
- { label: 'Title', name: 'title', widget: 'string' }
- { label: 'Publish Date', name: 'date', widget: 'datetime' }
- { label: 'Permalink', name: 'permalink', widget: 'string' }
- { label: 'Category', name: 'category', widget: 'string' }
- { label: 'Description', name: 'description', widget: 'text' }
- { label: 'Featured Image', name: 'thumbnail', widget: image, required: false }
- { label: 'Body', name: 'body', widget: 'markdown' }
- { label: 'Tags', name: 'tags', widget: 'list' }
- { label: 'banner', name: 'banner', widget: image, required: false }

gatsby-node.js 側の設定をしておきましょう。これをすることで実際に指定の URL に対するページを SSR で生成することができます。

gatby の API で createNodeFiled というメソッドがあります。これを設定することで graphql で node オブジェクトの中に新しいフィールドを生成することができます。

以下の場合ですと slug というフィールドを生成してその値にマークダウンへ保存した permalink の値を割り当てるようにしています。


gatsby-node.js

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

const { createNodeField } = actions;
if (node.internal.type === 'MarkdownRemark' && _.has(node, 'frontmatter') && _.has(node.frontmatter, 'permalink')) {
const permalink = `${_.kebabCase(node.frontmatter.permalink)}`;
createNodeField({ node, name: 'slug', value: permalink });
}
};

次に createPage メソッド部分の設定を調整します。最終的な目標としては/blog/{Categoly}/{Permalink}の形なので path の設定を変更します。これでページの生成は完了です。


gatsby-node.js

createPage({

path: path: `/blog/${node.frontmatter.category}/${_.kebabCase(node.fields.slug)}`,
component: postTemplate,
context: {
slug: _.kebabCase(node.frontmatter.permalink),
prev,
next,
},
});

残りはページのリンク先だけ修正しておきましょう。各自リンクを指定の URL に変更しておいて下さい。

私の場合はトップページとブログ一覧のそれぞれのコンポーネントに含まれているリンク先を変更しました。

const Article: React.FC<Props> = ({ title, date, excerpt, slug, timeToRead, category }) => {

const firstChar = title.charAt(0);

return (
<Post>
<Title>
<Initiale>{firstChar}</Initiale>
<Link to={`/blog/${category}/${slug}`}>{title}</Link>
</Title>
<Subline>
{date} &mdash; {timeToRead} Min Read &mdash; In
<Link to={`/categories/${kebabCase(category)}`}> {category}</Link>
</Subline>
<Excerpt>{excerpt}</Excerpt>
</Post>
);
};

以上で試しにページからリンクして正しいページが表示されれば完了となります。


まとめ

これで長い URL をよりシンプルなパーマリンクへと変更することができました。特に静的なサイトを作る場合には URL の名称をシンプルに維持するのが非常に重要なので必ず設定するようにしましょう。