<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Martin Splitt on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Martin Splitt</name>
  </author>
  <link href="https://web.dev/authors/martinsplitt/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/admin/HoAwoSaHr3yneJoSxKYc.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Our latest news, updates, and stories by Martin Splitt.</subtitle>
  
  
  <entry>
    <title>Web developer tools for debugging JavaScript issues in Google Search</title>
    <link href="https://web.dev/google-search-tools/"/>
    <updated>2020-06-25T00:00:00Z</updated>
    <id>https://web.dev/google-search-tools/</id>
    <content type="html" mode="escaped">&lt;p&gt;Google provides a lot of tools to help you debug JavaScript SEO issues in Google Search. This guide
gives you an overview of the available tools and suggestions on when to use each tool.&lt;/p&gt;
&lt;h2 id=&quot;find-basic-seo-issues-with-lighthouse&quot;&gt;Find basic SEO issues with Lighthouse &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#find-basic-seo-issues-with-lighthouse&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/overview/&quot; rel=&quot;noopener&quot;&gt;Lighthouse&lt;/a&gt; for your first investigation.
It comes with a bunch of &lt;a href=&quot;https://web.dev/pass-lighthouse-seo-audit/&quot;&gt;SEO audits&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of SEO audits in Lighthouse.&quot; decoding=&quot;async&quot; height=&quot;74&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/c6SfL83IXMmBArczs9Le.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The Lighthouse SEO audits are very basic first checks for a single page of your website. They catch
the most common mistakes and give you a first impression on how your website is doing in terms of
search engine discoverability. Note that Lighthouse runs in your browser, which is not an accurate
representation of how Googlebot might see a web page. For instance, browsers (and Lighthouse) don&#39;t
use &lt;code&gt;robots.txt&lt;/code&gt; to decide if they can fetch resources from the network, while Googlebot does. So when
Lighthouse identifies potential problems, you should fix them, but you may have to use other tools
to debug issues further.&lt;/p&gt;
&lt;h2 id=&quot;validate-pages-with-google-search-testing-tools&quot;&gt;Validate pages with Google Search testing tools &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#validate-pages-with-google-search-testing-tools&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Google Search provides
&lt;a href=&quot;https://developers.google.com/search/tools&quot; rel=&quot;noopener&quot;&gt;a set of tools for testing how Googlebot sees your web content&lt;/a&gt;.&lt;br /&gt;
Some of these tools are particularly useful when testing from your development environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;a href=&quot;https://search.google.com/test/mobile-friendly&quot; rel=&quot;noopener&quot;&gt;Mobile-Friendly Test&lt;/a&gt; ensures that a
page is mobile-friendly, which has been a
&lt;a href=&quot;https://webmasters.googleblog.com/2015/02/finding-more-mobile-friendly-search.html&quot; rel=&quot;noopener&quot;&gt;Google Search ranking signal since 2015&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://search.google.com/test/rich-results&quot; rel=&quot;noopener&quot;&gt;Rich Results Test&lt;/a&gt; validates that a page
is eligible for &lt;a href=&quot;https://developers.google.com/search/docs/guides/search-gallery&quot; rel=&quot;noopener&quot;&gt;rich results&lt;/a&gt;
based on the structured data that it provides&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://search.google.com/test/amp&quot; rel=&quot;noopener&quot;&gt;AMP Test&lt;/a&gt; validates your AMP HTML&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In combination with
&lt;a href=&quot;https://developers.google.com/search/docs/guides/debug#testing-firewalled-pages&quot; rel=&quot;noopener&quot;&gt;tools like local-tunnel or ngrok&lt;/a&gt;
you can create a temporary public URL from your local development environment and iterate quickly
while you are testing with Google&#39;s testing tools.&lt;/p&gt;
&lt;p&gt;These testing tools provide you with multiple helpful pieces of information, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The rendered HTML that Googlebot will use for indexing&lt;/li&gt;
&lt;li&gt;An overview of the resources loaded and explanations of why resources can&#39;t be loaded&lt;/li&gt;
&lt;li&gt;Console log messages and JavaScript errors with stack traces&lt;/li&gt;
&lt;/ul&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of the Mobile-Friendly Test.&quot; decoding=&quot;async&quot; height=&quot;492&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/HxpuDusVnyVm21QSD20b.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;The Google Search Console &lt;a href=&quot;https://support.google.com/webmasters/answer/9012289&quot; rel=&quot;noopener&quot;&gt;URL Inspection
Tool&lt;/a&gt; can also give you detailed
information about the status of a page.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of the URL Inspection Tool.&quot; decoding=&quot;async&quot; height=&quot;590&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/jyUDvp0zvkpUEgDjEULN.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Here you can find out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the URL is in the Google Search index or can be indexed in the future&lt;/li&gt;
&lt;li&gt;What the rendered HTML from the most recent crawl looks like&lt;/li&gt;
&lt;li&gt;What the rendered HTML looks like for a fresh crawl of the page&lt;/li&gt;
&lt;li&gt;Information about page resources&lt;/li&gt;
&lt;li&gt;JavaScript log messages and errors with stack traces&lt;/li&gt;
&lt;li&gt;A screenshot&lt;/li&gt;
&lt;li&gt;Mobile usability issues&lt;/li&gt;
&lt;li&gt;What structured data was detected on the page and if it&#39;s valid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using these tools you can identify most issues and resolve them. Google Search also provides
documentation for
&lt;a href=&quot;https://developers.google.com/search/docs/guides/fix-search-javascript&quot; rel=&quot;noopener&quot;&gt;fixing Google Search-related JavaScript problems&lt;/a&gt;
for more guidance on what to do once you identified the cause of a problem.&lt;/p&gt;
&lt;h2 id=&quot;investigate-site-health-with-google-search-console&quot;&gt;Investigate site health with Google Search Console &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#investigate-site-health-with-google-search-console&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The tools from the last section are great at resolving specific issues on a single page of your
website, but if you want to get a better overview of your entire website, the &lt;a href=&quot;https://search.google.com/search-console/about&quot; rel=&quot;noopener&quot;&gt;Google Search
Console&lt;/a&gt; is where you need to go.&lt;/p&gt;
&lt;h3 id=&quot;coverage-report&quot;&gt;Coverage report &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#coverage-report&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://support.google.com/webmasters/answer/7440203&quot; rel=&quot;noopener&quot;&gt;Coverage report&lt;/a&gt; shows you which
pages of your website are indexed and which ones have problems.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of the Coverage report.&quot; decoding=&quot;async&quot; height=&quot;567&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 754px) 754px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/A1KZQbjh96n9uv48fBCT.png?auto=format&amp;w=1508 1508w&quot; width=&quot;754&quot; /&gt;
&lt;/figure&gt;
&lt;h3 id=&quot;core-web-vitals-report&quot;&gt;Core Web Vitals report &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#core-web-vitals-report&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://support.google.com/webmasters/answer/9205520&quot; rel=&quot;noopener&quot;&gt;Core Web Vitals report&lt;/a&gt; helps you
get an overview of how the pages of your website are performing in terms of the &lt;a href=&quot;https://web.dev/vitals/#core-web-vitals&quot;&gt;Core Web
Vitals&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A screenshot of the Core Web Vitals report.&quot; decoding=&quot;async&quot; height=&quot;596&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 744px) 744px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/tcFciHGuF3MxnTr1y5ue01OGLBn2/LL7U1EcPCyuDcmjPD13c.png?auto=format&amp;w=1488 1488w&quot; width=&quot;744&quot; /&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;make-these-tools-part-of-your-developer-tooling&quot;&gt;Make these tools part of your developer tooling &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/google-search-tools/#make-these-tools-part-of-your-developer-tooling&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In this article, we&#39;ve seen a series of tools for various purposes from testing a page before
publishing it to monitoring the pages on a live website that give you transparency on how your
website does in terms of discoverability for Google Search. Some of these tools might become useful
parts of your development toolkit, others might be more like ad-hoc tools to identify the cause of a
problem and fix affected pages. To learn more about Google Search for developers or &lt;a href=&quot;https://developers.google.com/search/docs/guides/javascript-seo-basics&quot; rel=&quot;noopener&quot;&gt;JavaScript
SEO&lt;/a&gt;, check out the official
&lt;a href=&quot;https://developers.google.com/search&quot; rel=&quot;noopener&quot;&gt;Search for developers&lt;/a&gt; documentation.&lt;/p&gt;
</content>
    <author>
      <name>Martin Splitt</name>
    </author>
  </entry>
  
  <entry>
    <title>Making JavaScript and Google Search work together</title>
    <link href="https://web.dev/javascript-and-google-search-io-2019/"/>
    <updated>2019-06-05T00:00:00Z</updated>
    <id>https://web.dev/javascript-and-google-search-io-2019/</id>
    <content type="html" mode="escaped">&lt;p&gt;Great things are happening with Google Search, and we were excited to share them at Google I/O 2019!&lt;/p&gt;
