Technical SEO: the complete guide and checklist for 2026

Back to blog

You can have the best content in your industry and a handful of enviable links and still not show up. If Google can't reach your pages, doesn't understand them, or decides they're not worth storing, none of the rest matters. That invisible layer —the one that decides whether your site is even a candidate to rank— is technical SEO.

This guide covers everything we review in a technical audit, in the same order we review it, with the mistakes we find over and over and how to fix them. It applies whether your site runs on WordPress or is custom-built.

What technical SEO is (and isn't)

Technical SEO is everything that lets a search engine find, crawl, understand and index your site without obstacles. It doesn't deal with what you say or who links to you: it makes sure nothing prevents those two things from counting.

The most useful way to frame it is as a three-tier pyramid:

  1. Technical. Your pages are accessible, indexable and understandable. The foundation.
  2. Content. They answer what people search for better than the rest.
  3. Authority. Others vouch for you with links and mentions.

The order matters because the upper tiers don't compensate for the lower ones. An excellent article on a noindex URL is worth nothing. A link from a major publication pointing at a page that returns a 404 evaporates. Conversely, fixing the foundation multiplies what you already have: it's the kind of work whose results show up across every page at once.

It's worth saying what technical SEO isn't, too. It isn't "adding keywords", or installing a plugin and calling it done, or chasing 100 across every metric. It's plumbing work: finding where the water leaks and sealing it.

The chain: discover, crawl, index, serve

Almost any technical SEO problem can be placed in one of these four links. Identifying which one is broken saves weeks of misdirected work:

StageWhat happensWhat breaks itWhere you see it
DiscoverGoogle learns the URL existsOrphan page, no links or sitemapIndexing report
CrawlGooglebot visits and downloads itrobots.txt, 5xx errors, extreme slownessCrawl stats, logs
IndexIt decides to store itnoindex, duplicates, thin content, canonical elsewhereIndexing report
ServeIt shows it for a queryRelevance, authority, page experiencePerformance report

An example of why this matters: when a page doesn't show up in Google, the usual reaction is to rewrite the content. But if the problem sits in the "crawl" link, you can rewrite it ten times and nothing will change. Diagnose the link first, act second.

Crawling: letting Google in

robots.txt

A text file at the root of your domain that tells crawlers where not to go. Simple, powerful and dangerous: one misplaced line can wipe you off the map.

User-agent: *
Disallow: /wp-admin/
Disallow: /cart/
Disallow: /*?orderby=
Allow: /wp-admin/admin-ajax.php

Sitemap: https://yourdomain.com/sitemap.xml

Three rules that prevent most disasters:

  • Never block CSS or JavaScript. Google needs to render the page the way a user sees it; hide your styles and it may conclude your site isn't mobile-friendly.
  • robots.txt doesn't deindex. It blocks crawling, not appearance in results. We'll come back to this because it's mistake number one.
  • Check the production file, not the one on your laptop. The Disallow: / that protected the staging environment and shipped to production by accident is a classic that still ruins launches.

Crawl budget

Crawl budget is the resources Google devotes to crawling your site. Before you worry: if your site has fewer than a few thousand URLs, this isn't your problem. Google will crawl everything without difficulty and your time pays off better elsewhere.

It starts to matter on large catalogues, portals and ecommerce sites with filters. What wastes it is almost always the same:

  • Facets and combinable parameters, generating millions of equivalent URLs (?color=blue&size=m&sort=price).
  • Infinite pagination or calendars creating pages up to the year 2099.
  • Redirect chains, where each hop consumes a crawler visit.
  • Intermittent 5xx errors, which make Google slow down out of caution.

Capacity and demand: the two forces behind it

Crawl budget isn't a number Google assigns by lottery: it comes from two things you can influence separately.

  • Crawl capacity. How much Googlebot is willing to ask of you without causing harm. It works this out by measuring your response times and your errors: if the server answers fast and consistently, it raises the number of parallel connections; if responses start taking over a second or returning 5xx and timeouts, it throttles immediately so as not to knock you over. Slow hosting doesn't just cost you Core Web Vitals: it cuts your crawling.
  • Crawl demand. How keen it is to come back. This depends on how popular the URL is (links it receives) and how fresh it is (how often it genuinely changes). A news homepage gets crawled every few minutes; a legal notice untouched since 2019, a couple of times a year.

Hence the practical conclusion: speeding up the server and removing noise raises the budget available, and internal linking decides how it gets spent.

Taming faceted navigation

On an ecommerce site, most of the waste comes from filters. There's no single fix: each kind of parameter needs its own treatment.

Parameter typeWhat to doHow
Sorting (?sort=price)Consolidate authorityCanonical to the category without parameters
Pagination (?p=2)Let the first ones be crawledSelf-canonical and indexable; consider a depth limit
Single filter with demand (/running-shoes)Turn it into a real pageClean URL, own title, content and a link from the category
Single filter with no demand (?color=blue)Stop it generating a URLApply it in JavaScript without changing the URL, or block it
Combined filters (?color=blue&size=42&sort=price)Block at the perimeterDisallow in robots.txt on the full pattern

A framework that helps on large sites is classifying every URL template into one of four categories before touching anything:

  1. Priority indexable: what generates revenue or captures demand. Should be crawled often and linked from high up.
  2. Supporting indexable: content that props up the above without being the target itself.
  3. Crawlable but not indexable: pages internal linking flows through but which add nothing in results. They carry noindex and stay crawlable.
  4. Blocked: pure noise (combined facets, internal search, sessions). Disallow in robots.txt.

If a template fits none of them, it usually shouldn't exist.

Log analysis: the only source that doesn't estimate

Tools simulate; Search Console aggregates and samples; logs record. Your server's access log (access.log on Apache or NGINX) notes every request with its exact timestamp, source IP, user-agent, requested URL, response code and bytes served. It's the only place you see what Googlebot actually did, rather than what a tool thinks it would do.

It's also, by a distance, the most profitable diagnosis on large sites. And since AI search engines started crawling on their own account, it has stopped being a niche technique: it's the only way to know whether ChatGPT, Claude or Perplexity come through your site.

The usual approach is a 30 to 90 day window —anything less won't give reliable patterns— using Screaming Frog Log File Analyser, a Kibana or Splunk stack if you already run one, or straight from the terminal.

What to look for, in five steps

1. Isolate and verify the bots. First you filter out human traffic and keep the crawler user-agents. Then —and this is the step almost everyone skips— you verify they are who they claim to be: spoofing a user-agent is trivial, and a share of the traffic presenting itself as Googlebot is scrapers. The check is a reverse DNS lookup: the IP must resolve to a search engine domain, and that domain must resolve back to the same IP.

# Most-crawled URLs by Googlebot, ordered by number of hits
grep "Googlebot" access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -50

# Verifying an IP really belongs to Google
host 66.249.66.1        # → crawl-66-249-66-1.googlebot.com
host crawl-66-249-66-1.googlebot.com   # → must return 66.249.66.1

2. Measure the waste. Group requests by URL pattern and look at the split. The result is usually uncomfortable: a huge share of crawling goes on stale JavaScript, filter parameters and obsolete redirects, while the directories that make money get one visit a month. That percentage is the metric that justifies all the robots.txt and canonical work from the previous section.

3. Find the orphan pages. Cross-reference the URLs appearing in your logs against what a crawler discovers by following links. Anything in the logs but not in the crawl is orphaned: it exists, Google remembers it, but no internal path leads there. Then you decide: if it adds nothing, remove it with a 410; if it has traffic or external links, bring it back into the architecture by linking to it properly, and you recover authority you already had.

4. Catch the failures you can't see cold. A simulated audit makes slow, orderly requests any server can handle. Logs show what happens under real load: 302s where there should be 301s, chains eating through the crawler's tolerance, sporadic 500s at particular hours, and 429s telling Googlebot to stop asking. A 5xx spike at 3 a.m. coinciding with the backup shows up nowhere else.

5. See what the AI bots take. Segmenting crawl activity by user-agent reveals which sections each one prefers. That's actionable: if AI crawlers keep coming back to your glossary, your comparison tables or your documentation, that's the structure they're using to answer, and it's worth replicating across the rest of the site.

User-agentWhose it isWhat it crawls for
GooglebotGoogleSearch index and AI Overviews
Google-ExtendedGoogleGemini training (doesn't affect the index)
BingbotMicrosoftBing's index, the basis for Copilot
GPTBotOpenAIModel training
OAI-SearchBotOpenAIChatGPT's search index
ChatGPT-UserOpenAILive visit while answering a user
ClaudeBotAnthropicTraining and index
PerplexityBotPerplexityCitation index

The distinction matters when deciding: blocking GPTBot limits your content being used for training, but blocking OAI-SearchBot removes you from ChatGPT's answers outright. They aren't the same decision.

Indexing: making Google want to store it

noindex vs. robots.txt: the costliest mistake

It deserves its own section because we see it constantly and its logic is counter-intuitive:

  • Disallow in robots.txt says: don't visit this page.
  • <meta name="robots" content="noindex"> says: visit it, but don't store it.

Do both at once and you get the paradox: Googlebot doesn't visit the page, therefore never reads the noindex, and the URL can keep appearing in results —with no description, with a title pulled from the links pointing at it. That familiar "Indexed, though blocked by robots.txt" in Search Console is born right here.

The correct order to remove a page from the index:

  1. Allow crawling.
  2. Add noindex to the page (or an X-Robots-Tag header if it's a PDF or another file type).
  3. Wait for it to drop out of the index.
  4. Only then, if you want to save crawl budget, block it in robots.txt.

What Search Console statuses actually mean

The indexing report is your dashboard, but its labels are cryptic. A practical translation:

StatusWhat it really meansWhat to do
Discovered – currently not indexedGoogle knows about it but hasn't visitedLink it internally, review crawl budget
Crawled – currently not indexedIt visited and decided it adds nothingQuality or duplication issue, not technical
Duplicate, Google chose different canonicalIt ignored your canonicalConsolidate content or reinforce signals
Alternate page with proper canonical tagAll correct, it's a variantNothing, this is expected
Excluded by noindex tagWorking as intended… if it was intendedCheck it isn't an oversight
Page with redirectNormal on old URLsMake sure they aren't chains
Server error (5xx)Urgent: Google reduces crawlingCheck hosting and logs
Soft 404Returns 200 but looks emptyReal content or an honest 404

What shouldn't be indexed

Almost every site carries pages in the index that only dilute it. Check these suspects:

  • Internal search results (/?s=...): they generate endless low-quality pages.
  • Carts, checkout and "thank you for your order" pages.
  • Staging and test environments, especially when they're publicly reachable subdomains.
  • Empty or near-empty tags and categories in WordPress, a classic duplicate factory.
  • PDF versions of content that already exists in HTML.
  • Form thank-you pages, which distort your conversion data if indexed.

Rendering: what Googlebot actually sees

This is the area that has changed most over the last decade and the one most guides cover worst, still written on the assumption that every site is HTML served by a classic CMS.

Googlebot processes pages in two waves. First it downloads the HTML and extracts whatever is in it. If the content depends on JavaScript, the page joins a render queue waiting for available resources to execute it: that can take hours or weeks, and if the scripts take too long or fail, the second wave simply never arrives. Anything depending on it arrives late and competes worse.

The detail almost nobody mentions is that AI crawlers are far less patient than Google. Google at least has a render queue; most language-model bots read the HTML they're given and leave. A client-rendered site can end up indexed in Google late and, at the same time, completely invisible to ChatGPT or Perplexity.

Which means your architecture has direct consequences:

StrategyWhat the bot sees on the first passTTFBCost at scaleWhen it makes sense
Static (SSG)All the content in the HTMLMinimal, served from CDNVery lowBlogs, corporate sites, services, documentation
Incremental static (ISR)All the content, possibly minutes staleMinimal, cachedVery lowEcommerce, catalogues, portals with changing inventory
Server-rendered (SSR)All the content in the HTMLModerate: computed on every requestRises with trafficPersonalised content or content changing by the second
EdgeAll the content in the HTMLVery low: runs at the CDN nodeMediumCountry personalisation, A/B tests, geolocation
Client-rendered (CSR)An empty <div>Low, but with nothing insideVery lowDashboards and apps behind login: nothing to index

The first three rows solve the problem; the fourth solves it at low latency too. The fifth, for public content, isn't a defensible option in 2026. Pure CSR has its place —an application behind authentication doesn't need indexing— but not on the pages you want to rank.

The most useful middle ground is incremental: static pages with a revalidation window (60 seconds, 5 minutes, whatever the business needs). The bot always gets complete HTML from cache, TTFB stays at a minimum and the database never learns Googlebot exists. For a catalogue with prices or stock that change, it's the most sensible balance.

There are also three patterns Googlebot never resolves, whatever you do:

  • Content that only appears after interaction. The bot doesn't click, doesn't expand JavaScript-loaded accordions, doesn't press "show more". If the text isn't in the DOM after load, it doesn't exist. (An accordion whose content is in the HTML and is merely hidden with CSS does get indexed.)
  • Links that aren't links. A <div onClick="..."> or a <button> that navigates via JavaScript passes nothing along. Internal links must be <a href="/path/">, full stop.
  • Hash-based routes (/#/products), a legacy of early SPAs: to Google that's all one URL.

How to check it in two minutes: use URL Inspection in Search Console and look at the rendered HTML tab; if your text isn't there, Google doesn't have it. For a quick check, curl https://yourdomain.com/page returns the raw HTML with no JavaScript: roughly what the first wave sees.

In our case, this is one of the reasons we work with static generation: the content is in the HTML from the first byte, and there's no second wave to depend on. We compare both approaches in detail in Next.js vs WordPress.

Architecture, URLs and internal linking

Click depth

Count how many clicks it takes to get from the homepage to each page. The deeper it sits, the less authority it receives and the less it gets crawled. The rule of thumb —nothing important more than three clicks away— isn't dogma, but it's a good problem detector: if your flagship service sits five clicks deep, your architecture is working against you.

Orphan pages

These receive no internal links at all. They exist, they may even be in the sitemap, but no path leads to them. Google treats them as irrelevant by omission: if you don't link to them, why would they matter? Find them by cross-referencing your sitemap URLs against what a crawler discovers by following links.

URLs that make sense

A URL is a promise about content. These rules cover 95% of cases:

  • Short and descriptive: /services/seo/ beats /index.php?p=42&cat=7.
  • Hyphens to separate words, never underscores or encoded spaces.
  • Always lowercase (on many servers /Services and /services are different URLs: instant duplicate).
  • No dates on blogs whose content gets updated: /blog/seo/guide/ ages better than /2026/07/guide/.
  • Stable: changing a URL that already ranks costs traffic. If there's no way around it, 301 and move on.

Internal linking

It's the most underrated lever in technical SEO and one of the few you control entirely. Internal links do three things: they discover new pages, distribute authority, and tell Google what the destination is about through the anchor text.

  • Link with descriptive text, not "click here". The anchor is a topical label.
  • Link from the body of the content, not just from menus and footers: contextual links carry more weight.
  • Link to what you want to rank, not just to whatever you published last.
  • Make sure they don't point at redirecting URLs: every hop dilutes and slows.

Breadcrumbs solve navigation, context and search appearance at once. Mark them up with BreadcrumbList and Google can display the hierarchy instead of a bare URL.

Duplicates and canonicals

The four versions of your domain

Every site is born with four potentially distinct addresses:

http://yourdomain.com
http://www.yourdomain.com
https://yourdomain.com
https://www.yourdomain.com

Only one should return a 200; the other three should 301 to it. Add the trailing slash question (/page vs /page/): pick a convention and stick to it. These are trivial duplicates to fix and surprisingly common.

The canonical tag

<link rel="canonical" href="..."> tells Google which is the good version of content that exists at several URLs. Two nuances almost nobody explains:

  • It's a hint, not an order. Google can ignore it if other signals say otherwise (for instance, if all your internal links point at the URL you declared a duplicate). When that happens you'll see it in Search Console as "Google chose different canonical".
  • It should be self-referencing. Every original page should declare itself canonical, with an absolute URL. That stops campaign parameters (?utm_source=) from creating accidental duplicates.

Common mistakes: canonicals pointing to the homepage from every page (which destroys indexing site-wide), canonicals pointing at redirecting URLs, and relative canonicals that resolve incorrectly.

Pagination

Since Google dropped support for rel="next" and rel="prev", the advice is simple: every page in the series is self-canonical, all indexable, and from page 2 onwards nothing more is needed. What you shouldn't do is canonicalise them all to page 1: that hides everything after it.

Cannibalisation

This happens when several of your pages compete for the same search intent. The result is that none consolidates: Google alternates between them and all of them underperform.

How to spot it: in the Search Console performance report, filter by a specific query and open the pages tab. If three URLs split impressions for the same search, you have cannibalisation.

How to fix it: almost never by deleting. Pick the URL that should win, merge the best of the rest into it, 301 the others and update internal links so they all point at the winner. If the pages actually serve different intents and only the angle overlapped, rewriting titles and headings to separate them is sometimes enough.

Redirects and migrations

A redirect tells the browser and the search engine that content has moved. Choosing the wrong type has consequences:

  • 301 (permanent): the standard for definitive changes. Passes practically all authority.
  • 302 (temporary): only for what's genuinely temporary. Used by mistake in migrations, it keeps the old URL indexed for months.
  • 307/308: modern equivalents of 302 and 301 that preserve the HTTP method. Relevant with HSTS and forms.
  • JavaScript redirects: they work, but they're processed late and unreliably. Avoid them if you can redirect server-side.

Two conditions to hunt down in any audit: chains (A → B → C → D, where each hop wastes time and some signal) and loops, which make the page outright inaccessible.

Minimum migration checklist

Migrations are when most traffic is lost at once, almost always through avoidable oversights:

  1. A 1:1 map of old to new URLs, built before touching anything, from a full crawl of the current site.
  2. Direct 301 redirects, with no intermediate steps.
  3. Keep redirects for at least a year, ideally forever: external links take time to update, or never will.
  4. Update internal links to the final destination instead of letting them route through the redirect.
  5. New sitemap submitted in Search Console on switchover day.
  6. Watch for 15 days: crawl errors, index coverage and the pages that used to bring the most traffic.

Status codes that matter

Every server response is a signal. These are the ones that come up in an audit and how to read them in SEO terms:

CodeMeansSEO reading
200All goodNormal for indexable pages
301Moved permanentlyPasses authority to the destination
302Moved temporarilyKeeps the old URL in the index
304Not modifiedSaves crawl budget, a good sign
404Not foundFine in small doses; at scale, a symptom
410Gone for goodDeindexes faster than a 404
429Too many requestsYou're rate-limiting Googlebot: review
500Server errorUrgent: reduces crawling site-wide
503Service unavailableThe right one for planned maintenance

Special mention for the soft 404: a page returning 200 while showing "no results" or virtually nothing. Google detects and excludes it anyway, but burns crawl budget in the meantime. If something doesn't exist, say so with the right code.

XML sitemaps

A sitemap is a list of the URLs you want Google to know about. It doesn't guarantee indexing, but it speeds up discovery, and on large sites or those with few external links it's decisive.

Rules for a healthy sitemap:

  • Only indexable, canonical URLs that return 200. No noindex, redirects or 404s: a dirty sitemap costs you credibility.
  • Honest lastmod. Bumping the date site-wide every night without changing anything teaches Google to ignore the field.
  • Maximum 50,000 URLs or 50 MB per file; beyond that, split it and use a sitemap index.
  • Segmented by type (pages, posts, products) on large sites: that way the Search Console report tells you which section has problems.
  • Declared in robots.txt and submitted in Search Console and Bing Webmaster Tools.

If you work with Next.js, the sitemap is generated at build time and never goes stale:

// src/app/sitemap.ts
import type { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
    return getAllPosts().map((post) => ({
        url: `https://yourdomain.com/blog/${post.slug}/`,
        lastModified: post.updatedAt,
        changeFrequency: 'monthly',
        priority: 0.7,
    }));
}

Structured data

Structured data is a standard vocabulary (Schema.org) that translates your content into something a machine understands without interpreting: this is a company, this an article, this a price.

It doesn't lift rankings on its own —Google has said so repeatedly— but it changes how you appear and helps search engines understand what entity you are. With the arrival of AI-generated answers, that second effect has gained weight: well-marked-up content is easier to cite.

The types that pay off on most sites:

  • Organization on the homepage: name, logo, social profiles, contact details. The basis of your identity as an entity.
  • BreadcrumbList on every internal page.
  • Article on the blog, with author and published/modified dates.
  • Service or Product, depending on what you sell.
  • FAQPage when there are real questions on the page. Google cut back its display in results, but it still helps comprehension and AI assistants.
  • Person for team profiles, connecting authors to content.

Two mistakes that genuinely hurt: marking up content that isn't visible on the page (grounds for a manual action) and inventing ratings or data. Markup describes what's there; it doesn't replace it.

Always validate with Google's Rich Results Test and the Schema.org validator, which covers more types.

Your site as an entity: sameAs and knowsAbout

This is where markup has changed job. A language model that has to cite a specific fact —a price, an address, a methodology— compares several sources saying the same thing and goes with the one that makes it easy: the one declaring unambiguously what each thing is. JSON-LD has gone from decorating the result to being the route by which a machine identifies you.

That turns two rarely used properties into the most profitable in the vocabulary:

  • sameAs connects your entity to its verified profiles elsewhere: LinkedIn, X, Instagram, GitHub, Crunchbase, your Wikidata item if you have one. It's what tells a model that the company on your site and the one on those profiles are the same, consolidating signals scattered across half the internet into a single place.
  • knowsAbout declares what a person knows about. The interesting part is that it accepts URIs as well as text: instead of writing "SEO" you can point at that concept's Wikidata item (Q180711), and any ambiguity about what you mean disappears. It's the most direct way to translate what Google calls experience and expertise into code.
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://yourdomain.com/#organization",
  "name": "Your Company",
  "url": "https://yourdomain.com/",
  "logo": "https://yourdomain.com/logo.png",
  "vatID": "ESB12345678",
  "sameAs": [
    "https://www.linkedin.com/company/yourcompany/",
    "https://github.com/yourcompany",
    "https://www.wikidata.org/wiki/Q00000000"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "contactType": "customer service",
    "email": "hello@yourdomain.com",
    "availableLanguage": ["es", "en"]
  },
  "founder": {
    "@type": "Person",
    "@id": "https://yourdomain.com/team/#person",
    "name": "First Last",
    "jobTitle": "Technical director",
    "knowsAbout": [
      "https://www.wikidata.org/wiki/Q180711",
      "https://www.wikidata.org/wiki/Q845921",
      "Technical SEO"
    ],
    "sameAs": ["https://www.linkedin.com/in/profile/"]
  }
}

Three rules to make this actually work:

  • A stable @id per entity, with the rest of the markup referencing it. Without identifiers, every page declares a brand new company.
  • Link Article to its author Person, and that Person to a real profile page on your site. An author who only exists as a string inside JSON-LD credentials nothing.
  • Absolute consistency in name, address and phone across the site, the markup and external profiles. A mismatch breaks entity resolution and shows up in no report anywhere.

FAQPage: few questions, short answers

FAQ markup is one of the most useful types for getting an assistant to lift a literal answer, and one of the most abused. Injecting thirty artificial questions that aren't on the page is exactly the pattern search engines have learned to ignore —and to penalise when the markup doesn't match the visible content.

What works:

  • Six to ten questions, taken from what clients actually ask, not from a keyword list.
  • Phrased the way a person would say them to a chatbot: natural, complete language.
  • Two to four sentence answers, with the concrete fact in the first one. No sales padding: if the answer opens with "in our extensive experience", nobody is citing it.
  • Identical to the visible text on the page. Markup documents; it doesn't add.

Internationalisation: hreflang without the headaches

If your site exists in several languages or for several countries, hreflang tells Google which version to show each user. Done right it stops your English version from cannibalising the Spanish one; done wrong it does nothing, or mixes the two.

<link rel="alternate" hreflang="es-ES" href="https://yourdomain.com/servicios/" />
<link rel="alternate" hreflang="en" href="https://yourdomain.com/en/services/" />
<link rel="alternate" hreflang="x-default" href="https://yourdomain.com/servicios/" />

The rules that prevent 90% of failures:

  • Bidirectionality. If A declares B as an alternative, B must declare A. Without reciprocity Google ignores the whole block.
  • Self-reference. Every page includes itself in its own list.
  • Correct codes. Language in ISO 639-1 and optional country in ISO 3166-1 alpha-2, separated by a hyphen: es-ES, es-MX, en-GB. Not es_ES, not es-ESP.
  • Absolute URLs with no redirects or noindex at the destination.
  • x-default for anyone who doesn't match a specific version.
  • Actually translate. Two identical pages with different hreflang are still duplicates.

Performance and Core Web Vitals

Speed is part of technical SEO, but it deserves its own manual: what each metric measures exactly, how to diagnose it and which optimisations have real impact. We cover it in Core Web Vitals 2026: a practical guide.

The summary for this guide: LCP under 2.5 s, INP under 200 ms and CLS under 0.1, measured on real users at the 75th percentile over a 28-day window. They weigh less than content, but they act as a tiebreaker and have a large effect on conversion.

Images: format, weight and comprehension

Images are almost always the heaviest element on a page and, at the same time, the easiest to optimise. On most sites we audit they're the number-one cause of a failing LCP and a constant source of layout shifts. They deserve their own section because they touch three things at once: speed, indexing and accessibility.

Format: WebP and AVIF

Serving JPEG and PNG in 2026 leaves between 25% and 50% of the weight on the table:

  • WebP is today's default: universal browser support for years now, PNG-style transparency and far better compression. A photo weighing 400 KB as JPEG typically lands at 150-250 KB in WebP with the same perceived quality.
  • AVIF compresses further still (another 20-30% over WebP) at the cost of slower encoding. Worth it on image-heavy catalogues.
  • SVG for logos, icons and diagrams: vector, tiny, and scales without losing sharpness.
  • PNG only when you need lossless transparency and WebP doesn't fit; JPEG, as a fallback only.

Conversion doesn't have to be manual. With cwebp you convert and resize in a single command, and batching it is trivial:

cwebp photo.jpg -resize 1080 0 -q 84 -m 6 -o photo-1080w.webp

In a CMS, an optimisation plugin does the same on upload. And in modern frameworks like Next.js, the image component converts and serves the right format per browser without you touching anything.

Real weight and dimensions

The costliest mistake isn't the format: it's serving a 3,000 px image into a 600 px slot. The browser downloads the whole thing and then scales it down, so you pay the full weight and see none of the benefit.

  • Generate several sizes of each image and let the browser choose with srcset and sizes.
  • Set quality around 80-85%: above that, weight climbs sharply and the visual difference is imperceptible.
  • Always declare width and height (or aspect-ratio): that's what reserves the space and prevents CLS.
  • Apply loading="lazy" to below-the-fold images, and never to the LCP image.
<img src="/images/service-828w.webp"
     srcset="/images/service-640w.webp 640w,
             /images/service-828w.webp 828w,
             /images/service-1080w.webp 1080w"
     sizes="(max-width: 768px) 100vw, 50vw"
     width="1080" height="720" loading="lazy"
     alt="Team reviewing a technical SEO audit on screen" />

Making them understandable too

Optimising weight solves speed; the search engine still needs to know what's in the image:

  • Descriptive filenames: technical-seo-audit.webp, not IMG_20260726_final2.webp.
  • Informative alt text on every image that carries content, describing what's shown rather than repeating the keyword. Decorative images take alt="" so screen readers skip them.
  • Surrounding context: nearby text and captions help Google interpret the image.
  • An image sitemap if visual search is a channel for you (fashion, interiors, travel, recipes).

It's one of the few optimisations that improves Core Web Vitals, accessibility, your visitor's data usage and Google Images visibility all at once.

Mobile, HTTPS and accessibility

Mobile-first indexing. Google indexes the mobile version of your site, not the desktop one. If you hide content on mobile "to simplify", that content doesn't count. Check that text, links and structured data are the same in both versions.

HTTPS done properly. A valid, renewed certificate, redirection from HTTP, no mixed content (resources loaded over HTTP inside an HTTPS page) and, if you can, HSTS with TLS 1.3. It's an entry requirement, not an advantage.

Efficient delivery. Check the server serves HTML, CSS and JavaScript compressed with Brotli (or at least gzip) and with sensible cache headers. It's a configuration box that's often left unticked, and it improves LCP and crawl capacity at the same time, because every bot request costs less.

Accessibility. Not a direct ranking factor, but it overlaps so much with technical SEO that they're worth handling together: a descriptive alt on every informative image, a coherent heading hierarchy (a single <h1>, no jumps from <h2> to <h4>), sufficient contrast and full keyboard navigation. What helps a screen reader helps a crawler: both read structure, not design.

More and more searches end in a generated answer rather than a list of links. Industry studies published through 2025 all point the same way: AI summaries now appear on the majority of informational searches —in sectors like health and finance, measured rates run above 80%— with click drops on purely informational queries reaching the high double digits.

The useful reading isn't "traffic is over" but that the intermediary changed. The query that used to end in a click now ends in an answer that cites sources, and being among those sources is largely a technical matter: if a model can't read your HTML, identify who you are and extract a fact unambiguously, it won't cite you. That discipline is called GEO (Generative Engine Optimization), and it rests on three things you've already seen in this guide.

  • Content in the initial HTML. The entry requirement. AI bots don't wait for a second rendering wave.
  • Declared identity. Organization, Person, sameAs, stable @ids. That's what lets a model know the source is you and not an aggregator that copied you.
  • Extractable answers. Question-shaped headings, the fact in the first or second sentence of the paragraph, concrete figures, tables. A paragraph that stands on its own can be cited; one that needs the three before it can't.

On top of that sits the access question, which is now a business decision rather than just a technical one:

  • Decide deliberately who you let in via robots.txt, separating training bots from search bots: blocking GPTBot or Google-Extended limits your content being used to train models; blocking OAI-SearchBot or PerplexityBot wipes you from their answers. Check your CDN firewall too, which sometimes blocks them without anyone deciding to.
  • Publish an llms.txt with a readable map of your site for language models.
  • Check the logs to see whether they're really coming through, and where. It's the only verification that exists.

We go deeper in SEO for AI: how to show up in ChatGPT and Perplexity.

Three cases that show what's at stake

Technical SEO explains badly in the abstract and very well with numbers. These three public cases cover the three costliest failures there are: a migration with no redirects, a site drowning in useless pages, and an ecommerce store blocking itself.

A migration with no redirect map. Property portal ChatVal rebranded in 2024 and shipped its new URL structure without implementing 301 redirects. Around 324,000 pages —a third of the catalogue— started returning 404s, and years of accumulated link authority evaporated with them. After rebuilding the redirect map with regex rules, weekly organic sessions went from 974 to over 12,000 in three weeks (full case). No content plan would have fixed that.

Too many pages, none of them important. Seattle's official tourism portal had accumulated more than 58,000 technical errors and nearly 6,000 thin-content pages, with parameter duplication and severe cannibalisation. The fix wasn't publishing more: roughly 70% of pages were pruned and the broken redirect chains repaired. The result was recovering and then exceeding previous organic traffic levels (full case). Density over volume.

An ecommerce store blocking itself. After migrating its store, Quality Woven Labels lost 33% of its sessions. The audit found four textbook problems: a copy-pasted robots.txt preventing commercial categories from being crawled, thousands of URLs with no canonical, user profiles being indexed for want of a noindex, and a sitemap full of broken URLs. With all of that fixed and without adding a single line of new content, organic revenue rose 118% (full case).

The pattern repeats: in all three, the work was removing obstacles, not producing. That's what makes technical SEO the highest-return investment when something is broken, and also what explains why nobody notices it when it's done right.

How to run a technical audit

The tools

ToolWhat forCost
Google Search ConsoleIndexing, performance, real errorsFree
Bing Webmaster ToolsSecond opinion and Bing/Copilot dataFree
PageSpeed InsightsField and lab Core Web VitalsFree
Rich Results TestValidate structured dataFree
Screaming FrogFull site crawlFree up to 500 URLs
LibreCrawlUnlimited-URL crawling with JS renderingFree, open source
Semrush / AhrefsOngoing auditing, competitors, linksPaid
Screaming Frog Log File AnalyserProcessing logs without fighting the terminalFree up to 1,000 lines
Server logsWhat Google really crawlsIncluded with your hosting

Search Console plus a crawler covers practically an entire diagnosis. Paid suites add tracking over time and competitor comparison.

Crawlers deserve a closer look, since it's the tool you'll use most. Screaming Frog is the industry standard, but its free tier stops at 500 URLs, which a mid-sized site burns through on the first crawl. LibreCrawl is an MIT-licensed open-source alternative with no such cap: it crawls without a URL limit, integrates Playwright to render JavaScript —essential when auditing an SPA built with React, Vue or Next.js— and analyses metadata, hreflang, structured data and social tags. Because you can self-host it, crawl data never leaves your machine, which on client projects is no small detail.

The process, in six steps

  1. Crawl the whole site with Screaming Frog or LibreCrawl and export everything: status codes, titles, canonicals, depth, inbound internal links.
  2. Cross-reference with Search Console: which URLs Google knows about, which it indexed, which it discarded and why.
  3. Check rendering on one template of each type (home, category, product, article) with URL Inspection.
  4. Review the logs for the last 30-90 days: where Googlebot spends its time, which orphan pages surface, and which AI bots are coming in.
  5. Classify findings by which link is broken (discover, crawl, index, serve), not by which tool found them.
  6. Prioritise by impact and effort, and fix in that order.

Prioritise properly

Not all findings are worth the same. This order works in the vast majority of cases:

  1. Blockers: accidental noindex, Disallow in production, 5xx errors, redirect chains on key pages. Fix today.
  2. Structural: duplicates, cannibalisation, architecture and internal linking. Weeks of work, the biggest return.
  3. Refinement: structured data, image optimisation, performance details. Ongoing.

The usual trap is starting at point 3 because it's the easiest to measure, while a forgotten noindex keeps half the site out of the index.

Technical SEO checklist

The actionable summary. If you take one thing from this article, make it this:

Crawling

  • robots.txt reviewed in production, blocking neither CSS nor JS
  • Sitemap declared in robots.txt and submitted in Search Console
  • No recurring 5xx errors in the crawl stats report
  • Average server response time under one second
  • Parameters and facets under control on large sites
  • Every URL template classified: indexable, noindex or blocked
  • Logs reviewed: where Googlebot spends the crawl and which AI bots come through

Indexing

  • No important page carrying noindex
  • Nothing blocked in robots.txt that also carries noindex
  • Utility pages (cart, internal search, thank-you) out of the index
  • Staging environment inaccessible or deindexed
  • Indexing report reviewed monthly

Rendering

  • Key content appears in the rendered HTML in URL Inspection
  • Key content also appears in the raw HTML (curl), not only after rendering
  • All internal links are real <a href> elements
  • Nothing essential hidden behind a user interaction

Architecture

  • Nothing important more than three clicks from the homepage
  • No orphan pages (cross-referencing logs and crawl, not just the sitemap)
  • Short, lowercase, hyphenated, stable URLs
  • Contextual internal linking with descriptive anchors
  • Breadcrumbs implemented and marked up

Duplicates and redirects

  • Only one version of the domain returns 200; the rest 301 to it
  • A single trailing-slash convention
  • Self-referencing, absolute canonicals
  • No redirect chains or loops
  • No cannibalisation on priority queries

Images

  • Served as WebP or AVIF, not JPEG/PNG
  • Multiple sizes via srcset and sizes, no oversized images
  • width and height declared on all of them
  • loading="lazy" everywhere except the LCP image
  • Descriptive filenames and informative alt text

Understanding and experience

  • Organization, Article and BreadcrumbList implemented and validated
  • Stable @ids per entity and sameAs pointing to your verified profiles
  • Articles linked to an author Person with a real profile page on the site
  • FAQPage with real questions, short answers matching the visible text
  • Reciprocal, self-referencing hreflang with x-default if multilingual
  • Core Web Vitals green on field data
  • Same content on mobile and desktop
  • HTTPS with no mixed content
  • A deliberate decision about AI crawlers, separating training from search

How we work at yuGraphik

Our starting point is that technical SEO is inherited from architecture: it's far cheaper to build a site that's born indexable than to fix one that isn't. That's why we work with static generation, complete HTML from the first byte, structured data at template level and a sitemap generated on every build, all served from a CDN.

When we come into an existing project, the order is the one in this guide: full crawl, cross-reference with Search Console, rendering verification and a list prioritised by impact rather than ease. You can see the full approach in our SEO service, and if you'd like us to run this audit on your site, tell us about your project.

Conclusion

Technical SEO isn't the glamorous part of search, but it's the part that decides whether the rest of your work gets to count at all. The good news is that it's finite and verifiable: unlike content or links, here there's a closed list of things to check and each one has an objective state, right or wrong.

Start with the diagnosis, not the fix: work out which link in the chain is broken before touching anything. Fix what blocks first, what structures second, what refines last. And remember that at this layer a single misplaced line can cost more traffic than months of content: which is exactly why it's worth reviewing methodically, and reviewing again from time to time.

Frequently asked questions

What is technical SEO?

Technical SEO is the work that allows a search engine to find, crawl, understand and index your site without obstacles. It doesn't deal with what you say (that's content) or who recommends you (that's authority), but with making sure the infrastructure doesn't stop either of those from counting. It covers robots.txt, indexing, rendering, URL architecture, canonicals, redirects, sitemaps, structured data, hreflang, performance and mobile experience.

How long does a technical fix take to show results?

It depends what you fix. Unblocking a page that was set to noindex or blocked in robots.txt can show within days if you request indexing in Search Console. Consolidating duplicates or rebuilding internal linking takes weeks, because Google needs to recrawl and recalculate. And Core Web Vitals improvements are assessed over a rolling 28-day window of real user data, so a fix deployed today takes roughly a month to fully register.

Does Google index content loaded with JavaScript?

Yes, but in two waves and with no guaranteed timing. Googlebot first downloads the HTML and, if the content depends on JavaScript, queues the page for rendering, which can take anywhere from hours to weeks. Anything that arrives late competes worse. There are also things it never sees: content that only appears after a click, hash-based routes, or links implemented with onClick instead of an a tag with href. That's why critical content should be in the initial HTML, via static generation or server rendering.

To remove a page from Google, should I use robots.txt or noindex?

noindex, almost always. They're different things: robots.txt blocks crawling, not indexing. If you block a URL in robots.txt, Googlebot stops visiting it and therefore never reads the noindex tag inside, so the page can keep appearing in results with a title taken from external links. The correct order is: allow crawling, add noindex, wait for it to drop out of the index, and only then block crawling if you want to save crawl budget.

Does structured data improve rankings?

Not directly: Google has repeatedly said markup isn't a ranking factor. What it does is change how you appear —rich results, stars, breadcrumbs, prices— and help search engines understand what entity you are and what each page is about. The real effect comes through click-through rate and comprehension, and increasingly through AI assistants, which rely on structured data to cite sources.

How often should I run a technical audit?

A full audit once a year for a stable site, every six months if you publish heavily or run a large catalogue. Beyond that, three moments demand one: before and after a migration or redesign, when organic traffic drops with no content explanation, and when launching a new language or section. Between audits, a monthly review of the Search Console indexing report is enough.

Do I need a developer for technical SEO?

Not to diagnose: Search Console and a crawler like Screaming Frog give you the full map. To fix, it depends. In a CMS like WordPress much of it is solved with configuration and plugins. But rendering, server-level redirects, URL architecture or hreflang on a multilingual site touch code and infrastructure, and there it helps if whoever fixes it understands both sides: SEO and development.

How do I know whether AI crawlers visit my site?

Only by looking at your server logs. Search Console reports on Googlebot alone, so to find out whether GPTBot, OAI-SearchBot, ClaudeBot or PerplexityBot come through, you filter the access log by user-agent. Validate each IP with a reverse DNS lookup too, because spoofing a user-agent is trivial and a good share of the traffic claiming to be an AI bot isn't. If they don't appear at all, check you aren't blocking them in robots.txt or at the CDN firewall.

What is crawl budget and when should I worry about it?

It's the number of requests a search engine is willing and able to make to your server over a period. It comes from two things: capacity, which Google adjusts based on how fast and stable your server responds, and demand, which depends on how popular and how fresh your URLs are. Below a few thousand URLs it isn't your problem. It starts to be one on ecommerce sites with filters, portals and template-generated sites, where combinable parameters can multiply your URL inventory a thousandfold.

Back to blog
• DESIGNS THAT INSPIRE • WEBS THAT STAND OUT

Ready to grow your business?

Transform your digital presence with tailored web solutions that convert visitors into customers.

Request your free quote