Most technical SEO checklists were written for server-rendered pages and quietly stopped matching how sites get built. The items that actually break modern applications are specific and documented: fragment-based routing that Googlebot cannot resolve, canonical tags injected by JavaScript, single page apps returning a 200 status for error screens, content hidden behind APIs Googlebot does not support, resources blocked in robots.txt that prevent rendering entirely, and asset bundles that run past Google’s published fetch limits. This checklist covers the crawl, render, and index phases in the order they happen, names the failure each item prevents, and ends with the verification steps that belong in a release process rather than a quarterly audit.
A development team ships a rebuild on a modern framework. Lighthouse scores are excellent, the design is a clear improvement, and the code is genuinely better than what it replaced. Six weeks later, traffic is down forty percent and nobody can find a cause, because every conventional check passes. The pages load. The content is there. It is there in the browser, anyway.
Nearly every version of this story traces to the same root: the gap between what a browser does for a user and what a crawler does for an index has widened, and most technical SEO checklists never got updated to reflect it. What follows is organized around how Google’s systems actually process a page, with the specific published rules that modern builds violate most often.
Start from the three phases, not from a list of tags
Google documents its pipeline as three sequential stages: crawling, rendering, and indexing. Treating them as one step is the source of most confusion, because a page can pass the first and fail the second without any visible symptom.
Rendering happens in an evergreen version of Chromium, which is why the old advice about ancient browser support no longer applies. The important detail is the queue. Pages that return a 200 status get queued for rendering, and the wait varies. Pages returning other status codes may skip rendering altogether. Anything your application only produces after JavaScript executes is therefore not indexed at crawl time; it waits, and it is indexed only if the render succeeds.
That single fact reorders the priorities in any technical SEO checklist. Content present in the served HTML is indexed on the first pass with no dependencies. Content assembled client-side depends on a render that has a queue in front of it and several documented ways to fail. Neither is forbidden, but they are not equivalent, and choosing between them is an architectural decision made early, which is why we settle it during scoping on the website development projects we take on rather than diagnosing it after launch.
The rendering checklist
This is the part of a technical SEO checklist that has changed most since the last time yours was written. These are the JavaScript SEO items Google states explicitly, each one a documented rule rather than a best-practice opinion. Every row below has broken a real launch somewhere.
| Check | The rule | What breaks without it |
|---|---|---|
| Routing | Use the History API, not URL fragments | Googlebot cannot reliably resolve routes, so pages are never discovered |
| Canonicals | Do not use JavaScript to change a canonical to a different value than the served HTML | Conflicting signals about which URL is authoritative |
| Web components | Google flattens shadow DOM and light DOM; use slot elements | Component content missing from rendered HTML entirely |
| Connections | Googlebot uses HTTP requests only, not WebSockets or WebRTC | Live-updated content never appears to the crawler |
| State | Local storage, session storage, and cookies are cleared across page loads | Anything gated behind remembered state renders empty |
| Permissions | Expect Googlebot to decline user permission requests | Location-gated or camera-gated content stays blank without a fallback |
The state row deserves emphasis because it catches sophisticated teams. Google’s Web Rendering Service does not retain state across page loads, so a personalization layer that reads a stored preference before deciding what to display will show the crawler whatever the empty case renders. Feature detection with a real fallback is the documented answer, and the fallback needs to contain the actual content rather than a spinner.
One item on that list is safe and worth using: setting titles and meta descriptions with JavaScript is explicitly supported. The distinction is that descriptive metadata can be written client-side, while directives about identity and indexing should not contradict what the server sent. Getting that boundary right on component-driven sites is a recurring part of the builds documented in our development portfolio, because framework metadata APIs make it very easy to do both in the same file without noticing which is which.
The status code checklist
No technical SEO checklist survives contact with a modern app unless it covers this. Single page applications broke HTTP status codes as a side effect of their architecture, and the consequences are worse than they look. The router resolves an unknown path, the framework renders an error component, and the server, which was never asked, returns 200 for all of it.
Google’s own documentation warns that this pattern results in error pages being indexed and possibly shown in search results.
Google documents two acceptable fixes and neither is complicated. Perform a JavaScript redirect to a URL where the server genuinely responds with a 404, or inject a robots meta tag with noindex when the error state renders. Either one turns an invisible indexing problem into a correct signal. Skipping both leaves your index populated with “page not found” screens competing against your real content.
The same discipline applies to every non-success state a modern app produces: expired listings, out-of-stock products, gated content, and maintenance screens. Each needs a deliberate decision about what status the server returns and whether the URL should stay indexable. Auditing those states across a large catalogue is tedious and highly repeatable, which is why it sits in the crawl phase of the SEO engagements we run rather than being left to spot checks.
The byte budget almost nobody checks
This is the item missing from every technical SEO checklist written before bundlers. Google publishes hard limits on how much of a file it will fetch, and modern build output has grown enough that they are no longer theoretical.
Googlebot’s documented fetch limit for a supported file type, with 64MB allowed for PDFs. The limit applies to uncompressed data, individual CSS and JavaScript resources are each subject to it, and when the threshold is reached Googlebot stops the fetch and sends only the already downloaded portion for indexing consideration.
Three details in that paragraph matter for developers. The limit is measured uncompressed, so your gzip or Brotli numbers are not the ones being counted. Resources referenced in the HTML are fetched separately and each carries its own limit, so a single oversized bundle can be truncated while everything else fetches cleanly. And truncation is silent: nothing errors, the partial file is simply what gets considered.
Practically, that turns bundle size into an indexing concern rather than only a performance one, and it hits hardest on the exact patterns modern teams favor: everything in one chunk, inlined data payloads, and generated pages that embed large serialized state. Measuring uncompressed output as part of the build, and treating a growing bundle as a crawl risk, is the kind of item that belongs in a technical SEO checklist a developer will actually run, which is how we structure the audits described in the methodology we work through at the start of an engagement.
The asset and caching checklist
Two documented behaviors around assets cause problems that look like content problems, and both belong on any modern website technical SEO review.
Blocked resources break rendering, not just crawling. Google states plainly that it will not render JavaScript from files or pages blocked in robots.txt. A disallow rule covering a build directory, an API path that supplies page content, or a CDN subdirectory does not merely hide those files. It removes the ability to render the pages that depend on them, which presents as thin or empty content with no obvious cause.
Fingerprint your filenames. Google’s guidance is direct: the Web Rendering Service may ignore caching headers and use outdated resources, so embed a content fingerprint in the filename in the style of main.2bb85551.js. Most modern bundlers do this by default, which means the risk sits with hand-maintained scripts, third-party embeds, and legacy files that survived the migration. A stale cached script is a particularly nasty failure because the site works perfectly for every human who visits it.
Lazy loading belongs here too, following Google’s published guidance rather than a homemade implementation, since content that only loads on a scroll event a crawler never fires is content that does not exist as far as the index is concerned. The pattern of a site that ranks respectably yet somehow underperforms its content library shows up often in the recoveries collected in our SEO portfolio, and the cause is usually one of these three asset-level issues rather than anything in the writing.
The multi-market checklist
Any application serving more than one language or region adds a set of technical SEO checklist items that framework routing makes deceptively easy to get wrong.
Each language version needs its own crawlable URL rather than a variant swapped in by script or cookie, since the crawler carries no remembered locale between page loads. Annotations between versions have to be reciprocal, with every version pointing at every other including itself, and self-referencing canonicals pointing at the version they sit on rather than at a default locale. Automatic redirection based on detected location is the most common self-inflicted wound, because a crawler arriving from one place gets bounced to one version and never sees the others.
The failure mode here is quiet and expensive: several complete translations exist, cost real money to produce, and only one of them is ever indexed. Untangling that after launch means auditing every annotation pair across every route, which is why we build the URL and annotation scheme before any translation work starts in the multi-market search programs we run.
Verification that belongs in the release, not the audit
Every item on this technical SEO checklist is checkable before a deploy, and almost none of them are checked before a deploy. That timing gap is the difference between a five-minute fix and a two-quarter recovery.
The single highest-value habit is reading rendered HTML rather than source. Google’s URL Inspection tool and Rich Results Test both show what the renderer produced, and comparing that output against what you expected settles most arguments instantly. If the text you are counting on is absent from the rendered HTML, nothing further needs debugging until that changes.
A development pipeline drawn left to right in four gates. At the pull request gate, automated checks: uncompressed bundle size against the fetch limit, presence of title and meta tags in server output, and no robots directives accidentally committed. At the staging gate, manual checks: rendered HTML contains the body content, error routes return the right status, and staging itself is protected by authentication rather than a robots rule. At the release gate, spot checks on templates that changed. After release, monitoring: crawl statistics and indexing reports read weekly for the first month. A thin dotted line runs backwards from the monitoring box to the pull request box, labeled as the loop most teams never close.
Staging protection deserves its own line because the usual approach is wrong. Blocking a staging environment in robots.txt does not reliably keep it out of an index, and it creates the additional problem of hiding any directives on those pages from crawlers that reach them another way. Authentication is the dependable defense, and it costs one configuration line.
What turns this from documentation into practice is ownership. When these checks live with the developers who can fix them, in the pipeline where the code already runs, they get done. When they live in a quarterly report delivered to marketing, they get read and forwarded. Which of those two arrangements a client already has is one of the first things we look at, and it explains a fair amount of what clients say makes working with us different from a vendor who reports problems without ever touching the release process.
How much of this applies to you
Not every item on a technical SEO checklist carries equal weight for every build, and pretending otherwise is how checklists get abandoned. A statically generated marketing site with server-rendered content can skip most of the rendering section and should spend its attention on status codes and assets. A client-rendered application behind a router needs every line of it.
Catalogue size changes the calculus too. A site with forty pages can be verified by hand in an afternoon; a site with forty thousand needs the automated gates, because manual verification will not happen twice. Regulated and technical sectors add their own constraints on top, from documentation formats to accessibility requirements that interact with markup decisions, which is why the checklist gets weighted differently across the industries we build search programs for rather than applied identically.
There is one more variable worth naming, which is who owns the fix. A rendering problem is a code change, a status code problem is usually a routing change, and a robots directive is a configuration change, so all three sit with engineering. That is unusual in a discipline where most findings historically landed on a content team, and it is the practical reason these items go unfixed for so long: they get discovered by people who cannot merge the change and reported to people who did not know they owned it.
The through-line is simple enough to state in one sentence. Modern frameworks made it trivial to build things a browser handles beautifully and a crawler cannot see at all, and technical SEO for developers is now mostly the work of noticing that gap before it ships.
Frequently Asked Questions
Can Google index a JavaScript-rendered site properly?
Yes, with conditions. Google renders using an evergreen version of Chromium, but rendering happens in a queue after crawling, and it fails in documented ways: blocked resources, unsupported connection types, state that does not persist across page loads, and declined permission requests. Server-rendered content skips all of that. Client-rendered content works when the known failure modes are handled deliberately.
Why is my single page app getting error pages indexed?
Because the server returns a 200 status while the router renders an error component, which Google treats as a real page. The documented fixes are to perform a JavaScript redirect to a URL that genuinely returns 404, or to inject a robots meta tag with noindex when the error state renders. Without one of the two, “not found” screens compete with your actual content in the index.
Is there a file size limit for crawling?
Yes. Google documents a fetch limit of the first 2MB of a supported file type and the first 64MB of a PDF, measured on uncompressed data. Referenced resources such as CSS and JavaScript are fetched separately and each carries its own limit. When the threshold is hit, Googlebot stops the fetch and only the already downloaded portion is considered, with no error surfaced.
Should I set canonical tags with JavaScript?
Avoid changing a canonical with JavaScript to a value different from the one in the served HTML, which Google advises against directly. Titles and meta descriptions are explicitly fine to set client-side. The useful boundary is that descriptive metadata can be written by script, while directives about which URL is authoritative should come from the server and stay consistent.
Does blocking scripts in robots.txt hurt anything?
Considerably. Google will not render JavaScript from blocked files or blocked pages, so a disallow rule covering a build directory or a content API does not just hide those files, it prevents the pages that depend on them from rendering. The symptom looks like thin or empty content, which sends teams rewriting copy instead of checking a robots rule.
How do I check what Google actually sees?
Read the rendered HTML rather than the page source, using the URL Inspection tool or the Rich Results Test. Both show the output after rendering. If the content you expect is missing there, that is the whole problem and nothing else needs investigating until it appears. Making this a pre-release step rather than an audit finding is the highest-value habit in this checklist.
What is the right way to keep a staging site out of search?
Authentication. A robots.txt disallow does not reliably prevent indexing and additionally hides any directives on those pages from crawlers that find them through other links. Requiring a login is the dependable option and takes one configuration change, which is a better trade than discovering a staging domain competing with production.
Do web components cause indexing problems?
They can, and the fix is specific. Google flattens the shadow DOM and light DOM when rendering, so content has to end up in the rendered output to be indexed. Using slot elements correctly is the documented approach. Verifying it takes one look at rendered HTML for a page built from those components.
How often should this checklist run?
The automatable parts should run on every pull request, since bundle size, missing metadata, and stray robots directives are all cheap to test. The manual parts belong at the staging gate for any release touching templates, routing, or rendering. A periodic full pass still has value for drift, but it should be catching very little if the gates are doing their job.
Skyfield Digital will run this checklist against your build, in staging or in production, and hand your developers a prioritized list of what actually needs changing.
Sources
| Google Search Central | Understand the JavaScript SEO Basics |
| Google Search Central | Fix Search-Related JavaScript Problems |
| Google Search Central | Googlebot: File Size Limits and Crawler Behavior |
| Search Engine Land | Google Lists Googlebot File Limits for Crawling |
| Google Search Central | Tell Google About Localized Versions of Your Page |
| Google Search Console Help | URL Inspection Tool |