&lt;div class=&quot;youtube&quot;&gt;  &lt;lite-youtube videoid=&quot;ufcijo46LCU&quot;&gt;  &lt;/lite-youtube&gt;&lt;/div&gt;
&lt;p&gt;In this post we&#39;ll focus on best practices for making JavaScript web apps discoverable in Google Search, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The new evergreen Googlebot&lt;/li&gt;
&lt;li&gt;Googlebot&#39;s pipeline for crawling, rendering and indexing&lt;/li&gt;
&lt;li&gt;Feature detection and error handling&lt;/li&gt;
&lt;li&gt;Rendering strategies&lt;/li&gt;
&lt;li&gt;Testing tools for your website in Google Search&lt;/li&gt;
&lt;li&gt;Common challenges and possible solutions&lt;/li&gt;
&lt;li&gt;Best practices for SEO in JavaScript web apps&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;meet-the-evergreen-googlebot&quot;&gt;Meet the evergreen Googlebot &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#meet-the-evergreen-googlebot&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This year we announced the much-awaited &lt;a href=&quot;https://webmasters.googleblog.com/2019/05/the-new-evergreen-googlebot.html&quot; rel=&quot;noopener&quot;&gt;new evergreen Googlebot&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;Googlebot holding the Chrome logo&quot; decoding=&quot;async&quot; height=&quot;401&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 400px) 400px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/q6RSuwuwLT7mcgE9Joqp.png?auto=format&amp;w=800 800w&quot; width=&quot;400&quot; /&gt;
  &lt;figcaption&gt;Googlebot is now running a modern Chromium rendering engine.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Googlebot now uses a modern Chromium engine to render websites for Google Search. On top of that, we will test newer versions of Chromium to &lt;em&gt;keep&lt;/em&gt; Googlebot updated, usually within a few weeks of each stable Chrome release. This announcement is big news for web developers and SEOs because it marks the arrival of &lt;a href=&quot;https://caniuse.com/#compare=chrome+41,chrome+74&quot; rel=&quot;noopener&quot;&gt;1000+ new features&lt;/a&gt;—such as ES6+, &lt;code&gt;IntersectionObserver&lt;/code&gt;, and Web Components v1—in Googlebot.&lt;/p&gt;
