Shopifyストアのオーナーが去年、プレミアムメガメニューアプリをインストールしました。そのアプリは素晴らしいレビュー、美しいアニメーション、スッキリしたインターフェースを備えていました。販売は横ばいのままでした。3ヶ月後、Google Search Consoleでクロールされたページが40%減少したことを示しました。問題はメニューデザインではなく、メニューリンクがJavaScriptにのみ存在していたことです。Googleのクローラーは、カテゴリページへのリンクがないホームページを見ました。カテゴリページは孤立していました。
これが私が最も頻繁に目にするナビゲーションSEOの間違いです:ユーザーには完璧に見えるメニューが検索エンジンには見えません。修正は複雑ではありませんが、本物のHTMLリンクとJavaScriptのみのナビゲーションパターンの違いを理解し、トラフィックが失われる前に問題を検出するために自分のサイトを監査する方法を知る必要があります。
- Googleはhref属性を持つHTMLアンカータグをクロールします。JavaScriptのクリックハンドラーはカウントされません。
- ビューソースはJavaScriptが実行される前の生のHTMLを表示します。これはGoogleが最初に見るものです。
- 一般的な間違い:onclickハンドラー、javascript:void(0)、data-url属性を持つdiv要素。
- 修正:サーバーでHTMLにリンクをレンダリングし、JavaScriptで相互作用のみを向上させます。
Googleのクローラーが実際に見るもの
Googleがページをクロールするとき、サーバーにHTTPリクエストを送信してHTMLを受信します。クローラーはそのHTMLを解析してリンクを探します。具体的には、href属性を持つ<a>タグを探します。見つかったすべてのURLがクロールキューに追加されます。
これは最初のパスです。GoogleのクローラーはJavaScriptを実行できます(内部ではChromeのバージョンを使用しています)。しかし、JavaScriptレンダリングは後で2番目のパスで発生し、すべてのページで保証されません。Googleは最初のパスHTMLクロールを優先します。なぜなら、それは高速で信頼性が高いからです。ナビゲーション全体がJavaScriptに依存するページは不利です。
Googleが探すもの:
<a href="/collections/summer-shoes">Summer Shoes</a>
これは本物のリンクです。href属性にURLが含まれています。Googleのクローラーは/collections/summer-shoesを抽出してクロールキューに追加します。このページはクロールおよびインデックスされます。
Googleが最初のパス中に無視または見落とすもの:
<div onclick="window.location='/collections/summer-shoes'">Summer Shoes</div>
<a href="javascript:void(0)" onclick="navigate('/collections/summer-shoes')">Summer Shoes</a>
<button data-url="/collections/summer-shoes">Summer Shoes</button>
これらはいずれも本物のhref属性を持つアンカータグではありません。URLはコード内に存在します(onclickハンドラーまたはdata属性内)。Googleの最初のパスクローラーはリンクを検出するときにJavaScriptを実行したりdata属性を解析しません。これらのリンクは最初のクロール中は見えません。
Googleは他の手段(サイトマップ、外部バックリンク、JavaScriptレンダリング)を通じて最終的にこれらのページを検出する可能性がありますが、メインナビゲーションHTMLでリンクされることから来るクロール優先度やリンク流動性は得られません。
ビューソース:決定的なテスト
ナビゲーションがクローラブルかどうかを確認するのに特別なツールは必要ありません。すべてのブラウザには「ビューソース」機能があり、JavaScriptが実行される前にサーバーから送信された生のHTMLを表示します。これはまさにGoogleの最初のパスクローラーが見るものです。
確認方法
- Chrome、Firefox、またはSafariでストアのホームページを開きます。
- ページの任意の場所を右クリックして「ページソースを表示」を選択します(Windowsではctrl+U、MacではCmd+Option+U)。
- 新しいタブが開き、生のHTMLが表示されます。
- Ctrl+F(Macではcmd+F)を押して、メインカテゴリページのいずれかのURLを検索します。例:
/collections/women。
URLをこのようなアンカータグ内に見つけた場合:
<a href="/collections/women">Women's Clothing</a>
ナビゲーションはクローラブルです。Googleはそのリンクをたどることができます。
URLがビューソースにまったく表示されない場合、または<script>タグまたはこのようなdata属性内にのみ表示される場合:
<div class="menu-item" data-url="/collections/women">Women's Clothing</div>
ナビゲーションは最初のパスでクローラブルではありません。Googleの最初のHTMLクロールはそれを見落とします。
モバイル vs デスクトップ
多くのストアではモバイルとデスクトップで異なるナビゲーション実装を使用しています。デスクトップ版は意味的なHTMLアンカータグを使用し、モバイル版はJavaScriptのみのハンバーガーメニューを使用する場合があります。Googleはモバイルファースト インデックスを使用しているため(モバイル版がGoogleが主にクロールするバージョンです)、モバイルHTMLを別途確認する必要があります。
Chromeで:
- DevToolsを開きます(F12またはRight+click → 検査)。
- デバイスツールバーアイコンをクリックします(またはCtrl+Shift+M / Cmd+Shift+M)。
- ドロップダウンからモバイルデバイスを選択します(例:iPhone SE)。
- ページをリロードします。
- 再度右クリックしてソースを表示します。
モバイルHTMLでカテゴリURLを検索してください。表示されない場合、Googleのモバイルクローラーはナビゲーションリンクを見ていません。
ビューソーステストに失敗する一般的なパターン
パターン1:JavaScriptで生成されるメガメニュー
多くの最新メニューアプリはこのように機能します:
- サーバーは最小限のHTML(メニュートリガーボタンだけ)を送信します。
- ユーザーがホバーまたはクリックすると、JavaScriptはAPIからメニューデータをフェッチするか、JSONオブジェクトを解析します。
- JavaScriptは完全なDOM(すべての
<a>タグを含む)をビルドしてページに注入します。
サーバーから送信されたHTMLの例:
<button id="mega-menu-trigger">Shop</button>
<div id="mega-menu-container"></div>
<script>
const menuData = {
"women": {"label": "Women", "url": "/collections/women"},
"men": {"label": "Men", "url": "/collections/men"}
};
// JavaScriptはユーザーが相互作用する際にリンクをビルドして注入します
</script>
ビューソースはボタンと空のコンテナを表示します。リンクはまだ存在しません。Googleの最初のパスクロールはカテゴリページへのリンクを見ません。
パターン2:シングルページアプリのルーティング
ReactやVue等のSPAフレームワークで構築されたストアはしばしばクライアントサイドルーティングを使用します。メニューはフレームワークコードではこのように見えるかもしれません:
<Link to="/collections/summer-shoes">Summer Shoes</Link>
これがクローラブルかどうかは、フレームワークがどのようにレンダリングするか、そしてアプリがサーバーサイドレンダリングを使用しているかによります。アプリが純粋なクライアントサイドSPA(サーバーが単一のindex.htmlシェルを送信してJavaScriptがすべてをレンダリング)の場合、ビューソースはナビゲーションリンクのない空のシェルを表示します:
<!DOCTYPE html>
<html>
<head><title>Store</title></head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>
ナビゲーションを含むすべてのコンテンツはJavaScriptによってレンダリングされます。Googleの最初のパスクロールは何も見ません。
パターン3:hrefがないonclickハンドラー
一部のメニューはアンカータグを使用していますが、ナビゲーションロジックをonclickハンドラーに置き、javascript:void(0)をhrefとして使用します:
<a href="javascript:void(0)" onclick="goToCategory('women')">Women</a>
これはユーザーにはリンクのように見え、クリックされたときもリンクのように動作しますが、javascript:void(0)は本物のURLではありません。Googleのクローラーはhref属性からjavascript:void(0)を抽出し、クローラブルなURLではないため破棄します。本物の宛先(/collections/women)はクローラーが最初のパスHTMLの解析中に実行しないJavaScript関数goToCategory()に埋もれています。
パターン4:data属性を持つdivとボタン
開発者は時々非意味的要素を使用してナビゲーションをビルドします:
<div class="nav-item" data-url="/collections/women" onclick="navigate(this.dataset.url)">
Women
</div>
これはユーザーに対して機能します(JavaScriptはdata属性を読み取り、クリックされたときにナビゲートします)。しかし、<a>タグもhref属性もありません。Googleのクローラーはdata属性のURLを探しません。リンクは見えません。
JavaScriptのみのリンクを修正する方法
修正1:HTMLでリンクをレンダリングし、JavaScriptで向上させる
最良のアプローチ:サーバー(または静的サイトジェネレーター)が本物のアンカータグを持つ完全なHTMLを出力します。JavaScriptは上部に相互作用を追加します。
サーバーでレンダリングされたHTML:
<nav>
<a href="/collections/women">Women</a>
<a href="/collections/men">Men</a>
<a href="/collections/kids">Kids</a>
</nav>
このHTMLはクローラブルです。Googleはすぐにリンクを見ます。
その後JavaScriptで向上させます:
document.querySelectorAll('nav a').forEach(link => {
link.addEventListener('click', (e) => {
// スムーズなトランジション、分析などを追加
// ブラウザが通常通りナビゲートさせる(preventDefaultしない)
});
});
ナビゲーションはJavaScriptなしで動作します(グレースフルデグラデーション)。JavaScriptで完璧に動作します(プログレッシブエンハンスメント)。どちらの場合でもクローラブルです。
修正2:SPAのサーバーサイドレンダリングを使用する
ストアがReact、Vue等で構築されたシングルページアプリの場合、サーバーサイドレンダリング(SSR)または静的サイト生成(SSG)を実装してください。
これを簡単にするフレームワーク:
- Next.js for React
- Nuxt for Vue
- SvelteKit for Svelte
- Gatsby for static sites
これらのフレームワークはサーバーで完全なHTML(ナビゲーションを含む)をレンダリングします。最初のページロードは完全でクローラブルなHTMLを提供します。その後JavaScriptはページをハイドレートして、その後のナビゲーションを引き継ぎ、ユーザーにはSPA体験を、検索エンジンにはクローラブルなHTMLを提供します。
修正3:メニューアプリの設定を確認する
Shopifyメニューアプリを使用している場合、アプリの設定で「SEOモード」または「サーバーサイドレンダリング」オプションを確認してください。多くのアプリはこれをトグルとして提供しています。有効にすると、アプリはJavaScriptではなくLiquid(Shopifyのサーバーサイドテンプレート言語)でナビゲーションリンクをレンダリングします。
アプリがこのオプションを提供せず、ビューソース経由でナビゲーションがクローラブルでないことを確認している場合、オプションを提供するアプリへの切り替えを検討してください。Navi+ AI Menu BuilderはデフォルトですべてのリンクをHTMLでレンダリングします。リンクは最初のHTMLペイロードにあり、JavaScriptは相互作用とアニメーションのみを処理します。
修正4:ハンバーガーメニューのプログレッシブエンハンスメント
モバイルハンバーガーメニューはユーザーがアイコンをタップするまでナビゲーションを非表示にすることが多いです。リンクがHTMLに存在する限り、メニューはクローラブルのままです:
<nav class="mobile-menu" aria-hidden="true">
<a href="/collections/women">Women</a>
<a href="/collections/men">Men</a>
</nav>
CSSはデフォルトでメニューを非表示にします:
.mobile-menu {
display: none;
}
.mobile-menu.is-open {
display: block;
}
JavaScriptはハンバーガーがタップされたときにクラスを切り替えます:
hamburgerButton.addEventListener('click', () => {
mobileMenu.classList.toggle('is-open');
});
リンクはHTMLに存在します(ビューソースは表示します)。CSSで非表示になっていますが、Googleはクロールできます。これで問題ありません。Googleはコンテンツが欺瞞的でない限り、非表示コンテンツにペナルティを与えません(キーワード詰め込みスパムを非表示にしていない場合)。
機能しないもの:ハンバーガーがタップされたときにのみJavaScriptでモバイルメニューDOMをビルドします:
hamburgerButton.addEventListener('click', () => {
const menu = document.createElement('nav');
menu.innerHTML = '<a href="/jp/collections/women">Women</a>...';
document.body.appendChild(menu);
});
このメニューはユーザーが相互作用するまでHTMLに存在しません。Googleのクローラーはハンバーガーアイコンをタップしません。リンクは見えません。
修正をテストする
ナビゲーションを更新した後、それがクローラブルであることを確認します:
- ビューソーステスト:ホームページをリロードしてビューソースを表示します。カテゴリURLを検索してください。アンカータグに表示されることを確認します。
- JavaScript無効テスト:Chrome DevTools で、JavaScriptを無効にします(設定 → デバッガー → JavaScriptを無効)。ホームページをリロードします。ナビゲーションリンクが見えてクリックできることを確認します。リンクをクリックするとカテゴリページにナビゲートする必要があります(JavaScriptなしではページが壊れて見えますが、ナビゲーションは機能します)。
- Google Search Console:数日待ってから、カバレッジレポート(ページ → インデックス済み)を確認します。以前は孤立していたカテゴリページがインデックス済みとして表示され始めた場合、修正は機能しました。
デスクトップとモバイルの両方を確認してくださいサイトのデスクトップとモバイルの両方のバージョンでビューソーステストを実行してください。モバイルナビゲーションが異なる実装を使用している場合(ハンバーガーメニュー、別のアプリ、簡素化された構造)、別々にテストしてください。Googleのモバイルファースト インデックスは、モバイル版がランキングにとって重要なものであることを意味しています。
これが思っているより重要な理由
ナビゲーションはサイト上の多くの内部リンクのうちの1つではありません。これはGoogleが見る最も目立つ、一貫したリンクセットです。メインナビゲーションはすべてのページに表示されます。これはHTMLドキュメントの上部にあるヘッダーにあり、Googleが重要なリンクを見つけることを期待する場所です。Googleがホームページをクロールするとき、ナビゲーションは見つかった最初のリンクセットです。
これらのリンクがクローラブルでない場合、Googleは単にいくつかのページを見落とします。サイトアーキテクチャを理解するための主要な信号が失われます。カテゴリページは孤立したままです。これらのカテゴリページからのみリンクされている製品は、1レベル深い孤立した状態になります。Googleの観点からは、サイト全体の構造が崩壊します。
そしてナビゲーションは非常に一貫性があるため(すべてのページに同じメニュー)、影響は複合します。ホームページナビゲーションがJavaScriptのみの場合、サイト上のすべてのページに同じ問題があります。Googleが100ページをクロールしても、すべての100ページで0個のナビゲーションリンクが見つかります。これは軽微なSEO問題ではありません。これは基本的なクローラビリティ障害です。
ビューソーステストは30秒かかります。カテゴリURLが生のHTMLに表示されない場合、最も重要なSEO修正を見つけました。その他すべて(キーワード最適化、バックリンク、技術的改善)は、Googleがページをクロールできるという前提の上に構築されます。クローラブルなナビゲーションがなければ、その前提は偽りです。
このArticleは、より大きなガイドの一部です:Navigation SEO: making sure Google can crawl your menu structure。