集客・売上採用業務効率化制作実績会社概要ブログ無料相談
Webマーケ

カードは押せるのにリンクが無い。実績24件が内部リンク0本だった話

2026年9月5日
約13分で読めます
山田 祐輔
カードは押せるのにリンクが無い。実績24件が内部リンク0本だった話

自社サイトの制作実績ページを点検したら、掲載していた24件すべてが、検索エンジンから辿り着けない状態になっていました。カード自体はクリックできます。マウスで押せば詳細ページへ飛びます。それなのに、リンクとしては1本も存在していませんでした。

原因は、カードを<a>タグではなく、JavaScriptのクリック処理で動かしていたことでした。人間の操作では問題なく動くので、見ただけでは気づけません。修正自体は3箇所で終わりましたが、そこに辿り着くまでに一度誤診をして、無関係なファイルを直して本番に上げ、また戻すという往復をしています。その過程も含めて書きます。

きっかけは、実績を1件追加したことだった

新しい制作実績を1件追加し、一覧ページでの見え方を確認していたときのことです。カードのサムネイル画像の比率を測ろうとしてブラウザの検証ツールでDOMを覗いたところ、カードの中に<a>タグが1つも見当たりませんでした。

最初は「リンクが切れている」と判断しました。これが誤診でした。実際にはカードにdata-permalinkという属性が付いていて、テーマのJavaScriptがクリックを拾い、その値へ画面遷移させていたのです。つまり利用者にとっては正常に動いていました。

問題は別のところにありました。検索エンジンのクローラーはJavaScriptのクリックイベントを人間のようには辿りません。hrefのあるリンクを辿ってページを発見します。つまり実績の詳細ページは、一覧からの内部リンクが1本もない、孤立したページとして置かれていたことになります。

最初に、作業する場所を3つに分けて整理する

この手の作業でいちばん迷うのは「いま、どこを触っているのか」です。先に整理しておきます。

  • ブラウザの検証コンソール(調べる場所)。現状の把握と、直した後の確認に使います。ファイルは変わりません
  • テーマファイル(直す場所)。一覧ページを描画しているPHPテンプレートです。ここだけを編集します
  • WordPressの管理画面(今回は触らない)。記事や実績の中身の問題ではないので、投稿画面をいくら見ても原因は出てきません

用語は3つだけ覚えれば足りる

  • 内部リンク:同じサイト内のページ同士をつなぐリンク。クローラーがページを見つける通り道になります
  • アンカーテキスト:リンクとして表示されている文字。ここに何が書いてあるかで、リンク先の内容が伝わります
  • stretched link:小さなリンクの当たり判定を、擬似要素でカード全面まで広げる書き方。見た目を変えずにカード全体を押せるようにできます

手順0:自分のサイトが該当するか調べる

一覧ページのHTMLに、詳細ページへのリンクが何本あるかを数えます。ターミナルで次を実行してください。ドメインと一覧のパスは自分のものに置き換えます。

curl -s https://example.com/works/ | grep -c 'href="https://example.com/works/'

カードの枚数とだいたい同じ数が返れば正常です。0が返ったら、この記事と同じ状態です。ヘッダーやパンくずの分で数本多く出ることはありますが、判断は「0かどうか」で足ります。

手順1:カードが本当にリンクなのかを判定する【ブラウザの検証コンソール】

一覧ページを開き、検証ツールのコンソールで実行します。カードのクラス名は自分のテーマのものに置き換えてください。

const cards = [...document.querySelectorAll('.work-card')];
console.log('カード枚数:', cards.length);
console.log('リンクを持つカード:', cards.filter(c => c.querySelector('a[href]')).length);
console.log('data属性で動かしているか:', cards.filter(c => c.dataset.permalink).length);

3行目が効いてきます。リンクが0でdata属性が枚数分あれば、JavaScript頼みの構成だと確定します。私の場合はカード24枚、リンク0、data属性24でした。「押せば動く」ことは、リンクがあることの証明になりません。

手順2:どのファイルが描画しているかを特定する【テーマファイル】

ここで私は失敗しています。カードのHTMLを出力している関数をfunctions.phpの中に見つけたので、そこを修正して本番に反映しました。ところが表示は何も変わりませんでした。

原因は単純で、その関数はファイル内に定義されているだけで、どこからも呼ばれていなかったからです。過去の作り替えで使われなくなったまま残っていた、いわゆる死んだコードでした。実際に一覧を描画していたのは、固定ページ用の別テンプレートのほうです。無駄な往復を1回して、変更を本番ごと元に戻しました。

同じ轍を踏まないために、直す前にテーマ全体を検索して、そのHTMLを出しているのがどのファイルかを先に確定させてください。

grep -rn "work-card" --include="*.php" .

複数のファイルが引っかかったら、定義しているだけのものと、実際にループの中で出力しているものを見分けます。関数として定義されている場合は、その関数名でもう一度検索して、呼び出し元があるかどうかを確認するのが確実です。

手順3:タイトルを実リンクにする【テーマファイル】

カード全体を<a>で囲む方法もありますが、既存のCSSがdisplay: flexなどを前提にしているとレイアウトが崩れます。崩さずに済ませるなら、タイトルだけをリンクにするのが安全です。アンカーテキストが実績名になるので、リンクの意味もはっきりします。

<div class="work-title">
  <a class="work-link" href="<?php echo esc_url( get_permalink( $id ) ); ?>"><?php echo get_the_title( $id ); ?></a>
</div>

