2020-11-20

【Gatsby.js】やたら簡単!Netlifyでリダイレクト!(URL転送)

プラグインなどのインストールなしでリダイレクトするコードがあるのでわかりやすく解説。

Article Image

なぜリダイレクトが必要なのか

URLを引っ越ししたときにGoogle検索が404になってしまう対策。

ユーザー側への不利益のみならず、自身のSEOへも悪影響がある。

そんな頻繁に引っ越しする? → 意外にする

Gatsby.jsは基本的にフォルダ階層がそのままURLへと変換される。

つまりフォルダ名を変更したり、階層を増やしたりする場合URL転送が逐一必要になる。

私の場合BLOG記事が増えすぎて年ごとにフォルダ分けしたためURL転送が必要となった。

前提条件

  • サーバーがNetlifyであること(別サーバーだと:slugなどのプレースホルダは使用不可)

  • gatsby-plugin-netlifyがインストール済みであること(Netlifyを使っていれば普通入ってるはず)

他にライブラリ等はいらないので基本的にはすごく簡単。

今回の例

具体的な私の例を見て示す。

「/blog/記事」 → 「/blog/2020/記事」 へ転送

/blog/配下にあった記事を/blog/2020/の配下へ配置し転送する。

コード : gatsby-node.js

まずは転送元と転送先をgatsby-node.jsに書く。

exports.createPages = ({ actions, graphql }) => { //ここはもともとあるコード
  const { createPage, createRedirect } = actions //ここはもともとあるコード

  //これが転送用の関数
  createRedirect({
    fromPath: "/blog/:slug",
    toPath: "/blog/2020/:slug",
    isPermanent: true
  });
    
...以下略

createRedirect

コード内にcreateRedirectを記述してbuildするだけで転送設定は完了する。

オプションはシンプルで

  • fromPath : こちらのURLにアクセスしたときに
  • toPath : このURLへ転送する

isPermanentは一時的なサイト移転(あとでもとに戻す予定)でなければtrue。つまりURLは変更したまま戻すことはないですよという意味。

基本はtrueでいいはず。SEOに関わってくると思われるが詳しくは別サイトにて。

以上!簡単!

なんと、以上で転送設定は終わっている。

buildしてNetlifyにdeployして本番で確認する。

createRedirectはgatsbyが用意している基本機能なので簡単なのだ。

これで/blog/なんとかにアクセスすると /blog/2020/なんとかに正しく「301」コードにて転送される(SEO的にもGoogle検索も問題ない)

注意点はdevサーバーでは転送が行われないこと。

あくまでcreateRedirectは本番サーバーのサーバー側の転送プログラムを呼び出すものであり、開発環境では意味がない。

さて、ここからは細かく説明するので必要な人のみどうぞ。

試しに次のリンクで/blog/直下でアクセスすると/blog/2020/へとリダイレクトが確認できる

/blog/2020-11-20-【Gatsby_js】やたら簡単!Netlifyでリダイレクト!(URL転送)/

:slugとは?

このコロン:から始まるのはNetlify側で設定されている変数のようなもの。プレースホルダーと呼ばれている。

スラッグの意味を知らないブロガーはあまりいないと思うが要するにここは「記事ごとに別々のタイトルが入りますよ」という意味。

つまり?

  • /blog/hogeなら/blog/2020/hoge
  • /blog/fuga/なら/blog/2020/fuga

に転送される。

「*」と「:splat」で説明してるサイトが多いんですが...?

このサイト以外では恐らく次のコードで転送を推奨しているが私の場合は動作しないので後ほど解説する。

  createRedirect({
    fromPath: "/blog/*",
    toPath: "/blog/2020/:splat",
    isPermanent: true
  });

この場合は恐らく/blog/a/b/c/d/e/のように深い階層もまるごと/blog/2020/に転送するコードとなる。

/blog/2020/a/b/c/d/e/に転送されるはずだ。

しかしながら私のケースではこれは404が表示される。後ほど詳しく解説する

※このコロンのあとに続くプレースホルダの詳細は公式を参照。

Redirect options | Netlify Docs

転送前にファイルがある場合とない場合

まず*splatを理解する前にファイルがある場合と無い場合で転送の挙動が異なるので覚えておきたい。

例えば今回の例のような転送が設定されている状態で/blog/aにアクセスしたとする。

/blog/直下にaというファイルが存在した場合、転送は行われずaの内容が表示される。

aが存在しなければ/blog/2020/aに転送される。

更に/blog/2020/aも存在しなければここでようやく404になる。

「*」と「:splat」のバグ?

バグ?としたのは公式に詳しい解説がないからそうさせていただいた。

私のバグは「*」と「:splat」で転送すると/blog/直下にファイルが存在しないのに転送が行われず問答無用で404が返される。

これはなぜなのだろうか。

記事のタイトルが「2020-」から始まっている

どうやら記事のタイトル(スラッグ)がすべて2020-から始まっているのが悪さをしているらしい。

つまり

/blog/2020/2020-月-日-タイトル

というところに転送してほしいのだが「*」か「:splat」のどちらかでバグがあり先頭の2020とフォルダ名の2020は纏められて

/blog/2020-月-日-タイトルでURLが解決してしまうのである。

結果404

フォルダ名と記事名が被る可能性があるなら:slug

記事タイトルの開始文字がフォルダ名とかぶる可能性がある転送は:slugを使ったほうが良いのではと結論づける。

偶然フォルダ名とタイトルの前方が一致してしまった場合転送が行われないので十分注意である。

ただ、別の解決作として/2020/のフォルダを/posts2020/のように絶対被らないフォルダ名にするという手もある。

直下だけでなく深い階層も追従して転送するのであればこのような方法を考えると良いと思う。

以上

公式に詳しい解説がないのであくまで私の推論になってしまったのだが、簡単な反面よくわからない挙動を偶然を引いてしまった。

もしだれか同じような不具合で困っている場合助けになれたら幸いである。



この記事のタグ

この記事をシェア


謎の技術研究部 (謎技研)