
URLが気になっていました
このブログは韓国語、英語、日本語の3言語に対応しています。ですが、URL構造に少し問題がありました。
韓国語: /2026/02/21/claude-code-1m-cost-reality/
英語: /2026/02/21/claude-code-1m-cost-reality-en/
日本語: /2026/02/21/claude-code-1m-cost-reality-ja/
英語記事のURLの末尾に-enが付いているのが、どうにも気になっていました。見た目もよくないですし、Googleも言語別コンテンツは/en/のようなサブディレクトリ構造を推奨しています。記事が増えれば増えるほど、後から変更するのは大変になります。
目指したのはこの構造です。
graph LR
subgraph 変更前
A["/日付/slug/"] --- B["韓国語"]
C["/日付/slug-en/"] --- D["英語"]
E["/日付/slug-ja/"] --- F["日本語"]
end
subgraph 変更後
G["/日付/slug/"] --- H["韓国語"]
I["/en/日付/slug/"] --- J["英語"]
K["/ja/日付/slug/"] --- L["日本語"]
end
permalink + redirect_from の組み合わせで解決
Jekyllでは記事ごとにpermalinkを指定できます。英語・日本語の記事のfront matterに以下を追加しました。
# 英語記事のfront matter
permalink: /en/:year/:month/:day/:title/
redirect_from:
- /2026/02/21/claude-code-1m-cost-reality-en/
permalinkで新しいURLを指定し、redirect_fromで旧URLから自動リダイレクトされるようにしました。jekyll-redirect-fromプラグインが必要ですが、GitHub Pagesで公式サポートされているため、_config.ymlに1行追加するだけです。
# _config.yml
plugins:
- jekyll-redirect-from
次に、_layouts/default.htmlのhreflangタグも修正しました。
<!-- 変更前 -->
<link rel="alternate" hreflang="en" href="https://realcoding.blog-en/" />
<!-- 変更後 -->
<link rel="alternate" hreflang="en" href="https://realcoding.blog/en-en/" />
ただ、本当に大変だったのはその先でした。本文中にハードコードされたリンクが152箇所あり、すべて修正する必要がありました。
<!-- 変更前 -->
[Escaping Compacting Hell](/2026/02/20/claude-code-1m-context-review-en/)
<!-- 変更後 -->
[Escaping Compacting Hell](/en/2026/02/20/claude-code-1m-context-review-en/)
結果:140ファイル変更、569行追加、154行削除。かなり大がかりな作業でした。
ところがページネーションが壊れました
URL構造を変更したら、ページネーションに問題が発生しました。Jekyllのjekyll-paginateプラグインはルートディレクトリ(/)でしか動作しないという既知の制約があります。
韓国語のトップページ(/)では問題なく動いていましたが、/en/や/ja/ではpaginatorオブジェクト自体が存在しません。サーバーサイドのLiquidテンプレートでは対処できませんでした。
JavaScriptで全面刷新
そこで、クライアントサイドのJavaScriptページネーションに切り替えました。仕組みはシンプルです。
- Liquidですべての記事をHTMLにレンダリング
- JSが10件ずつ
display: none/blockで表示を切り替え ?page=2のURLパラメータでページを管理
コアとなるコードはこちらです。
(function() {
var POSTS_PER_PAGE = 10;
var posts = document.querySelectorAll('.posts-list .post-item');
if (posts.length <= POSTS_PER_PAGE) return;
var totalPages = Math.ceil(posts.length / POSTS_PER_PAGE);
var params = new URLSearchParams(window.location.search);
var currentPage = parseInt(params.get('page')) || 1;
function showPage(page) {
var start = (page - 1) * POSTS_PER_PAGE;
var end = start + POSTS_PER_PAGE;
for (var i = 0; i < posts.length; i++) {
posts[i].style.display = (i >= start && i < end) ? '' : 'none';
}
}
showPage(currentPage);
})();
このスクリプトをindex.html、en/index.html、ja/index.htmlの3箇所に配置しました。多言語ラベルは_data/*.ymlに追加しています。
# _data/ja.yml
posts:
prev_page: "前へ"
next_page: "次へ"
以前は韓国語のみ/page2/、/page3/形式でページネーションが機能していましたが、今は3言語すべてが?page=2方式に統一されました。
まとめ
URL構造は記事が蓄積される前に、早めに設計しておくべきです。後から変更すると、140以上のファイルを修正する作業が待っています。多言語Jekyllブログであれば、ルート以外のページには最初からJavaScript方式のページネーションを検討するのが現実的です。