&lt;h2 id=&quot;learn-how-googlebot-works&quot;&gt;Learn how Googlebot works &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#learn-how-googlebot-works&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Googlebot is a pipeline with several components. Let&#39;s take a look to understand how Googlebot indexes pages for Google Search.&lt;/p&gt;
&lt;figure data-size=&quot;full&quot;&gt;
  &lt;img alt=&quot;A diagram showing a URL moving from a crawling queue to a processing step that extracts linked URLs and adds them to the crawling queue, a rendering queue that feeds into a renderer which produces HTML. The processor uses this HTML to extract linked URLs again and index the content.&quot; decoding=&quot;async&quot; height=&quot;446&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/zu4wDqHHxpU0dbwSajqA.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;Googlebot&#39;s pipeline for crawling, rendering, and indexing a page.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The process works like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Googlebot queues URLs for crawling.&lt;/li&gt;
&lt;li&gt;It then fetches the URLs with an HTTP request based on the &lt;a href=&quot;https://webmasters.googleblog.com/2017/01/what-crawl-budget-means-for-googlebot.html&quot; rel=&quot;noopener&quot;&gt;crawl budget&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Googlebot scans the HTML for links and queues the discovered links for crawling.&lt;/li&gt;
&lt;li&gt;Googlebot then queues the page for rendering.&lt;/li&gt;
&lt;li&gt;As soon as possible, a headless Chromium instance renders the page, which includes JavaScript execution.&lt;/li&gt;
&lt;li&gt;Googlebot uses the rendered HTML to index the page.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your technical setup can influence the process of crawling, rendering, and indexing. For example, slow response times or server errors can impact the &lt;a href=&quot;https://webmasters.googleblog.com/2017/01/what-crawl-budget-means-for-googlebot.html&quot; rel=&quot;noopener&quot;&gt;crawl budget&lt;/a&gt;. Another example would be requiring JavaScript to render the links can lead to a slower discovery of these links.&lt;/p&gt;
&lt;h2 id=&quot;use-feature-detection-and-handle-errors&quot;&gt;Use feature detection and handle errors &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#use-feature-detection-and-handle-errors&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The evergreen Googlebot has lots of new features, but some features are still not supported. Relying on unsupported features or not handling errors properly can mean Googlebot can&#39;t render or index your content.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at an example:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;     navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;geolocation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCurrentPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onSuccess&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span class=&quot;token function&quot;&gt;loadLocalContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This page might not show any content in some cases because the code doesn&#39;t handle when the user declines the permission or when getCurrentPosition call returns an error. Googlebot declines permission requests like this by default.&lt;/p&gt;
&lt;p&gt;This is a better solution:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br /&gt;     &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;geolocation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span class=&quot;token comment&quot;&gt;// this browser supports the Geolocation API, request location!&lt;/span&gt;&lt;br /&gt;       navigator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;geolocation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCurrentPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;br /&gt;         &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onSuccess&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span class=&quot;token comment&quot;&gt;// we successfully got the location, show local content&lt;/span&gt;&lt;br /&gt;           &lt;span class=&quot;token function&quot;&gt;loadLocalContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;         &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span class=&quot;token comment&quot;&gt;// we failed to get the location, show fallback content&lt;/span&gt;&lt;br /&gt;           &lt;span class=&quot;token function&quot;&gt;loadGlobalContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;         &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span class=&quot;token comment&quot;&gt;// this browser does not support the Geolocation API, show fallback content&lt;/span&gt;&lt;br /&gt;       &lt;span class=&quot;token function&quot;&gt;loadGlobalContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;If you have problems with getting your JavaScript site indexed, &lt;a href=&quot;https://developers.google.com/search/docs/guides/fix-search-javascript&quot; rel=&quot;noopener&quot;&gt;walk through our troubleshooting guide&lt;/a&gt; to find solutions.&lt;/p&gt;
&lt;h2 id=&quot;choose-the-right-rendering-strategy-for-your-web-app&quot;&gt;Choose the right rendering strategy for your web app &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#choose-the-right-rendering-strategy-for-your-web-app&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The default rendering strategy for single-page apps today is client-side rendering. The HTML loads the JavaScript, which then generates the content in the browser as it executes.&lt;/p&gt;
&lt;p&gt;Let&#39;s look at a web app that shows a collection of cat images and uses JavaScript to render entirely in the browser.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A code box showing HTML that loads some scripts. A screenshot of a web page on mobile that shows placeholder images while loading the actual content.&quot; decoding=&quot;async&quot; height=&quot;447&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/lzijYVwo1DPX3Fa2liXk.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;The rendering strategy influences the performance and robustness of your web apps.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If you&#39;re free to choose your rendering strategy, consider server-side rendering or pre-rendering. They execute JavaScript on the server to generate the initial HTML content, which can improve performance for both users and crawlers. These strategies allow the browser to start rendering HTML as it arrives over the network, making the page load faster.  The &lt;a href=&quot;https://www.youtube.com/watch?v=k-A2VfuUROg&quot; rel=&quot;noopener&quot;&gt;rendering session at I/O&lt;/a&gt;  or &lt;a href=&quot;https://web.dev/rendering-on-the-web/&quot;&gt;the blog post about rendering on the web&lt;/a&gt; shows how server-side rendering and hydration can improve the performance and user experience of web apps and provides more code examples for these strategies.&lt;/p&gt;
&lt;p&gt;If you&#39;re looking for a workaround to help crawlers that don&#39;t execute JavaScript—or if you can&#39;t make changes to your frontend codebase—consider &lt;a href=&quot;https://developers.google.com/search/docs/guides/dynamic-rendering&quot; rel=&quot;noopener&quot;&gt;dynamic rendering&lt;/a&gt;, which you can try out in &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/dynamic-rendering&quot; rel=&quot;noopener&quot;&gt;this codelab&lt;/a&gt;. Note, though, that you won&#39;t get the user experience or performance benefits that you would with server-side rendering or pre-rendering because dynamic rendering only serves static HTML to crawlers. That makes it a stop-gap rather than a long-term strategy.&lt;/p&gt;
&lt;h2 id=&quot;test-your-pages&quot;&gt;Test your pages &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#test-your-pages&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While most pages generally work fine with Googlebot, we recommend testing your pages regularly to make sure your content is available to Googlebot and there are no problems. There are several great tools to help you do that.&lt;/p&gt;
&lt;p&gt;The easiest way to do a quick check of a page is the &lt;a href=&quot;https://g.co/mobilefriendly&quot; rel=&quot;noopener&quot;&gt;Mobile-Friendly Test&lt;/a&gt;. Besides showing you issues with mobile-friendliness, it also gives you a screenshot of the above-the-fold content and the rendered HTML as Googlebot sees it.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;The mobile-friendly test shows the rendered HTML Googlebot sees after rendering the page&quot; decoding=&quot;async&quot; height=&quot;414&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/15IgtDchchBvLsVyzmG2.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;The mobile-friendly test shows you the rendered HTML Googlebot uses.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;You can also find out if there are resource loading issues or JavaScript errors.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;The Mobile-Friendly Test shows JavaScript errors and a stack trace.&quot; decoding=&quot;async&quot; height=&quot;414&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/22ttektRnHrbGT0zvbHK.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;It&#39;s recommended to verify your domain in &lt;a href=&quot;https://g.co/searchconsole&quot; rel=&quot;noopener&quot;&gt;Google Search Console&lt;/a&gt; so you can use the URL inspection tool to find out more about the crawling and indexing state of a URL, receive messages when Search Console detects issues and find out more details of how your site performs in Google Search.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;The URL inspection tool showing a page that is indexed with information on discovery, crawling and indexing for one URL&quot; decoding=&quot;async&quot; height=&quot;655&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/JYsPy8FXL3E86gCzekQ3.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;The URL Inspection Tool in Search Console shows the status of a page in crawling, rendering, and indexing.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For general SEO tips and guidance, you can use the SEO audits in Lighthouse. To integrate SEO audits into your testing suite, use the &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse/tree/master/lighthouse-cli&quot; rel=&quot;noopener&quot;&gt;Lighthouse CLI&lt;/a&gt; or the &lt;a href=&quot;https://github.com/GoogleChromeLabs/lighthousebot&quot; rel=&quot;noopener&quot;&gt;Lighthouse CI bot&lt;/a&gt;.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A lighthouse SEO report with a score of 44 and warnings about mobile-friendliness as well as warnings about content best practices&quot; decoding=&quot;async&quot; height=&quot;443&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/admin/ctch0ql8UQZiaKaWy34u.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;Lighthouse shows general SEO recommendations for a page.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;These tools help you identify, debug, and fix issues with pages in Google Search and should be part of your development routine.&lt;/p&gt;
&lt;h2 id=&quot;stay-up-to-date-and-get-in-touch&quot;&gt;Stay up to date and get in touch &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/javascript-and-google-search-io-2019/#stay-up-to-date-and-get-in-touch&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To stay up to date with announcements and changes to Google Search, keep an eye on our &lt;a href=&quot;https://webmasters.googleblog.com/&quot; rel=&quot;noopener&quot;&gt;Webmasters Blog&lt;/a&gt;, the &lt;a href=&quot;https://youtube.com/GoogleWebmasterHelp&quot; rel=&quot;noopener&quot;&gt;Google Webmasters Youtube channel&lt;/a&gt;, and our &lt;a href=&quot;https://twitter.com/googlewmc&quot; rel=&quot;noopener&quot;&gt;Twitter account&lt;/a&gt;.
Also check out our &lt;a href=&quot;http://developers.google.com/search/docs/guides/&quot; rel=&quot;noopener&quot;&gt;developer guide to Google Search&lt;/a&gt; and our &lt;a href=&quot;https://www.youtube.com/watch?v=LXF8bM4g-J4&amp;amp;list=PLKoqnv2vTMUPOalM1zuWDP9OQl851WMM9&quot; rel=&quot;noopener&quot;&gt;JavaScript SEO video series&lt;/a&gt; to learn more about SEO and JavaScript.&lt;/p&gt;
</content>
    <author>
      <name>Martin Splitt</name>
    </author><author>
      <name>Lizzi Harvey</name>
    </author>
  </entry>
  
  <entry>
    <title>Fix sneaky 404s</title>
    <link href="https://web.dev/codelab-fix-sneaky-404/"/>
    <updated>2018-11-05T00:00:00Z</updated>
    <id>https://web.dev/codelab-fix-sneaky-404/</id>
    <content type="html" mode="escaped">&lt;p&gt;Single Page Apps can show different content without loading a new page. To do
