Scanning the page — checking accessibility, JS weight, structured data, discoverability, and carbon footprint…

Is Your Site Marketing-Hygienic?

Last scanned 2026-10-24 17:28 UTC

Results for

https://seo-coach.eu/

92 Spotless

Agent-ready and human-ready — minor polish only.

42 of 49 checks passed (pass rate 86%)

Listed in Verified sites

The audit at a glance

6 steps · 3 priorities · quick wins · next steps

Audit steps

1. Accessibility treeDone

Roles, names and focus validated

Aim for: Every button and link has a role, a name, is enabled and focusable

Audit this with: Chrome DevTools → Accessibility (F12) (opens in a new tab)

2. JS weightDone

0 KB JavaScript · 0 KB unused

Aim for: Under 100 KB, ideally 0–50 KB; unused JS under 50 KB

Audit this with: pagespeed.web.dev (opens in a new tab)

3. Structured dataFix

Validator errors

Aim for: Valid JSON-LD for Person / Organization and the page's main entity

Audit this with: validator.schema.org (opens in a new tab) · see the fix

4. Markdown alternateDone

Available

Aim for: <link rel="alternate" type="text/markdown" href="…">

Audit this with: isitagentready.com (opens in a new tab)

5. Carbon measureDone

A+ · 0.009 g CO₂ per view

Aim for: ≤ 0.1 g per view (A+)

Audit this with: websitecarbon.com (opens in a new tab)

6. Accessibility (keyboard & WAVE)Improve

Lighthouse accessibility 95/100

Aim for: Keyboard accessible; WAVE AIM score 9/10

Audit this with: wave.webaim.org (opens in a new tab) · see the fix

If you do only three things

  1. Done Don't block AI user agents in robots.txt — add a Content-Signal and the sitemapsearch=yes, ai-input=yes, ai-train as you decide; without it agents don't know what to do
  2. Improve Show firsthand proof on the pageauthor page and link, case studies with dates, client examples — check it every month
  3. By hand Once a month, ask the top AI platforms your clients' questionssee whether you are mentioned or cited; if not, see who is, and do a better job than they do

Quick wins — do these first

  • Done
    Repair the heading outline and mark up header, nav, main and footer
  • Done
    Give every button, field and icon link a clear name
  • Done
    Cut JavaScript: drop unused code, defer what's left, trim tracking tags
  • Done
    Shrink big images and serve them as WebP or AVIF
  • Fix
    Describe the page's main entity in valid JSON-LDPasses the schema.org Markup Validator

Scoring and next steps

  • Pass rate: 42 of 49 checks pass on this page (86%) — passed checks divided by all checks, counted per page.
  • Fix accessibility and rendering/JavaScript first (2 open items here): people, screen readers and agents all depend on them.
  • Audit again every three months, and after any major change to the site (new theme, page builder, plugins or tracking tags).

Accessibility

11/12
Passed:

One clear, descriptive <h1>

Goal

Give the page exactly one <h1> that says what the page is about ("SEO Services for Small Businesses", not "Services"), and section headings that say what follows, so people, screen readers and agents can scan the outline.

Result

Exactly one <h1>: "Get Found by Google and by AI"; tip: make these section headings more specific: "FAQ".

Passed:

No skipped heading levels

Goal

Keep heading levels sequential (H1 → H2 → H3) so screen readers and crawlers can build an accurate document outline.

Result

Heading levels increase in order, without skipping a level.

Passed:

Semantic landmarks present

Goal

Mark header, nav, main, and footer regions semantically so screen readers and agents can jump straight to the right part of the page.

Result

header, nav, main, and footer landmarks are all present.

Passed:

Images have meaningful alt text

Goal

Give every <img> an alt attribute — a short description of what matters for meaningful images ("Three-column WordPress blog layout", not "image" or IMG_4729.jpg), empty alt="" for purely decorative ones.

Result

3/3 images have an alt attribute, none of them a placeholder or file name.

Passed:

Form fields have visible labels; errors are announced

Goal

Give every form field a visible <label> tied to it (for/id or wrapping), and make validation errors reach screen readers — native browser validation, or aria-invalid plus an error message linked with aria-describedby or an aria-live/role=alert region.

