SlidevをGitHub Pagesで公開

2 min read読了の目安(約2500字

こちらの記事を見て自分も触ってみたくなりSlidevを使ってみました。

https://sli.dev/guide/#overview

SPAとしてビルド

guideページで一通り使い方やサンプルを見て、アニメーションや動画が入ったスライドも作りやすそうだなと思いました。さらにSPAとして出力し、静的ホスティングサービスにデプロイすることで動きのあるスライドもそのまま簡単に共有できるというのが良いなーと思いました。

GitHub Pagesにデプロイしてみる

GitHub PagesはGitHubの静的サイトホスティングサービスです。

https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages

試しにリポジトリを作り、そのリポジトリのGitHub Pagesとしてデプロイしてみました。

ベースパスの設定

しかし、そのままでは表示されませんでした。というのも、GitHub Pagesは種類があり、

  • ユーザーサイト
    • http(s)://<username>.github.io/でアクセス
  • プロジェクトサイト
    • http(s)://<username>.github.io/<repository>でアクセス

という状況で、自分は後者のものでデプロイしていました。
Slidevで単純にビルドを行うとassetsなどのパスがdocument root(/)基準で決まります。であるのでこのままではプロジェクトサイトでは正しくassetsなどが参照出来ません。ビルド時にベースパスのオプションを指定することでこれを解決出来ます。

slidev build --base /<repository>

リロードすると404

これでやっとスライドが表示されました!満足しながら触っていて、ふと途中のページでリロードをすると404ページに飛んでしまいました。。。
落ち着いて考えればSPAはクライアント側でルーティングされているだけでサーバー上にはindex.htmlしかページは無いので当然です。これではちょっと残念だな。。。と思いググってみました。

404のトリック

こちらのブログにたどり着きました。

https://dev.to/_evansalter/github-pages-and-single-page-apps

GitHub Pagesは404.htmlを追加することで独自の404ページを表示出来ます。それを利用して今回の状況を解決していました。手順は以下です。

1. 404.htmlの追加

以下のコードを含む404.htmlを追加します。

<script>
  sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/'"></meta>

これは

  • sessionStorageに現在のパスを保持
  • リロード時にルートに飛ばす

という処理を行うようにしています。

2. index.htmlにscriptの追加

さらに404から帰ってきたルートで以下のスクリプトが働くようにコードを追加しておきます。

<script>
  (function(){
    var redirect = sessionStorage.redirect;
    delete sessionStorage.redirect;
    if (redirect && redirect != location.href) {
      history.replaceState(null, null, redirect);
    }
  })();
</script>

これはつまり以下の状況では404から遷移してきたとみなし、保持していたパスにHistory APIで書き換えてしまうということです。

  • redirectが存在
  • かつredirectが現在のパス(document root)と異なる

1,2をあわせてもとのページ -> 404 -> document root -> もとのページへと遷移します。
これを組み込んでみることでリロードをしてももとのページに戻ることが出来ました!ちょっと感動しました!

テンプレートを作ってみた

以上でGitHub Pagesに正しく動くようにデプロイし、リロードしてももとのページを表示できるようになります。ただ特に404の追加やindex.htmlへコードを挿入するのは面倒なのでpackage.jsonにそれらを行い、gh-pagesでデプロイまでするscriptを追加したテンプレートを作ってみました。

https://github.com/shu1007/slidev-gh-page-template

テンプレートで作ったGitHub Pagesです。

https://shu1007.github.io/slidev-gh-page-template

みなさん良ければ使ってみてください。

終わりに

まだフルに機能を生かしたスライドは作っていませんが、何かの発表の機会を見つけてSlidevでスライドを作ってみたいと思います!