so, they use click handlers on links and the History API. The &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/History&quot; rel=&quot;noopener&quot;&gt;History
API&lt;/a&gt; allows to
manipulate the browser session history. This way we can update the URL when
showing a different page (usually called a &amp;quot;view&amp;quot; in Single Page Apps). It also
makes sure the browser&#39;s back button still works as expected.&lt;/p&gt;
&lt;p&gt;Take a look at the Single Page App in this codelab. It shows either cat or dog
images and provides links to toggle between the two animals. It seems to work
fine!&lt;/p&gt;
&lt;h2 id=&quot;uncovering-the-sneaky-404&quot;&gt;Uncovering the sneaky 404 &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/codelab-fix-sneaky-404/#uncovering-the-sneaky-404&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unfortunately there is a subtle bug in the app. Let&#39;s take a look!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To preview the site, press &lt;strong&gt;View App&lt;/strong&gt;. Then press
&lt;strong&gt;Fullscreen&lt;/strong&gt;
&lt;img src=&quot;https://web.dev/images/glitch/fullscreen.svg&quot; alt=&quot;fullscreen&quot; style=&quot;padding: 4px 8px; opacity: .5; border: 1px solid #c3c3c3; border-radius: 5px; margin-top: 0;&quot; /&gt;.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Doggos&lt;/strong&gt; link. Notice how the URL changed.&lt;/li&gt;
&lt;li&gt;Reload the app.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You get a page with &amp;quot;&lt;code&gt;Cannot GET /doggos&lt;/code&gt;&amp;quot; on it—a sneaky 404. It is &amp;quot;sneaky&amp;quot;,
because the web app seems to work fine as long as you only click on links within
it. It breaks when using the URLs in a new browser window or when refreshing the
page. The issue is that the server does not know how to respond to a request for
these URLs. The JavaScript code in our web app is using the History API to
navigate between them, but the server does not know what to do with them.
Whenever the server does not know what to do for a requested URL, it responds
with the HTTP status code &lt;code&gt;404&lt;/code&gt;. With this code the server says it hasn&#39;t found
anything for the requested URL.&lt;/p&gt;
&lt;p&gt;Search engines will not index the URLs in this case, because a user would click
on a search result and find the error message, but not the content they were
looking for, such as the dog pictures.&lt;/p&gt;
&lt;h2 id=&quot;fixing-the-server&quot;&gt;Fixing the server &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/codelab-fix-sneaky-404/#fixing-the-server&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This project uses an &lt;a href=&quot;https://expressjs.com/&quot; rel=&quot;noopener&quot;&gt;express.js&lt;/a&gt; server written in
JavaScript. Let&#39;s fix the server, so it responds with index.html and the single
page app will take care of the rest.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Remix to Edit&lt;/strong&gt; to make the project editable.&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;server.js&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This file contains the server code. It sets up an express.js server and sends
the content of index.html. The route setup in line 15 only serves the web app
when requests go to the URL &lt;code&gt;/&lt;/code&gt;. The server should also serve the other URLs we
have created. Let&#39;s change this to serve all URLS, so it also works with
additional URLs in the future.&lt;/p&gt;
&lt;p&gt;To do so, we can change the code starting at line 15 to this:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/*&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;/views/index.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;/*&lt;/code&gt; matches any URL and the server now responds with the web app in
&lt;code&gt;index.html&lt;/code&gt; for any given URL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To preview the site, press &lt;strong&gt;View App&lt;/strong&gt;. Then press
&lt;strong&gt;Fullscreen&lt;/strong&gt;
&lt;img src=&quot;https://web.dev/images/glitch/fullscreen.svg&quot; alt=&quot;fullscreen&quot; style=&quot;padding: 4px 8px; opacity: .5; border: 1px solid #c3c3c3; border-radius: 5px; margin-top: 0;&quot; /&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Refreshing and opening the links in a new incognito window should now work as
expected.&lt;/p&gt;
</content>
    <author>
      <name>Martin Splitt</name>
    </author>
  </entry>
</feed>
