Fix Search-related JavaScript problems

This guide helps you identify and fix JavaScript issues that may be blocking your page, or specific content on JavaScript powered pages, from showing up in Google Search. While Google Search does run JavaScript, there are some differences and limitations that you need to account for when designing your pages and applications to accommodate how crawlers access and render your content. Ourguide on JavaScript SEO basicshas more information on how you can optimize your JavaScript site for Google Search.

Googlebot is designed to be a good citizen of the web. Crawling is itsmain priority,while making sure it doesn't degrade the experience of users visiting the site. Googlebot and its Web Rendering Service (WRS) component continuously analyze and identify resources that don't contribute to essential page content and may not fetch such resources. For example, reporting and error requests that don't contribute to essential page content, and other similar types of requests are unused or unnecessary to extract essential page content. Client-side analytics may not provide a full or accurate representation of Googlebot and WRS activity on your site. Usethe crawl stats report in Google Search Consoleto monitor Googlebot and WRS activity and feedback on your site.

If you suspect that JavaScript issues might be blocking your page, or specific content on JavaScript powered pages, from showing up in Google Search, follow these steps. If you're not sure if JavaScript is the main cause, follow ourgeneral debugging guideto determine the specific issue.

  1. To test how Google crawls and renders a URL,use theRich Results Testor theURL Inspection Toolin Search Console. You can see loaded resources, JavaScript console output and exceptions, rendered DOM, and more information.

    Optionally, we also recommend collecting and auditing JavaScript errors encountered by users, including Googlebot, on your site to identify potential issues that may affect how content is rendered. Here's an example that shows how to log JavaScript errors that are logged in theglobal onerror handler.Note that some types of JavaScript errors, such as a parse error, cannot be logged with this method.

    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 /logError');
    client.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
    client.send(errorText);
    
    });
  2. Make sure to preventsoft 404errors.In a single-page application (SPA), this can be especially difficult. To prevent error pages from being indexed, you can use one or both of the following strategies:
    • Redirect to a URL where the server responds with a404status code.
      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';
      }
      });
    • Add or change therobotsmetatag tonoindex.
      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);
      }
      });

    When an SPA is using client-side JavaScript to handle errors they often report a200HTTP status code instead of theappropriate status code.This can lead to error pages being indexed and possibly shown in search results.

  3. Expect Googlebot to declineuser permission requests.
    Features that require user permission don't make sense for Googlebot, or for all users. For example, if you make theCamera APIrequired, Googlebot can't provide a camera to you. Instead, provide a way for users to access your content without being forced to allow camera access.
  4. Don't use fragment URLs to load different content.
    A SPA may use fragment URLs (for example https://example /#/products) for loading different views. TheAJAX-crawling scheme has been deprecatedsince 2015, so you can't rely on fragment URLs to work with Googlebot. We recommend using theHistory APIto load different content based on the URL in an SPA.
  5. Don't rely on data persistence to serve content.
    WRS loads each URL (refer toHow Google Search Worksfor an overview of how Google discovers content), following server and client redirects, same as a regular browser. However, WRS does not retain state across page loads:
    • Local Storage and Session Storage data are cleared across page loads.
    • HTTP Cookies are cleared across page loads.
  6. Use content fingerprinting to avoid caching issues with Googlebot.
    Googlebot caches aggressively in order to reduce network requests and resource usage. WRS may ignore caching headers. This may lead WRS to use outdated JavaScript or CSS resources. Content fingerprinting avoids this problem by making a fingerprint of the content part of the filename, likemain.2bb85551.js. The fingerprint depends on the content of the file, so updates generate a different filename every time. Check out theweb.dev guide on long-lived caching strategiesto learn more.
  7. Ensure that your application usesfeature detectionfor all critical APIs that it needs and provide a fallback behavior or polyfill where applicable.
    Some web features may not yet be adopted by all user agents and some may intentionally disable certain features. For example, if you use WebGL to render photo effects in the browser, feature detection shows that Googlebot doesn't support WebGL. To fix this, you could skip the photo effect or decide to use server-side rendering to prerender the photo effects, which makes your content accessible to everyone, including Googlebot.
  8. Make sure your content works with HTTP connections.
    Googlebot uses HTTP requests to retrieve content from your server. It does not support other types of connections, such asWebSocketsorWebRTCconnections. To avoid problems with such connections, make sure to provide an HTTP fallback to retrieve content and use robust error handling andfeature detection.
  9. Make sure your web components render as expected. Use theRich Results Testor theURL Inspection Toolto check if the rendered HTML has all content you expect.
    WRS flattens thelight DOM and shadow DOM. If the web components you use aren't using<slot>mechanismfor light DOM content, consult the documentation of the web component for further information or use another web component instead. For more information, seebest practices for web components.
  10. After you fix the items in this checklist, test your pagewith theRich Results Testor theURL inspection toolin Search Console again.

    If you fixed the issue, a green check mark appears and no errors display. If you still see errors, post in theSearch Central help community.