検索関連の JavaScript の問題を解決する

このガイドでは、ページ(または JavaScript を使用するページの特定のコンテンツ)が Google 検索結果に表示されない場合、その原因となっている JavaScript の問題を特定して解決する方法を説明します。Google でも JavaScript は実行されますが、クローラによるアクセスやレンダリングに対応するには、ページやアプリケーションを設計する際に特別に考慮しなければならない点や制限事項がいくつかあります。 Google 検索向けに JavaScript サイトを最適化する方法について詳しくは、JavaScript SEO の基本に関するガイドをご覧ください。

Googlebot は、ウェブ上の一員として有益な働きができるよう設計されています。その主要な優先事項がクロールです。クロールは、サイトにアクセスするユーザーの利便性を損なわない仕組みになっています。Googlebot とそのウェブ レンダリング サービス(WRS)コンポーネントは、継続的に分析を行うことで、重要なページ コンテンツに貢献しないリソースを特定し、そのようなリソースを取得しない場合があります。たとえば、重要なページ コンテンツに貢献しないレポート作成やエラー要求などのリクエストは、重要なページ コンテンツの抽出に使用されない場合や、不要と判断される場合があります。クライアント側の分析では、サイト上での Googlebot や WRS のアクティビティを、完全または正確に把握できない可能性があります。Googlebot と WRS のアクティビティを確認し、サイトに関するフィードバックを得るには、Search Console を使用してください。

