GitHub Pagesで、サイト内のリンクを絶対パスで張るときは、変数site.baseurlを使う必要がある。そうしないと、公開サイトとローカルの両方で有効なパスにならないからだ。前回書いたように、GitHub Pagesをローカルでテストするためには、この考慮が必要になる。

例えば、サイトのトップにindex.htmlがあって、ディレクトリの深いところからトップに戻るリンクを張るとする。ここで絶対パスを

[サイトのトップ](/index.html)

と書くと、ローカルでは動くが、公開サイトでは動かない。なぜなら、公開サイトのURLは、リポジトリ名を含んだhttps://alpha3166.github.io/blogのような形をしているので、/index.htmlは、https://alpha3166.github.io/index.htmlと解釈されてしまうからだ。かといって、リンクにリポジトリ名を含めて

[サイトのトップ](/blog/index.html)

と書くと、今度はローカルで動かなくなる。ローカルでは、http://localhost:4000/index.htmlのように、リポジトリ名がないURLが必要だからだ。

そこで、こういう場合は、サイトの基準パスを変数site.baseurlを使って書くようにする。

[サイトのトップ]({{ site.baseurl }}/index.html)

あるいは、Liquidフィルタのrelative_urlを噛ませてもよい。relative_urlは入力値の前にsite.baseurlの値を追加してくれるので、上と同じ結果になる(relativeという名前だが、別に相対パスに変換されるわけではない)。

[サイトのトップ]({{ "/index.html" | relative_url }})

GitHub Pagesのサイトでは、_config.ymlにbaseurlを書いておかなくても、勝手にhttps://alpha3166.github.io/blogのような値が注入されるようだ。

ローカルで動かす場合は、jekyll serveのオプションに--baseurl ""で空文字列を渡してやる。なので、前回書いたDockerファイルも、最後のCMDにこのオプションを付けるようにする。

FROM    jekyll/jekyll
RUN     echo "source 'https://rubygems.org'" > Gemfile && \
        echo "gem 'github-pages', group: :jekyll_plugins" >> Gemfile && \
        bundle install && \
        rm -f Gemfile Gemfile.lock
RUN     mkdir /srv/src
EXPOSE  4000
WORKDIR /srv/src
CMD     ["bundle", "exec", "jekyll", "serve", "--destination", "/srv/jekyll", "--host", "0.0.0.0", "--baseurl", ""]

Dockerイメージのビルドと実行手順は前回と同じ。

vi Dockerfile
docker build -t gh-pages .
cd サイトのトップディレクトリ
docker run --rm -it -v "$PWD:/srv/src" -p 4000:4000 gh-pages

※バージョンメモ

  • Ubuntu Server 18.10
  • Docker 18.09.3

※更新履歴

  • 2020-06-11 誤記訂正。
  • 2024-02-10 Jekyll(というか、正確にはLiquid)の変数展開をエスケープする手段を見つけたので、例の中の全角波括弧を半角に修正。
  • 2024-02-18 relative_urlの記述を追加。