Help us understand the problem. What is going on with this article?

Github Pages で .htaccess の代わりに javascript のみでURLの rewrite を実現してパーマリンクを有効にする

More than 1 year has passed since last update.

目的

Github Pages でパーマリンク(整形された動的URL)を使えるようにする。Github Pages では .htaccess などによるURLの rewrite ができないので、同等の機能を javascript のみで実現する。

必要なもの

  • javascript のみ

※ Jekyll は使わない。

仕組み

  1. パーマリンクによる無効なURLを一旦 404.html で受ける(Github Pages のデフォルト仕様)
  2. 404.html に仕込んだ javascript で、クエリストリング付きの有効なURLに変換して目的のページ post.html にリダイレクト
  3. リダイレクトされた目的のページ post.html で、historyAPI の replaceState を使ってURLを最初にリクエストされたパーマリンクに変換

基本構成と各ファイルがやっていること

--
 |-- index.html
 |-- 404.html(無効なパーマリンクを有効なURLに変換してリダイレクト)
 |-- post.html(リクエストされたURLをパーマリンクに再変換)

サンプル

実際に GitHub Pages でサンプルサイトを公開中。

パーマリンクでの遷移を実現するためにやっていることは

  • 404.html
  • post.html

内に記述した下記 javascript のみ。

404.html
/*
 * (JS部分のみ抜粋)
 * パーマリンクをクエリストリング付きのURLに変換してリダイレクト
 */

// リダイレクト先のファイル名
var redirect_file_name = 'post.html';

// リダイレクトで使用するパラメータキー
var parameter_key = 'post_id';

// パーマリンクの取得
var path_name = window.location.pathname;

// クエリストリング付きのURLに変換してリダイレクト
var match_condition = new RegExp(redirect_file_name.replace('.html', '') + '/[a-z0-9-_]+$');
if (permalink = path_name.match(match_condition))
{
  location.href = path_name.replace(permalink, '') + redirect_file_name + '?' + parameter_key + '=' + permalink[0].replace(/post\//, '');
}
post.html
/*
 * (JS部分のみ抜粋)
 * クエリストリング付きのURLをパーマリンクに再変換
 */

// ファイル名
var file_name = 'post.html';

// パラメータキー
var parameter_key = 'post_id';

// URLを取得
var path_name = window.location.pathname;
var query_string = window.location.search;
var base_dir = path_name.split(file_name)[0];

// パーマリンクに再変換
var match_condition = new RegExp(parameter_key + '=[a-z0-9-_]+$');
if (parameter = query_string.match(match_condition))
{
  parameter_value = parameter[0].split('=')[1];
  history.replaceState(null, null, base_dir + file_name.replace('.html', '/') + parameter_value);
  document.title = parameter_value + ' | Github Pages Rewrite';
}

詳しくはこちらのサンプルソースから。

問題点

  • リダイレクトが実行されるので明らかな遷移感がある
  • replaceState が走る前に一瞬変換前のURLが見える(ときもある)

mod_rewrite などWEBサーバのリライト機能と完全に同等というわけではなく、結果として同じことができている、ということ。

その他

Github Pages は拡張子なしのURLを受け付けるので、canonical でURLの正規化さえしておけば固定ページのリライトを意識する必要はなさそう。

どちらも同じリソースを表示する
/contact.html
/contact

さいごに

Jekyllredirect_from のほうがスマートですが、ワイルドカードや正規表現を使ったリダイレクトルールが作れなかったので無理やりこの方法を試してみました。
もっといい方法があればどなたかご教授ください。

そもそも S3Firebase などリライトが可能なサービス使えよ、っていう話ですが、やっぱり CI や Pipeline の設定なしでそのまま本番デプロイできる Github Pages は便利だな、と思うので。
Github さんには rewrite 機能を json で設定できるなどの追加サービスを期待したいです。

以上です。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away