Google 検索結果にページ(または JavaScript を使用するページの特定のコンテンツ)が表示されない原因が、JavaScript の問題と考えられる場合は、下記の手順を実施します。JavaScript が主原因かどうか不明な場合は、一般的なデバッグのガイドに沿って問題を特定してください。

  1. Google による URL のクロールとレンダリングをテストするには、Search Console のモバイル フレンドリー テストまたは URL 検査ツールを使用します。読み込まれたリソース、JavaScript コンソールの出力と例外、レンダリングされた DOM、その他の情報を表示できます。

    必要に応じて、サイトのユーザー(Googlebot も含め)で発生した JavaScript エラーの収集と監査を行い、コンテンツのレンダリングに影響しうる問題を特定することもおすすめします。

    以下に、Global Onerror Handler に記録された JavaScript エラーを記録する方法の例を示します。JavaScript エラーの種類によって(解析エラーなど)は、この方法では記録できません。

    window.addEventListener('error', function(e) {
        var errorText = [
            e.message,
            'URL: ' + e.filename,
            'Line: ' + e.lineno + ', Column: ' + e.colno,
            'Stack: ' + (e.error && e.error.stack || '(no stack trace)')
        ].join('\n');
    
        // Example: log errors as visual output into the host page.
        // Note: you probably don't want to show such errors to users, or
        //       have the errors get indexed by Googlebot; however, it may
        //       be a useful feature while actively debugging the page.
        var DOM_ID = 'rendering-debug-pre';
        if (!document.getElementById(DOM_ID)) {
            var log = document.createElement('pre');
            log.id = DOM_ID;
            log.style.whiteSpace = 'pre-wrap';
            log.textContent = errorText;
            if (!document.body) document.body = document.createElement('body');
            document.body.insertBefore(log, document.body.firstChild);
        } else {
            document.getElementById(DOM_ID).textContent += '\n\n' + errorText;
        }
    
        // Example: log the error to remote service.
        // Note: you can log errors to a remote service, to understand
        //       and monitor the types of errors encountered by regular users,
        //       Googlebot, and other crawlers.
        var client = new XMLHttpRequest();
        client.open('POST', 'https://example.com/logError');
        client.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
        client.send(errorText);
    
    });
  2. soft 404 エラーを確実に防止します。シングルページ アプリケーション(SPA)では特に、ソフト 404 エラーを防止するのが困難な場合があります。エラーページがインデックスに追加されないようにするには、次のいずれかまたは両方を実施します。
    • サーバーが 404 ステータス コードを返す URL にリダイレクトする。
      fetch(`https://api.kitten.club/cats/${id}`)
       .then(res => res.json())
       .then((cat) => {
         if (!cat.exists) {
           // redirect to page that gives a 404
           window.location.href = '/not-found';
         }
       });
    • noindex に robots メタタグを追加する、または robots メタタグを変更する。
      fetch(`https://api.kitten.club/cats/${id}`)
       .then(res => res.json())
       .then((cat) => {
         if (!cat.exists) {
           const metaRobots = document.createElement('meta');
           metaRobots.name = 'robots';
           metaRobots.content = 'noindex';
           document.head.appendChild(metaRobots);
         }
       });

    SPA がエラーの処理にクライアント側 JavaScript を使用している場合に、適切なステータス コードではなく、200 HTTP ステータス コードを報告することが頻繁に発生します。それにより、エラーページがインデックスに登録され、検索結果に表示される可能性があります。

  3. Googlebot はユーザーへのアクセス許可リクエストを拒否するものと考えます
    ユーザー権限を必要とする機能は、Googlebot またはすべてのユーザーにとって意味をなしません。たとえば、Camera API を必須にしたとしても、Googlebot はカメラ機能を提供できません。ユーザーにカメラへのアクセス許可を求めずに、コンテンツにアクセスできるようにします。
  4. フラグメント URL を使用して別のコンテンツを読み込まないでください。
    SPA では、別のビューの読み込みにフラグメント URL(https://example.com/#/products など)を使用する場合があります。2015 年以降、AJAX クロールに関するスキームが廃止されたため、Googlebot との連携にフラグメント URL を使用することはできません。History API を使用して、SPA の URL に基づいて別のコンテンツを読み込むことをおすすめします。
  5. データの保持を利用してコンテンツを配信しないでください。
    WRS は、通常のブラウザと同じように、サーバーとクライアントのリダイレクトに従って各 URL を読み込みます(Google がコンテンツを検出する方法の概要については、Google 検索の仕組みをご覧ください)。ただし、WRS ではページ読み込み時に状態が保持されません。
    • ローカル ストレージとセッション ストレージのデータは、ページ読み込み時にクリアされます。
    • HTTP Cookie はページ読み込み時にクリアされます。
  6. コンテンツのフィンガープリントを使用すると、Googlebot のキャッシュに関する問題を回避できます。
    Googlebot は、ネットワーク リクエストとリソース使用量を低減するために、積極的にキャッシュに保存しますが、WRS はキャッシュ ヘッダーを無視する場合があります。このため、WRS は古い JavaScript や CSS リソースを使用するおそれがあります。この問題は、ファイル名の一部をコンテンツのフィンガープリントにすることで回避されます(main.2bb85551.js など)。フィンガープリントはファイル コンテンツによって異なるため、更新するたびに別のファイル名が生成されます。詳細については、長期保存キャッシュを使用する際の web.dev ガイドをご覧ください。
  7. アプリケーションでは、必要なすべての重要な API について機能検出を使用し、フォールバック動作や可能な場合はポリフィルを用意するようにします。
    ウェブ機能によっては、まだすべてのユーザー エージェントに採用されていない可能性があり、またエージェントによっては、意図的に特定の機能を無効にしている場合もあります。たとえば、ブラウザでフォト エフェクトをレンダリングするのに WebGL を使用する場合、機能検出により Googlebot では WebGL がサポートされていないことがわかります。これを解決するため、フォト エフェクトをスキップするか、サーバー側レンダリングを使用してフォト エフェクトを事前にレンダリングしておきます。こうすることで、Googlebot を含むすべてのユーザーがコンテンツにアクセスできるようになります。
  8. コンテンツが HTTP 接続に対応していることを確認します。
    Googlebot は、HTTP リクエストを使用してサーバーからコンテンツを取得します。 WebSockets WebRTC など、他のタイプの接続はサポートされていません。このような接続の問題を回避するには、コンテンツを取得するための HTTP フォールバックを提供し、堅牢なエラー処理と機能検出を使用してください。
  9. ウェブ コンポーネントのレンダリングが想定どおりに行われていることを確認します。モバイル フレンドリー テストまたは URL 検査ツールを使用して、レンダリングされた HTML に想定されるコンテンツがすべてあるかどうかを確認します。
    WRS は、Light DOM と Shadow DOM をフラット化します。ご使用のウェブ コンポーネントで Light DOM コンテンツに対し <slot> メカニズムが使用されていない場合は、ウェブ コンポーネントのドキュメントを参照して詳細を確認するか、別のウェブ コンポーネントを使用します。詳しくは、ウェブ コンポーネントに関するおすすめの方法をご覧ください。
  10. このチェックリストの項目を解決したら、Search Console のモバイル フレンドリー テストまたは URL 検査ツールを使用してページを再度テストします。

    問題が解決した場合は、エラーの代わりに緑色のチェックマークが表示されます。それでもエラーが表示される場合は、検索ワーキング グループの JavaScript サイトに投稿してください。