手順4:カード全面をリンクにする【テーマファイル / CSS】

タイトルだけがリンクだと、これまでカードのどこでも押せていたのに操作感が落ちます。擬似要素でリンクの当たり判定をカード全面に広げます。追加するのは実質3行です。

.work-card { position: relative; }
.work-title .work-link { color: inherit; text-decoration: none; }
.work-title .work-link::after { content: ""; position: absolute; inset: 0; z-index: 2; }

1行目が要です。::afterposition: absoluteで広がるので、基準になる親にposition: relativeが要ります。これが無いと、もっと外側の要素を基準にして画面全体を覆ってしまいます。

もうひとつ確認が要るのが重なり順です。カードの内側にpositionが指定された要素があると、擬似要素より前面に出てクリックを奪うことがあります。私のケースではサムネイル部分にposition: relativeが付いていましたが、z-indexautoでした。擬似要素側にz-index: 2を与えているので、擬似要素が前面に来ます。次のコードで確認できます。

const card = document.querySelector('.work-card');
[...card.querySelectorAll('*')]
  .map(e => ({ cls: e.className, pos: getComputedStyle(e).position, z: getComputedStyle(e).zIndex }))
  .filter(o => o.pos !== 'static')
  .forEach(o => console.log(o));

z-indexが2以上の要素が出てきたら、擬似要素側の値をそれより大きくします。

既存のJavaScriptは消さなくてよい

カードをクリックで飛ばしていたJavaScriptは、消さずに残して問題ありません。この種の実装は、たいてい次のような分岐を持っています。

if (e.target.closest('a, button')) return;

リンクやボタンの上でのクリックは処理せず、ブラウザ本来の動きに任せる、という書き方です。擬似要素でカード全面を覆うと、クリック対象はリンクになるので、JavaScript側は何もせずに抜けます。二重に遷移することはありません。もし自分のテーマにこの分岐が無ければ、追記しておくと安全です。

つまずき早見表

症状原因対処
直したのに表示が変わらない編集したファイルが使われていない(死んだコード)grepで出力元を特定し直す。関数なら呼び出し元の有無を確認
クリック範囲が画面全体になったカードにposition: relativeが無いカードの基準を先に作る
サムネイルの上だけ押せない内側の要素のz-indexが擬似要素より大きい擬似要素側のz-indexを上げる
カードのレイアウトが崩れたカード全体を<a>で囲んだタイトルだけをリンクにし、擬似要素で広げる方式に変える
タイトルの色が変わった・下線が出たリンクの既定スタイルcolor: inherittext-decoration: noneを当てる

直ったことの確認方法

手順0と同じコマンドをもう一度実行します。0だった数字がカード枚数になっていれば成功です。あわせて次の3点を見ます。

  • リンク先がすべて詳細ページか。誤って問い合わせページなどに向いていないか、出力されたURLを一覧で確認します
  • 中クリックで新しいタブに開けるか。JavaScript頼みだとこれができません。実リンクになった証拠になります
  • 見た目が変わっていないか。カードの寸法とカラム数を検証ツールで測り、修正前と一致することを確かめます

そのうえで、Search Consoleの「URL検査」で詳細ページを1件かけてみてください。インデックス状況と、そのページが発見された経路を確認できます。

正直に書いておくこと

この修正で検索順位が上がるとは言えません。内部リンクは評価に関わる要素のひとつですが、それ単体で順位が動くものではありません。ここで直せるのは「クローラーがそのページに辿り着く道を作る」ところまでです。詳細ページの中身が薄ければ、道ができても評価はされません。

また、JavaScriptでのクリック遷移そのものが悪いわけでもありません。近年の検索エンジンはJavaScriptを実行してページを読みます。ただし実行されるかどうかはクローラーの都合に依存しますし、hrefがあるリンクのほうが確実です。中クリックや「新しいタブで開く」が使えるという、利用者側の利点もあります。確実な側に寄せておく、という判断です。

効果の検証にも時間がかかります。クローラーが再訪して構造の変化を認識するまで、数日から数週間の幅があります。直した翌日に何かが変わることは期待しないでください。

要点

  • カードが「押せる」ことと「リンクがある」ことは別。hrefの数を数えれば1行で判定できる
  • 直す前に、そのHTMLを出力しているファイルを特定する。使われていないコードを直しても表示は変わらない
  • タイトルをリンクにして擬似要素で全面に広げれば、見た目も既存のJavaScriptも壊さずに済む
関連サービス
枚方市・交野市のホームページ制作 20万円〜(税別)。WordPress構築・スマホ対応・お問い合わせフォーム・初期SEO設定まで一式でご用意します。
この記事をシェア
freee・マネーフォワードをClaudeに繋ぐと何ができるのか|確定申告まで自動化できない理由 Gemini APIで素材画像を内製する。3枚で数十円、ただし無料枠はゼロ
山田祐輔 山田祐輔
山田 祐輔
YUSUKE YAMADA
代表取締役 / Web制作・AI業務効率化
30社+
支援実績
4
事業歴
1000
最大月商達成
10
最速成果達成
大阪府枚方市を拠点に、中小企業・個人事業主・スタートアップの「集客」と「採用」を仕組みから支援。2022年の個人開業を経て2024年1月に法人化。ホームページ制作・EC構築・LP制作からWeb広告運用・採用支援・業務効率化まで一気通貫で対応。
ホームページ制作 LP制作 ECサイト Google広告 Meta広告 採用支援 業務効率化 Notion
お問い合わせ LINEで相談