Result

No form fields found on the page.

Passed:

Buttons are real, named controls

Goal

Every action (book, buy, send, subscribe) is a real <button> or <a href> with an accessible name, so screen readers and agents can tell what will happen — a clickable <div> or an icon-only button is invisible as an action.

Result

No buttons on the page; links carry the actions.

Passed:

Every link and button can be reached with the keyboard

Goal

Every link, button and form control must be focusable — reachable with the Tab key — because that is also how agents find what they can act on. Controls with tabindex="-1", links without an href and javascript: links are invisible to both.

Result

No links or controls removed from the keyboard order (no negative tabindex, no href-less or javascript: links).

Passed:

Tab test: every control reachable with visible focus

Goal

Click the logo, put the mouse away and press Tab: every link — including drop-down and sub-menu items — must receive visible focus in a sensible order, and focus must never get stuck. If a keyboard can't reach it, many agents can't either.

Result

Tabbed through the rendered page in Chrome: 25 of 24 visible controls received focus, all with a visible focus indicator; no keyboard trap.

Passed:

Rendered page passes axe-core (WCAG 2.2 AA)

Goal

The page as a browser renders it — after CSS and JavaScript — has no WCAG 2.2 A/AA violations: sufficient colour contrast, valid ARIA, a name for every control and image. This is the automated core of WAVE and Lighthouse; the target is zero.

Result

No WCAG A/AA violations found by axe-core 4.14 in the rendered page (21 rules passed).

Warning:

Lighthouse accessibility audit (axe-core, independent)

Goal

Pass an automated accessibility audit run in a real browser: Lighthouse's accessibility category (axe-core rules) should score 90+ with no failing audits. Confirm with WAVE (wave.webaim.org) — the target there is an AIM score of 9 out of 10.

Issue

Lighthouse accessibility 95/100 with 1 failing audit(s): Touch targets do not have sufficient size or spacing. (1).

How to implement

Open the Lighthouse/PageSpeed accessibility section for this page; each failing audit lists the exact elements. Fix colour contrast, ARIA attributes, names and focus order first, then re-run.

Independent check: WAVE (WebAIM)

Runs WebAIM's WAVE on this page: AIM score, errors and contrast errors. The target is an AIM score of 9 out of 10 and zero errors.

Open the full WAVE report (opens in a new tab)

Rendering & JS

9/10
Passed:

Rendering mode: content in the initial HTML

Goal

Identify the rendering mode and keep key content server-rendered or static (SSR/SSG). Many AI/LLM crawlers never execute JavaScript, so content that only appears after hydration is invisible to them.

Result

Rendering mode: server-rendered or static (SSR/SSG). ~5189 characters of visible text arrive in the server HTML. In a real browser the page shows ~4415 characters; practically all of it is already in the server HTML.

Passed:

Works without JavaScript: pagination, forms, interactions

Goal

Don't make JavaScript the only way to understand or use the page: "Load more" and infinite scroll need real pagination links, forms need a <form> with an action and a submit button, interactive content needs its HTML in the page with JavaScript only as enhancement.

Result

No JavaScript-only pagination or forms found in the server HTML.

Passed:

JavaScript weight ≤ 100 KB gzipped

Goal

Keep total JavaScript under 100 KB gzipped — ideally 0–50 KB (hard ceiling ~170 KB). The average site ships ~700 KB of JavaScript in ~20 requests per page; every extra KB costs load time, carbon, and agent parsing effort.

Result

~0 KB of JS (transfer size, i.e. gzipped/brotli where the server compresses) across 0 sampled file(s).

Passed:

Third-party tags audited and trimmed

Goal

Every third-party script (tag manager, analytics, pixels, chat widgets, overlays) should earn its place: each one adds JavaScript, delays interaction, and sends visitor data elsewhere. Keep the ones you act on; remove the rest.

Result

No third-party scripts in the initial HTML.

Passed:

Page weight ≤ 270 KB (A+) / ≤ 530 KB (A)

Goal

