ページを消すとき、一緒に消えるもの
実績とスキルの個別ページを、トップページの中へ統合しました。
作業自体は「セクションにidを付けて、ページを2枚消す」だけです。消すほうに、決めることが集まっていました。
個別ページを持つ価値をどう判断したか、ページを消すときに一緒に消えてしまうもの、そして統合したあとに出た「リンクを押しても動かない」問題です。
同じ内容が、2つのURLにあった
トップページには、もともと実績・スキル・プロフィールのセクションがあります。そのうえで /projects と /skills という個別ページも持っていました。
個別ページを持つ価値は、そこにしかない情報があるかで決まります。実績が20件あって絞り込みや並べ替えが要るなら、独立したページに意味があります。
しかし実績は数件で、当面増える見込みもありません。結果として、ほぼ同じ内容が2か所にある状態でした。
検索エンジンから見ると、似た内容のページが2つあります。どちらを検索結果に出すべきかを判断させることになり、評価も2つに分かれます。
読む人にとっても、メニューの「実績」を押した先が、直前まで見ていたトップの内容とほぼ同じ、というのは肩透かしです。
消すと、一緒に消えるもの
ここが本題です。ページを削除すると、そのURLは404になります。失われるのは中身だけではありません。
| URLに付いていたもの | 削除したとき |
|---|---|
| 検索エンジンからの評価 | 引き継がれず消える |
| 他サイトから貼られたリンク | 404へ向かう |
| ブックマーク・履歴 | 404が出る |
URLは外から指される名前です。中を整理した都合で、外からの参照を無効にしてよい理由にはなりません。
そこで、旧URLを新しい位置へ転送する設定を入れました。
/projects → /#projects
/skills → /#skills
これで評価は転送先へ引き継がれ、古いリンクを踏んだ人も目的の場所に着きます。
恒久か、一時的か
転送には「もう戻らない」と「一時的に別の場所を見せている」の2種類があります。今回は戻す予定が無いので恒久を選びました。
恒久として返すと、ブラウザはその対応を記憶します。次からはサーバーに聞かずに転送先へ行きます。速い代わりに、あとで気が変わっても、記憶を持っている人には届きません。
迷いがあるうちは一時的な転送にしておくほうが安全です。恒久にするのは、本当に戻さないと決めてからで遅くありません。
sitemapからは外した
細かい点ですが、転送するURLを一覧に載せたままにしませんでした。
sitemapは「このURLを登録してほしい」という一覧です。そこに転送するURLを書くと、「登録してほしい」と「そこへ行くな」を同時に伝えることになります。矛盾した指示は、送らないほうが良いはずです。
統合したら、リンクが動かなくなった
ここで問題が出ました。トップページ以外から「実績」を押しても、目的の場所へ行きません。
原因は、ページの移動の仕方でした。
同じページの中 → ブラウザが自分でスクロールする
別のページから来た → 画面を読み込み直さず中身だけ差し替える
= ブラウザは「移動した」と思っていない
= URLの # を見て動いてくれない
加えて、移動した直後は画面の先頭に戻されます。何もしないと「トップページの一番上に着いただけ」という結果になります。
そこで、移動後にURLの # を読んで、その位置までスクロールさせる処理を足しました。飛び先がまだ描画されていない場合に備えて、1回だけ待って再試行しています。
# つきのリンクは、HTMLの最初期からある機能です。動いて当然と思っていました。
しかし「画面を読み込み直さずに中身を差し替える」作りにした時点で、ブラウザが担当していた仕事の一部を、こちら側が引き取っています。引き取ったことに気づいていないと、こういう抜けになります。
着地の位置も直した
もうひとつ。アンカーで飛んだ先が、貼り付いたヘッダーの裏に隠れていました。
飛び先の位置を計算するとき、ブラウザはヘッダーの存在を考慮しません。要素の上端を画面の上端に合わせるだけです。
飛んだときだけ余白を確保する指定があるので、ヘッダーの高さぶんを足しました。
今回の学び
まず、個別ページを持つ価値は、そこにしかない情報があるかで決まること。ページ数が多いこと自体には価値がありません。同じ内容が複数の場所にあると、評価も注意も分散します。
次に、URLは外から指される名前なので、中の都合で無効にしないこと。これはアンカーIDのときと同じ話でした。指す側は、指される側の事情を知りません。消すなら、行き先を用意してから消します。
そして、恒久的な指定は、取り消しにくいこと。恒久転送はブラウザに記憶されるので、あとから変えても届かない相手が出ます。迷いがあるうちは一時的にしておく判断があります。
最後に、仕組みを変えたら、ブラウザ任せだった部分を確認すること。画面を読み込み直さない作りにした時点で、いくつかの仕事がこちら側に移っています。移ったことに気づかないまま「昔から動くもの」として扱うと、静かに動かなくなります。
意味を確認したい言葉があれば、用語集にまとめています。
301リダイレクト / sitemap.xml / canonical / スラッグ / App Router / prefers-reduced-motion
関連記事

ゆっくり読む人ほど、読了にならなかった
読了判定の分母に、フッターや前後記事リンクまで入っていた。本文を読み終えても89.9%。丁寧に読む人ほど読了にならない逆転が起きていた原因と、測ってから直した記録。

順番で決まる名前は、いつか壊れる
用語集の102語に記事からリンクを張ろうとしたら、そのIDが「何番目に出てきたか」で決まっていた。1語足すたびに以降が全部ずれる仕組みを、手書きの対応表に置き換えた話。

1語1ページにしなかった理由
用語集を作るとき、1語につき1ページにするか、まとめて1ページにするか。解説を厚くすると決めた時点で前提が変わり、最初の判断を見直すことになった。薄いページを大量に作るリスクと、本番のPHPを触れないという制約から、分野別8ページという形にたどり着いた記録。