Allow crawlers by default, and block only with a written reason
A robots.txt file should allow every crawler by default and disallow a path only where somebody has written down why. Disallow controls fetching, not indexing: a blocked URL can still be indexed from an external link, and because the crawler never fetches it, a noindex tag on that page is never seen.
Disallow and noindex are therefore alternatives, not belt and braces: a page that must stay out of the index stays crawlable and carries noindex, while a disallowed path may still surface as a bare listing. Our own robots.txt disallows nothing — the legal pages carry noindex, and a disallow rule we once had would have stopped the tag ever being read. The confusion with llms.txt has its own piece, llms.txt is not robots.txt.
- Fetch your own robots.txt and read it as a crawler would.
- Allow every user agent unless a written commercial reason says otherwise.
- Use noindex, not disallow, for a page that must stay crawlable but unindexed.
- Name the AI crawlers you allow — GPTBot, ClaudeBot, PerplexityBot — so removing one is a decision.
- Test the file against a live URL after every edit.
Render anything that must be indexed or quoted on the server
Content that exists only after client-side JavaScript runs is content some fetchers never see. Googlebot renders JavaScript later and with limits; AI retrieval crawlers largely do not render it at all. Anything that must be indexed or quoted — copy, headings, structured data, canonical tags — belongs in the HTML the server sends.
Static generation or server rendering is the plain fix. The test is cheap: fetch a page with a tool that does not execute scripts and compare it with what a browser shows; wherever the two differ on something that matters, that content is at the mercy of a render queue. Client-side rendering remains fine for a scheduler or a calculator that nobody needs to index. This site is built that way, every page generated at build time.
Settle on one URL per page and one language per URL
Every page should have one canonical URL that returns 200, declares itself as canonical, and is the only address the site links to. Choosing www or the apex domain, and HTTPS over HTTP, is a decision made once and enforced with a permanent redirect. Where a site has several languages, each language gets its own URL.
A canonical tag that points at a URL which redirects is a contradiction: the page says the true copy lives elsewhere, and elsewhere says it has moved. The same goes for trailing slashes, letter case and query strings — pick a form, redirect the rest, and make internal links, sitemap and canonical agree. Hreflang annotations must be reciprocal and self-referencing, and redirecting visitors by IP address hides the alternatives from crawlers, which arrive from one country.
Large sites mint their own thin and duplicate pages — facets, sort orders, session parameters, near-identical variants — and each address dilutes one intent. Canonicalise, noindex or stop generating them, and point internal links at the owner rather than the variant. Crawl budget is the wrong frame for most of this: Google's own guidance on it is addressed to very large sites, and at a few thousand pages what a log-file review turns up is almost always duplication rather than budget.
Generate the XML sitemap from the same source as the pages
An XML sitemap should list only URLs that exist, return 200, and are meant to be indexed — no redirects, no noindexed pages, no planned pages that are not yet live. The reliable way to guarantee that is to generate the sitemap from the same source that generates the pages, so the two cannot drift apart.
A hand-maintained sitemap is a list of good intentions: entries lag additions and outlive removals, and every crawler that trusted the file gets a 404. This site's sitemap is built from the content registries that build the pages — a service page is listed because, and only because, its data exists — and the noindexed legal pages are left out on the same basis. That is a practice we describe, not a result we claim.
Redirect in one hop, and map a migration URL by URL before the switch
A redirect should resolve in a single hop to a URL that returns 200, and a migration should be mapped URL by URL before anything is switched. Crawlers follow a chain only so far before giving up, and a migration without a map sends old pages to the homepage or a 404, discarding what they had earned.
Redirecting an entire old site to the new homepage is the failure we see most often, and engines treat it much as a soft 404: the destination has nothing to do with the source, so nothing is passed along. The map is tedious and there is no shortcut. Chains accumulate over successive redesigns, each layer redirecting to the last, so part of any migration is flattening the previous ones.
- Crawl the old site and export every URL before anything changes.
- Give every URL with traffic, links or rankings a named destination.
- Return 410 for pages with no equivalent rather than redirecting them somewhere unrelated.
- Test the redirect rules on staging against the full exported list, not a sample.
- Record a field-data baseline before the switch, so a regression can be proven new.
Read Core Web Vitals from field data and judge the work on conversion
Core Web Vitals should be read from field data — measurements collected from real visitors — and assessed per template against Google's published thresholds. They are a genuine ranking signal and a weak one, deciding between otherwise comparable pages. The work is worth doing as a conversion project, with the ranking effect treated as a side benefit.
Search Console groups URLs that share a failing pattern, so ask which template fails on which metric, not which page. A lab run on a fast machine will pass a page that real visitors on cheaper devices experience as broken; where the two disagree, the field data counts. The heaviest cost is usually third-party scripts nobody owns as a total, so start with an inventory of every external tag. Field data accumulates slowly; put the verification date in the diary.
Mark up only what the visible page already says
Structured data should describe what the visible page says and nothing more. An Offer node with no visible offer, a Review node with no reviews, a rating you cannot substantiate, or a LocalBusiness node for a city with no office are claims made to machines that the page does not make to people, and they invite manual action.
Validate the markup whenever it changes and watch the enhancement reports in Search Console afterwards, because one template edit can silently drop a property from every page at once. Link the nodes into one graph with stable identifiers — the organisation, the website, the page — rather than fragments that each describe the company differently. Our own site emits a LocalBusiness node only for the one city where it has a transcribed address, and nothing for the cities it serves remotely.
Keep a change log so a drop can be traced to a deploy
Technical SEO needs monitoring because its failures are silent: a robots.txt edit, a canonical change or a dropped rendering step produces no error, only a decline that surfaces later. Server logs show what crawlers actually fetch, index coverage shows what an engine kept, and a change log ties any drop to the deploy that caused it.
Logs are the only record of what a crawler did: which user agents arrive, where they spend their requests, and whether they reach the pages that matter or a parameter swamp. Index coverage is the other half — what was kept, what was excluded, and the stated reason. The change log is the cheapest: every deploy, template change, redirect rule and robots.txt edit gets a dated line, so that when traffic moves, what shipped that week is a lookup rather than a guess.
Takeaways
- Allow crawlers by default; a disallowed page never shows its noindex, so the two are alternatives.
- Anything that must be indexed or quoted belongs in the HTML the server sends.
- One canonical URL per page, returning 200, and a sitemap generated from the same source as the pages.
- Core Web Vitals are a conversion project read from field data, with ranking as the side effect.
- Mark up only what the page visibly says, and keep a change log so a drop traces to a deploy.
Questions
Does blocking a page in robots.txt stop it being indexed?
No. A robots.txt disallow stops a crawler fetching the page, not an engine indexing the URL. The address can still be listed from external links, and a noindex tag on the page is never seen because the crawler never loads it. To keep a page out of the index, leave it crawlable and use noindex.
Do Core Web Vitals affect rankings?
Yes, weakly. Core Web Vitals are a confirmed ranking signal, but they act as a tie-breaker between pages of similar relevance and authority rather than lifting a page above a better one. The stronger case for the work is conversion: slow loading and shifting layouts lose visitors directly, whatever the ranking effect is.
Should a JavaScript site be server-rendered for SEO?
Yes, for anything that must be indexed or quoted. Search engines render JavaScript later and with limits, and most AI retrieval crawlers fetch raw HTML without executing scripts, so copy that only appears after hydration may never be seen. Render the substance on the server or at build time and hydrate the interactive parts afterwards.
How often should an XML sitemap be updated?
Every time a page is added, removed or moved — so generate the sitemap from the same source as the pages rather than editing it by hand. A sitemap that lists a URL returning 404, or omits one that has gone live, is wrong from that moment; a lastmod date only helps if it is true.
What is the difference between a canonical tag and a redirect?
A redirect moves the visitor: the old URL stops serving content and sends everyone to the new one. A canonical tag leaves both pages serving and tells engines which to treat as the original. Use a redirect when a page has moved; use a canonical when two working URLs show the same content and one should win.
In this series
Related services
More reading
- How to measure who gets cited: a 12,000-prompt methodology
- llms.txt is not robots.txt — and treating it that way costs you citations
- The answer-first rewrite: a 50-word pattern that wins snippets
- Why your Shopify feed is invisible to shopping agents
- Best SEO practices for 2026: the ten that still decide rankings
- On-page SEO best practices: what a page must do to be the best answer
- SEO best practices for AI search: getting cited by ChatGPT, Claude and Perplexity
- Outdated SEO practices: what to stop doing in 2026, and what replaced each one