Keep the total transferred weight of the page at or under ~270 KB for an A+ carbon rating (≤ ~530 KB still earns an A). For scale: static HTML ~0.1 MB loads in 0.3–0.8 s, a standard React app ~1.2 MB in 1.2–2.5 s, a heavy framework ~4.8 MB in 4–8 s — and conversion is about 3× higher at 1 s than at 5 s. Images are usually the biggest lever.

Result

~59 KB transferred — HTML 7 KB · CSS 0 KB · JS 0 KB · images 52 KB (3 sampled) · 5 requests referenced in the HTML (average site: ~20).

Passed:

Fast server response (hosting)

Goal

The server should start answering within ~800 ms (Google's "good" TTFB; ≤ 600 ms is better) and deliver the whole HTML well within the 1–5 seconds AI crawlers wait before giving up. Slow hosting, no page cache or a heavy theme/plugin stack delays everything after it — for visitors and crawlers alike.

Result

The page's HTML started arriving after ~530 ms (best of two requests from our server on a warm connection); the complete HTML took ~1894 ms on a cold connection, the way a crawler meets it (AI crawlers time out after 1–5 s).

Passed:

HTML, CSS and JavaScript are compressed

Goal

Serve HTML, CSS and JavaScript compressed (Brotli or gzip). It typically cuts text transfer by 70–80 % at no cost — what optimisation plugins call "zip".

Result

2/2 text resources served compressed (HTML: gzip).

Passed:

No page-builder layer, few plugins loading assets

Goal

Every page builder and every plugin that loads its own CSS/JS adds a layer between your content and the reader. Clean up before you add: fewer plugins, a light theme, no builder where the block editor or plain HTML will do.

Result

No page builder detected; not a WordPress page.

Warning:

Core Web Vitals pass (LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1)

Goal

Pass Google's Core Web Vitals on mobile: Largest Contentful Paint ≤ 2.5 s, Interaction to Next Paint ≤ 200 ms (lab stand-in: Total Blocking Time ≤ 200 ms), Cumulative Layout Shift ≤ 0.1.

Issue

Failing: Largest Contentful Paint 2.7 s (target ≤ 2.5 s).

How to implement

Open the PageSpeed Insights report: LCP usually means an oversized hero image or render-blocking CSS/JS; INP/TBT means too much JavaScript on the main thread; CLS means images or embeds without width/height.

Passed:

Unused JavaScript removed or deferred

Goal

JavaScript that loads but never runs on this page is pure cost. Lighthouse's "Reduce unused JavaScript" audit measures it; the target is under 50 KB of unused JavaScript (and under 100 KB of JavaScript in total).

Result

~0 KB of JavaScript could be removed according to Lighthouse (counts every script loaded during the run, including ones other scripts load later — so it can exceed the JS weight sampled from the HTML above).

Independent check: Core Web Vitals (PageSpeed Insights)

Running Lighthouse on Google’s servers — usually 10–30 seconds…

Open the full report on pagespeed.web.dev (opens in a new tab)

Structured data & trust

9/13
Passed:

JSON-LD structured data present

Goal

Describe the page's main entity (who you are, what you offer) as JSON-LD so search engines and AI agents can read it as structured facts, not prose to interpret.

Result

1 JSON-LD block(s) found.

Passed:

JSON-LD parses without errors

Goal

Keep every JSON-LD block syntactically valid — a single stray comma invalidates the whole block.

Result

All JSON-LD blocks are valid JSON.

Passed:

Describes a recognized entity type

Goal

Use a well-known schema.org @type (Organization, LocalBusiness, Product, Service, Article, FAQPage, etc.) so search engines and agents recognize what kind of thing this page describes.

Result

Found: WebSite, Person, ProfessionalService, Course, FAQPage

Passed:

No conflicting Organization/LocalBusiness blocks

Goal

Keep a single, consistent Organization/LocalBusiness record so crawlers and AI agents don't get contradictory facts about who you are.

Result

Organization/LocalBusiness data is consistent.

Failed:

Passes the schema.org Markup Validator

Goal

Every structured-data object on the page passes the official Schema Markup Validator (validator.schema.org) with no errors or warnings: valid types, valid property names, valid values.

Issue

validator.schema.org reports: 3 error(s) and 3 warning(s): ProfessionalService: unknown field: availableLanguage, ProfessionalService; ProfessionalService: unknown field: availableLanguage, ProfessionalService; ProfessionalService: unknown field: provider, ProfessionalService; page: unknown field: provider, ProfessionalService; page: unknown field: availableLanguage, ProfessionalService; page: unknown field: availableLanguage, ProfessionalService.

How to implement

Open the validator for this URL, fix each flagged property or type name (they must match schema.org exactly, case-sensitive), and re-validate.

Passed:

Markup for a rich-result type is complete

Goal

Give each page structured data for a type Google can show as a rich result (Article, Product, FAQ, Breadcrumb, Local business, Event, Recipe, Video, Software app…) with the properties it requires. FAQ results are shown only for some sites in Google, but the markup still helps AI answers.

Result

Complete rich-result markup: Course, FAQ; incomplete: Local business (missing address).

Passed:

Prices are machine-readable

Goal

When a page shows prices, mark them up too (Offer or PriceSpecification with price and priceCurrency, inside the Product or Service), so agents can read "SEO consultation – €500" as a service and its price instead of guessing from text.

Result

1 price(s) on the page (€399) and price markup in the structured data.

Passed:

Author or operator identity is machine-readable

Goal

Say who stands behind the page in a form machines can read — a Person/Organization in JSON-LD with a name and a url/email/sameAs, an author/publisher property, a <meta name="author">, or a rel="author" link. Claims without a named, reachable author get mentioned, not cited.

Result

JSON-LD names a Person/Organization with a URL, email or sameAs links.

Warning:

Content is dated and current

Goal

Keep content current and say so: show when it was published or last updated (e.g. "Updated September 2026 · Author: Name") in a form machines can read (datePublished/dateModified in JSON-LD, a <time datetime> element, or article:modified_time), so agents can tell current content from stale content.

Issue

No publish or last-updated date found in JSON-LD, <time datetime>, or meta tags.

How to implement

Add dateModified (and datePublished) to the page's JSON-LD and show the same date visibly in a <time datetime="YYYY-MM-DD"> element.

Warning:

Clean, complete metadata

Goal

Give every page a descriptive <title>, a meta description, a canonical URL, the page language, a viewport tag and Open Graph title/image — the metadata search engines, AI crawlers and link previews read first.

Issue

Metadata gaps: meta description is 194 characters (aim for 50–170).

How to implement

Fill the missing tags in the page template (most SEO plugins and frameworks expose all of them).

Warning:

Proof of work: author page and case studies are linked

Goal

Show proof that you did the work: link an author/about page and case studies, references or client examples (with dates) from your pages. "We offer the best deal in town" — can you prove it? Without proof you get mentioned, not cited.

Issue

No link to an author/about page found on this page.

How to implement

Create (or link) an author page with your experience and profiles, and a case-study/references page with dated, specific client results; link both from the navigation or footer and from authority pages.

Informational:

By hand: the vanish test for your authority pages

Goal

Ask honestly for each authority page: if this page did not exist, would it matter? It should only exist if its content exists only here. If it is a rewrite of what 16 other sites say, rethink it — AI crawlers look for the single best, unique answer.

Result

Manual check — uniqueness of content can't be judged by a scanner.

Passed:

Served securely over HTTPS

Goal

Serve every page over HTTPS, redirect http:// to https://, and load no images, scripts or styles over plain http — browsers, search engines and AI systems treat insecure pages as less trustworthy.

Result

HTTPS, http:// redirects to https://, HSTS enabled, no mixed content.

Independent check: schema.org Markup Validator

The "Passes the schema.org Markup Validator" check above already contains the official validator's result for this page. Open the full validator report to see each object and property, and Google's Rich Results Test for rich-result eligibility.

Validate this page’s JSON-LD (opens in a new tab)

Discoverability

11/11
Passed:

robots.txt exists

Goal

Publish a robots.txt file so crawlers know what they may fetch before they fetch anything else.

Result

Found at https://seo-coach.eu/robots.txt

Passed:

Sitemap referenced or reachable

Goal

Give crawlers a complete, structured list of your URLs instead of making them discover pages by following links alone.

Result

robots.txt references a sitemap.

Passed:

Explicit rules for AI/LLM crawlers

Goal

Decide intentionally whether GPTBot, PerplexityBot, ClaudeBot, and similar AI crawlers can access your content, instead of leaving them on the default catch-all rule.

Result

robots.txt has explicit rules for: GPTBot, ChatGPT-User, CCBot, Google-Extended, PerplexityBot, ClaudeBot, anthropic-ai, Bytespider, Applebot-Extended, plus a Content-Signal policy.

Passed:

The page can be indexed

Goal

Search engines and AI crawlers may only use pages that are indexable: HTTP 200, no noindex in a robots meta tag or X-Robots-Tag header, and a canonical that points to the page itself.

Result

HTTP 200, no noindex, and the canonical (if any) points to this URL.

Passed:

AI search and assistant crawlers are not blocked

Goal

robots.txt must not block the crawlers that fetch pages for search and for users' questions (Googlebot, Bingbot, OAI-SearchBot, ChatGPT-User, PerplexityBot, Claude-SearchBot/User…). Blocking AI training crawlers is a legitimate policy choice; blocking search and assistant crawlers makes you invisible in AI answers.

Result

No search or assistant crawler is blocked from the site root. Training crawlers blocked by policy: GPTBot, ClaudeBot, anthropic-ai, CCBot, Google-Extended, Bytespider, Meta-ExternalAgent.

Passed:

AI crawlers receive the page within 5 seconds

Goal

When robots.txt allows them, AI crawlers (GPTBot, ClaudeBot, PerplexityBot) must actually get the same page as a visitor, within the 1–5 seconds they wait — no firewall block, no challenge page, no empty shell.

Result

Requests identifying as PerplexityBot (1601 ms) got the full page. Not tested (blocked in robots.txt by policy): GPTBot, ClaudeBot.

Passed:

Content-Signal directive

Goal

State a machine-readable policy on whether your content may be used for search indexing, AI-agent answers, and AI model training — separately.

Result

robots.txt declares a Content-Signal policy (search / ai-input / ai-train).

Passed:

llms.txt present

Goal

Offer a short, curated Markdown index of your most important pages so LLMs and agents don't have to guess which pages matter.

Result

llms.txt found — a curated entry point for LLMs/agents.

Passed:

Markdown version of this page

Goal

Offer a clean Markdown version of the page — what AI agents prefer to read — at least for your top five authority pages: a <link rel="alternate" type="text/markdown">, content negotiation on Accept: text/markdown, or a .md twin.

Result

A Markdown version of this page is available via a Markdown twin at /index.md: 6 KB with headings and links, plus frontmatter (title, canonical); tip: send X-Robots-Tag: noindex on the .md URL so it isn't indexed as a duplicate of the page.

Passed:

Services, prices, FAQs and contact/booking are easy to find

Goal

Clear, extractable content gets you cited when people ask AI to compare and shortlist: what you offer, what it costs, answers to common questions (FAQs) and how to contact or book you — reachable straight from the navigation or on the page.

Result

Found: services, contact, FAQs.

Passed:

One heading, one idea: sections stand on their own

Goal

Structure content so each section covers one idea, answers its question early and is understandable on its own — that is good writing first, and it lets search and AI systems match a section to a question. Use subheadings, short paragraphs and lists; avoid "as mentioned above"; don't split text artificially. There is no ideal chunk size: a chunk ends where a thought is complete.

Result

~635 words in 20 section(s) (~32 words each, longest ~136), 4 list(s)/table(s), no wall-of-text paragraphs, no "as mentioned above" references.

Informational:

Monthly by hand: are you mentioned or cited by AI assistants?

Goal

Once a month, ask the main AI platforms (ChatGPT, Gemini, Claude, Perplexity, Copilot) the questions your clients ask. Check whether you are mentioned and cited, in an incognito window and logged in. If someone else is cited, study why and do a better job than they do.

Result

Manual check — the scanner can't see AI answers. Pair it with the vanish test and proof-of-work checks.

Independent check: agent-readiness level

Scanning the site’s agent protocols — about 10 seconds…

Level from Cloudflare’s isitagentready.com, a free public scanner. We are not affiliated with Cloudflare.

Open on isitagentready.com (opens in a new tab)

Carbon

2/4
Passed:

CO₂ per page view ≤ 0.095 g (A+), ≤ 0.186 g acceptable (A)

Goal

Estimate CO₂ per page view with the Sustainable Web Design model v4 and keep it at or below 0.095 g (A+); 0.186 g (A) is acceptable. The global median is about 0.36 g.

Result

~0.009 g CO₂/view (rating A+), estimated from ~59 KB transferred (HTML + sampled CSS/JS/images), Sustainable Web Design v4. websitecarbon.com's calculator did not answer during this scan (HTTP 403).

Passed:

Images compressed, modern formats, lazy-loaded

Goal

Serve images compressed and at their display size, in WebP or AVIF, and lazy-load the ones below the fold. Images are usually the biggest lever on page weight and carbon.

Result

2 raster image(s) sampled, ~52 KB total; 2 in WebP/AVIF; 0/0 below-the-fold images lazy-loaded.

Warning:

Caching and CDN enabled

Goal

Serve static assets with long cache lifetimes (Cache-Control max-age ≥ 1 day, ideally immutable) from a CDN close to the visitor, so repeat views and far-away visitors cost almost nothing.

Issue

Only 0/2 sampled CSS/JS/image files are cacheable for a day or more.

How to implement

Put the site behind a CDN (Cloudflare's free plan, or your host's built-in edge) and set Cache-Control: public, max-age=31536000, immutable on versioned CSS/JS/image files.

Warning:

Green hosting

Goal

Host on infrastructure that runs on renewable energy or is verified green (The Green Web Foundation directory). It lowers the data-centre share of every page view's footprint.

Issue

Hosting is not verified as green.

How to implement

Ask your host whether they are listed with The Green Web Foundation, or move to a verified green host/CDN when feasible.

Over a year

Over a year

1.07 kgCO₂ equivalent
2.2 kWhof energy
144cups of tea boiled
179smartphone charges
14 kmin an electric car
0.1trees to absorb it in a year

Rough equivalents from this page's ~0.009 g CO₂ per view (Sustainable Web Design v4); every page you make lighter shrinks all of them.

Independent check: Website Carbon Calculator

Agent API

2/2
Passed:

ai-agent.json / ai-plugin.json manifest

Goal

Optional: publish an agent manifest at /.well-known/ (ai-agent.json pointing agents to your critical pages, or ai-plugin.json describing a callable API with name, description, auth and OpenAPI spec location).

Result

Found a manifest at /.well-known/ai-agent.json.

Passed:

security.txt contact file

Goal

Publish a /.well-known/security.txt (RFC 9116) with a contact method — a small, standard trust signal that you're a real, reachable operator.

Result

Found a security.txt file.

What crawlers and agents see

no JavaScript

Text-only extraction of the first server response — what many AI crawlers index, and the actions an agent can take (role + name).

Title, headings & text

title: "SEO Coaching & AI Search (GEO) | Warren Laine-Naida"
heading 1: "Get Found by Google and by AI"
heading 2: "Four Ways to Work Together"
heading 3: "1:1 & Team SEO Coaching"
heading 3: "Direct SEO Work"
heading 3: "Structured 1:1 SEO Course"
heading 3: "Ongoing Coaching (Retainer)"
heading 2: "What You Walk Away With"

SEO Coaching · WordPress · AI Search Get Found by Google and by AI SEO is ensuring your content is relevant and credible. I can help you with this. Your SEO coach and consultant for WordPress and WooCommerce sites: SEO coaching, SEO audits, hands-on SEO work and a 1:1 SEO training course. Online or on site in Germany a…

~795 words of main content.

Actions

link: "Book a Free 20-Min Call"
link: "Only Online Marketing Book You Need series"
link: "Book My Free Call"

Extracted links

link: "SEO Coaching & AI Search Warren Laine-Naida → /"
link: "Services → /"
link: "Course → /"
link: "FAQ → /"
link: "Let's Talk → /"

These are automated heuristics, not a professional audit. Please use your own judgment when applying a fix, as results are provided “as-is” and the operator assumes no liability for actions taken on them.