ブログ一覧の下に、Show more ボタンを置きたくなりました。
やりたいことは単純です。
ボタンを押したら、次の記事が下に増える。
以上。
……のはずでした。
実際には、Show more をどう見せるかより先に、ページネーションをどう扱うかを決める必要がありました。
/blog/page/2/ は残すのか。
JavaScriptが動かなかったらどうするのか。
Show more を押したあと、URLは変えるのか。
直接2ページ目へアクセスされたら、1ページ目も一緒に出すのか。
ボタンひとつのつもりが、ページネーション設計の話になりました。
最初に直したかった違和感
きっかけは、ブログ一覧まわりの小さな違和感でした。
まず、一覧ページの1ページ目は2カラム表示になっているのに、2ページ目以降は旧レイアウトの1カラム表示になっていました。
これは普通にバグです。
同じ記事一覧なのに、1ページ目と2ページ目で見た目が変わるのは気持ち悪い。
さらに、記事ページでは 公開日 2026-05-26、一覧カードでは 2026.05.26 のように、日付表記も揺れていました。
関連記事も最大3件になっていて、2カラム表示だと最後の1件だけが余る形になっていました。
どれも大事故ではありません。
でも、こういう小さな違和感が重なると、サイト全体が少し雑に見えます。
そこで、一覧表示を整理するついでに、ページネーションの導線も Show more にしてみようと考えました。
この時点では、まだ「ちょっとUIを整えるだけ」くらいの気持ちでした。
Show moreにすると何が嬉しいのか
ブログの記事一覧は、モバイルではカードを流し見することが多いです。
そのとき、毎回 次へ を押してページ遷移するより、今見ている一覧の下に記事が増えていく方が自然に感じます。
特に、今回の一覧はカード型の2カラム表示です。
Show more を押すと、次のカード群がそのまま下に追加される。
これは見た目にも操作感にも合っています。
Previous / Next のページネーションより、少しモバイル寄りです。
ただし、ここで問題があります。
「じゃあ、普通のページネーションURLは消していいのか?」という話です。
でもページURLを消していいのか問題
Show more だけを置いて、JavaScriptで次の記事を読み込むだけなら、見た目はすっきりします。
しかし、それだけにすると、JavaScriptが動かない環境では次ページへ進めません。
たとえば、次のようなURLです。
/blog/page/2/
/blog/page/3/
この静的なページURLは残しておいた方が安全です。
そこで、Show more は見た目としてはボタン風にしつつ、実体はリンクとして残すことにしました。
<a href="/blog/page/2/" data-show-more-link>Show more</a>
MDNの <a> HTML anchor element でも、href を持つ <a> はURLで指せるページやファイルなどへのハイパーリンクを作るものとして説明されています。今回の Show more は、見た目はボタンでも、役割としては次ページへ進むリンクです。
つまり、JavaScriptが使えるときだけクリックを横取りして、追加読み込みにします。
JavaScriptが動かなければ、普通に /blog/page/2/ へ移動します。
ここでようやく、ただのボタンではなくなりました。
採用した仕様
最終的には、次のような仕様にしました。
| 状況 | 挙動 |
|---|---|
| JavaScript有効時 | Show more で次ページHTMLを取得し、記事カードを追加する |
| JavaScript無効時 | 通常リンクとして次ページへ遷移する |
/blog/page/2/ 直接アクセス | 2ページ目の記事だけ表示する |
Show more 押下後 | URLは変えない |
| リンクとしての導線 | <a href> は残す |
/blog/page/2/ は、あくまで2ページ目です。
一方で、/blog/ 上で Show more を押したときだけ、1ページ目の下に2ページ目の記事カードを追加します。
また、Show more を押してもURLは変えません。
history.pushState() や replaceState() を使って、URLを /blog/page/2/ に変えることもできます。
でも今回はやめました。
URLだけが2ページ目になっているのに、画面には1ページ目と2ページ目が両方ある、という状態にしたくなかったからです。
仕組みはできるだけ単純にしました。
実装方針
実装では、JSONエンドポイントは作りませんでした。
既にAstroで /blog/page/2/ の静的HTMLが生成されているので、それをそのまま利用します。
流れはこうです。
Show more の href を読む
↓
次ページHTMLを fetch
↓
DOMParser でHTML化
↓
data-article-grid の article を取り出す
↓
現在の一覧末尾へ append
↓
次の Show more href を更新
使った目印は、主にこのあたりです。
<div data-article-grid>
<a href="/blog/page/2/" data-show-more-link>Show more</a>
fetch() はリソース取得に使えるWeb APIで、今回は次ページのHTMLを取得するために使いました。
取得したHTML文字列は、そのままだと文字列です。
そこで DOMParser を使い、HTML文字列をDOMとして扱える形にします。
そこから次ページ側の data-article-grid を探し、その中の article を現在ページの一覧へ追加します。
やっていることだけ見ると単純です。
でも、その前に「どのURLを残すのか」「URLは変えるのか」「直接アクセス時は何を出すのか」を決めておかないと、実装の意味がぶれます。
分岐としてはこうなった
今回の挙動を図にすると、こうなります。
この図だけ見ると、そんなに難しいことはしていません。
ただ、最初からこの図が頭にあったわけではありません。
「Show moreを置けば終わりでしょ」と思ってから、ここに着地しました。
一回目の実装で気づいた違和感
機能としての Show more は入りました。
でも、一回目の実装を見たら、別の違和感が出てきました。
Show more が左に寄っている。
白背景に薄いborderで、ボタンが背景と一体化している。
押したあと、Page 1 / 2 の表示まで消える。
ボタンを足したはずが、今度はボタンの存在感を探すことになりました。
さすがに、これは少し間抜けです。
そこで追加で修正しました。
最終ページまで読み込んだ後は、Show more だけを消します。
ページ表示そのものは残します。
つまり、Show more を押した後は Page 2 / 2 に更新し、ボタンだけ消えるようにしました。
この方が、いまどこまで読み込んだのか分かりやすいです。
Show moreにはaria-labelも付けたくなった
Show more という表示文言は、そのまま残したいです。
日本語にすると、少しサイトの雰囲気と合いません。
ただ、表示文言だけを見ると、何をもっと表示するのかは文脈に依存します。
W3C WAIの Understanding Success Criterion 2.4.4: Link Purpose (In Context) では、リンクの目的がリンクテキストや文脈から判断できることが扱われています。
そのため、記事にするなら実装側にも aria-label を足した方がよいと考えました。
表示は Show more のままにして、支援技術向けにはもう少し具体的な目的を渡す形です。
<a href="/blog/page/2/" data-show-more-link aria-label="次の記事一覧を表示する">
Show more
</a>
可能なら、次ページ番号も含めるとより分かりやすそうです。
aria-label="次の記事一覧を表示する(2ページ目)"
これは、本文だけの話ではなく、実装側にも反映したいところです。
小さいボタンだと思っていたものが、最終的にはアクセシビリティの話まで連れてきました。
本当に、ただのボタンでは済みませんでした。
ついでに直したもの
今回の主役は Show more ですが、一覧まわりの違和感も一緒に直しました。
まず、2ページ目以降のブログ・カテゴリ・タグ一覧も ArticleGrid に統一しました。
これで、1ページ目だけ2カラム、2ページ目だけ旧1カラム、という状態はなくなりました。
日付表示も YYYY.MM.DD に統一しました。
2026.05.26
記事ページでは、次のようにラベル付きで表示します。
公開日 2026.05.26
更新日 2026.05.26
さらに、関連記事は最大4件に変更しました。
2カラム表示なので、最大3件より最大4件の方が収まりが良かったからです。
ここは大きな設計というより、見た目の気持ちよさです。
でも、こういう気持ちよさも大事です。
参考にした情報
今回の記事はSEO解説ではありません。
ただ、Show more をただのJavaScriptボタンにせず、<a href> を残す判断や、HTMLを取得してDOMとして扱う実装を説明するために、MDNとW3C WAIの情報を参照しました。
- MDN:
<a>HTML anchor element - MDN: Fetch API
- MDN: DOMParser
- MDN: History API
- W3C WAI: Understanding Success Criterion 2.4.4: Link Purpose (In Context)
Show more がSEOに有利になる、という話ではありません。
今回の判断は、もっと手前の話です。
次ページへ進めるURLを残しておく。
JavaScriptが動かなくても遷移できる。
直接URLへアクセスしても意味のあるページを表示する。
そのうえで、JavaScriptが使える環境だけ Show more として振る舞わせる。
それくらいの温度感です。
学び
今回の学びは、かなり地味です。
小さいUI変更でも、仕様はあります。
Show more は、ページネーションの置き換えではありませんでした。
少なくとも今回のブログでは、ページネーションの見せ方のひとつでした。
静的なページURLを残す。
そのURLを href に入れる。
JavaScriptが有効なら追加読み込みにする。
JavaScriptが無効なら普通に遷移する。
この形にしたことで、モバイルでの見やすさと、静的サイトとしての分かりやすさを両方残せました。
最初から完璧なUIにはなりませんでした。
左に寄るし、ボタンは薄いし、押したらページ表示まで消えました。
でも、見て直せばよいです。
小さいボタンひとつでも、確認するとちゃんと直すところが出てきます。
まとめ
Show more ボタンを入れたら、ページネーション設計の話になりました。
ただのボタン追加のつもりでしたが、実際にはURL、JS無効時の動作、直接アクセス、状態表示まで決める必要がありました。
結果として、今のブログでは次の形に落ち着きました。
- ページURLは残す
Show moreは<a href>として実装する- JavaScript有効時だけ追加読み込みする
- JavaScript無効時は通常リンクとして遷移する
Show more押下後もURLは変えない- 直接2ページ目へアクセスしたら2ページ目だけ表示する
Show moreは、ただのボタンではありませんでした。
少なくとも、今回の自分のブログではページネーション設計でした。