Get in touch
CZ EN RU
Mon-Fri 10-17
00:00:00

GEO in practice: How we optimized Zenitho.ai for ChatGPT and Perplexity in April 2026

In 48 hours (April 21–22, 2026) we ran our own website through a full GEO (Generative Engine Optimization) stack: sped up First Contentful Paint from 4.3s to 1.7s, added 17 JSON-LD schema blocks, registered the site with four search engines, extended robots.txt with AI crawlers, and shipped an llms.txt. Here's every step, what worked, what surprised us, and the numbers we actually measured.

Scope note upfront. This article documents the technical and structural foundation we put in place in 48 hours — Core Web Vitals, indexation, JSON-LD, robots.txt, llms.txt, IndexNow, middleware. What we can not yet prove: actual citation frequency in ChatGPT, Perplexity, and Gemini. That gets measured in Part 2, 30 days from now — AI citations need a different time horizon than a one-off technical sprint. So read this first piece as "how we built the runway", not "how often AI cites us today".

Why this article exists

In April 2026 every major Czech SEO agency published a theoretical guide to GEO — SEO Consult, MARF, Inpage, SEOkonzult, Symbio, Digichef. The guides are solid, but they almost all end the same way: "here's the definition, here are 10 tips." What's missing between them is a concrete implementation with real data. Someone who tried it on their own site and published the numbers.

So we decided to do it. Over two days we took Zenitho.ai — a site that had only gone through light SEO hygiene — and pushed it through the full GEO stack. This article is a literal diary of that work: what we changed, why we ordered it that way, what broke, and what it means for you if you want the same on your own site.

What GEO is (and how it differs from classical SEO)

GEO (Generative Engine Optimization) is optimizing your content and technical layer so that your website gets cited by large language models — ChatGPT, Perplexity, Google AI Overviews, Gemini, Claude, Microsoft Copilot. Synonyms: AEO (Answer Engine Optimization), LLMO (Large Language Model Optimization), AIO (AI Optimization).

The difference from classical SEO is the goal:

Why it matters now: by late 2025, over 40% of Google queries (US) ended as so-called "zero-click" — the user got their answer from an AI Overview and never clicked a SERP result. The Czech number is lower, but the trend is identical. If AI models don't cite you, your visibility will erode over the next 12 months even if your classical SEO positions stay the same.

The starting state of Zenitho.ai (morning of April 21, 2026)

The site before any intervention:

In other words: a typical state for a site where nobody had systematically worked on SEO. A great baseline for the experiment — any movement from here would tell us the interventions were working.

Strategy: 5 layers, in this order

We didn't want to make random moves. We decided to work through five clearly separated layers, in this order:

  1. Technical foundation — Core Web Vitals, clean URLs, correct language
  2. Classical indexation — Google, Bing, Seznam
  3. AI-specific filesrobots.txt directives for AI bots + llms.txt
  4. Structured data — JSON-LD schema on every page
  5. External signals and monitoring — directories + crawler detection

Why this order: speed and indexation are prerequisites. If crawlers time out or Google doesn't even know about you, everything else is wasted. Schema and AI files are the core — without them AI can't assign structure to your content. Directories and detection are the reinforcing layer — they boost signal, but alone they don't work.

Implementation, step by step

Step 0: Technical foundation (April 21, 2026, 16:00–23:43)

Seven hours, 20+ commits. The most painful layer, because PageSpeed doesn't forgive.

Before:

Metric (mobile)Before
First Contentful Paint4.3s
Largest Contentful PaintError (NO_LCP)
Total Blocking TimeError (NO_LCP)
Speed Index8.8s
Cumulative Layout Shift0

LCP couldn't be measured at all. Reason: the viewport fade-in animation used opacity: 0, which PageSpeed interprets as "no visible LCP candidate." The fix: change it to opacity: 0.01. Unmeasurable became measurable — and that was just the first of twenty similar optimizations:

After:

Metric (mobile)BeforeAfterChange
First Contentful Paint4.3s1.7s−60%
Largest Contentful PaintError4.2smeasurable
Total Blocking TimeError0 msgreen
Speed Index8.8s1.8s−80%
CLS00.033green

LCP 4.2s is still in the red — the next round. But three out of four metrics are green, crawlers stopped timing out, and Googlebot can now traverse the full site.

Why this matters for GEO: AI crawlers don't directly measure speed. But AI Overviews pull from Google's index, and Google weighs Core Web Vitals as a ranking factor. A slow site = lower index position = lower chance of being picked up by AI.

Step 1: Indexation in search engines

An underrated layer. Most GEO guides skip it, yet it's critical: most AI models (Gemini, AI Overviews, Copilot) pull from Google's or Bing's index. If you're not in them, AI can't see you.

What we did:

  1. Clean URLs — rewrote .html extensions to canonical URLs. /portfolio instead of /portfolio.html. Configured via Vercel rewrites.
  2. sitemap.xml — added /sluzby/web, /sluzby/kliniky (previously missing)
  3. html lang="cs" — fixed from invalid cz (BCP 47 requires the two-letter ISO 639-1 language code; cz is a country code, not a language)
  4. Canonical + title — cleaned up across all pages
  5. Register, submit sitemap:
    • Google Search Console → submit sitemap, Request indexing for every key page
    • Bing Webmaster Tools → submit sitemap (Bing is worth it in Czechia too, because Copilot)
    • Seznam WMT → verification file uploaded to root + meta tag, submit sitemap

Within 24 hours of Request indexing, every key page was in Google's index. Seznam took 3 days. Bing took 2.

IndexNow — automated push signal

Manually submitting the sitemap in every WMT after every change doesn't scale. On day two in the evening (April 22, after publishing this article) we therefore added IndexNow — an open protocol where a single POST to api.indexnow.org is forwarded to Bing, Seznam, Yandex, and Naver. You ping once; every participating engine receives it.

Why it matters for GEO: a routine crawl by Bingbot/SeznamBot discovers a page update in days to weeks. IndexNow is a push — it tells the engine, "look here again, now." Faster Bing index = faster Copilot coverage; faster Seznam = faster visibility in Czech AI assistants that pull from Seznam.

Implementation: stdlib Python script (zero deps) + GitHub Actions workflow, triggered by every push to main that changes HTML or sitemap:

on:
  push:
    branches: [main]
    paths: ['**.html', 'sitemap.xml']
  workflow_dispatch:

jobs:
  ping:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 2 }
      - name: Wait for Vercel production deploy
        run: sleep 90
      - name: Ping IndexNow (changed URLs)
        run: python3 indexnow.py

Key detail: sleep 90. We wait 90 seconds before pinging so Vercel has time to deploy the new version to the CDN. If we pinged immediately on merge, the engine would fetch the stale version and IndexNow would backfire. workflow_dispatch also enables a manual ping of the entire sitemap (python3 indexnow.py --all) — useful after a major rewrite or a new language variant.

Authentication uses a static key file at the site root (<key>.txt, contents = the key itself). The engine fetches it to confirm you own the domain — standard ownership proof.

Google does not accept IndexNow. It has its own Indexing API, but that's restricted to JobPosting and BroadcastEvent — unusable for regular pages. For Google, the classic submit-sitemap + Request indexing in Search Console stays. Not a dealbreaker — Googlebot is the most aggressive crawler of the bunch anyway.

Net result: every merge to main now auto-notifies Bing, Seznam, and Yandex. Zero manual steps, zero chance of forgetting — and this article you're reading was the first URL the workflow pinged in production.

Step 2: AI-specific files

robots.txt for AI crawlers

We extended robots.txt with explicit User-agent directives for the main AI crawlers:

Explicit Allow directives tell AI crawlers "yes, you can train on us and cite us." OpenAI and Anthropic have publicly confirmed they respect robots.txt.

llms.txt

llms.txt is an unofficial standard (Mintlify, April 2025). Goal: give LLMs a structured text summary of your site — like robots.txt, but for content. We filled ours with:

Important caveat: no major AI provider officially respects llms.txt yet. Not OpenAI, not Anthropic, not Google. Perplexity reportedly reads it experimentally but hasn't confirmed publicly. Why we still do it: it takes 15 minutes to write, and if the standard gets traction, we're ready. An asymmetric risk/reward bet.

Step 3: Structured data (17 JSON-LD blocks)

The core GEO work. Without schema, a website reads as unstructured text to machines. With JSON-LD ("this is an Organization, this is its Service with pricing, this is a FAQPage with 11 questions, these are the Person entities behind it") AI can recognize entities and relationships — and cite them.

What we added, page by page:

PageSchema types
index.htmlOrganization, WebSite, WebPage, ProfessionalService
sluzby.htmlBreadcrumbList, CollectionPage, ItemList (services)
sluzby/web.htmlBreadcrumbList, Service, 3× Offer (Starter/Business/Premium pricing)
sluzby/kliniky.htmlBreadcrumbList, Service, FAQPage (11 Q&As)
portfolio.htmlBreadcrumbList, CollectionPage, ItemList (6 cases)
o-nas.htmlBreadcrumbList, AboutPage, 4× Person with knowsAbout
kontakt.htmlBreadcrumbList, ContactPage, ContactPoint, OpeningHoursSpecification

Total: 17 blocks, 0 errors in Google Rich Results Test. On the second pass we added optional fields: logo, address, image, priceRange (Google flagged these as recommended, not required).

Concrete E-E-A-T tip: for AboutPagePerson entries, use the knowsAbout property with a list of domain skills. Google's Knowledge Graph uses this signal to establish entity authority. In our case, each person has 3–5 knowsAbout entries (e.g. "conversion rate optimization," "B2B lead generation," "marketing for healthcare providers").

Step 4: Edge Middleware for AI crawler detection

Vercel Web Analytics filters bots by design (it tracks humans via JS pixel; bots don't run JS). So for monitoring AI crawlers, it's useless. Solution: a Vercel Edge Middleware, 14 lines of code:

export const config = {
  matcher: '/((?!assets|api|_vercel).*)'
};

const BOT_RE = /GPTBot|OAI-SearchBot|ChatGPT-User|PerplexityBot|ClaudeBot|anthropic-ai|Google-Extended|Googlebot|Bingbot|SeznamBot|Applebot/i;

export default function middleware(request) {
  const ua = request.headers.get('user-agent') || '';
  const match = ua.match(BOT_RE);
  if (match) {
    const path = new URL(request.url).pathname;
    console.log(`[bot] ${match[0]} -> ${path}`);
  }
}

Middleware runs on every non-static request. Logs show up in Vercel Observability → Middleware. On the Hobby plan you get aggregates (invocation count, paths, actions); on Pro you get the actual log text. In the first day we saw 14 middleware invocations — bot/human ratio traceable, but detailed UA text stays behind the paywall.

Step 5: External signals (directories and platforms)

Entity recognition in AI models leans on what the rest of the internet says about you. The more independent domains cite the "Zenitho" entity, the stronger the entity signal.

We registered on:

Each platform is another authority domain confirming "this is Zenitho agency, offering X, located in Y." AI models pick up these cross-references during entity resolution.

Results after 48 hours

AreaBefore (April 21 morning)After (April 22 evening)
FCP (mobile)4.3s1.7s
LCP (mobile)Error (NO_LCP)4.2s
Speed Index8.8s1.8s
JSON-LD blocks on site017
Schema errors (Rich Results Test)0
Indexed in GoogleNoYes (24h)
Indexed in BingNoYes (2 days)
Indexed in SeznamNoYes (3 days)
AI crawler directives in robots.txt08
llms.txtDidn't existPublished, 4.4 kB
Directory listings1 (Maps)5
AI crawler monitoringNoneEdge Middleware

What we haven't measured yet: the actual rate of citations in ChatGPT/Perplexity/Gemini. That's inherently hard to measure — the tools for it (Otterly, Peec AI, AthenaHQ) are paid and need 2–4 weeks for a meaningful trend. We'll report in a follow-up article in 30 days.

What surprised us

1) Vercel Web Analytics filters bots. We assumed turning on Analytics would show us AI crawlers. It didn't — Analytics tracks humans with browsers; bots don't execute JS. Fix: Edge Middleware.

2) No one officially respects llms.txt. OpenAI, Anthropic, Google don't officially crawl it. Perplexity supposedly does (unconfirmed publicly). We still recommend doing it — minimal investment, asymmetric upside.

3) JSON-LD alone isn't enough. Probably the most common mental shortcut. Schema tells machines the structure, but they still read the content. If your Service schema wraps boilerplate copy ("professional custom websites"), AI will cite a competitor with weaker schema but unique data and concrete numbers over you.

4) The Czech market is asleep in practice. The big Czech agencies published theoretical GEO guides in 2026. But almost nobody has published a concrete implementation with numbers. That's the gap this article fills — and we hope it inspires you to the same openness.

Key takeaways

  1. Speed is a prerequisite, not a GEO feature. Without a fast site, crawlers timeout or drop requests. But speed alone doesn't earn citations — content does.
  2. Index yourself everywhere AI draws from. Google, Bing, Seznam. Without classical indexation you're invisible to 80% of AI systems.
  3. Schema is a must-have, not a silver bullet. 17 JSON-LD blocks alone won't increase AI citations. You also need content worth citing.
  4. llms.txt is an investment in the future. Nobody officially respects it today. In a few months that may change. 15 minutes of work, negligible risk.
  5. Detect crawlers, don't hope. Without your own logs you don't know who's visiting. Edge Middleware in 14 lines of code gives you the answer.

Checklist: 10 steps for small-to-medium Czech businesses

  1. Run your site through PageSpeed Insights. Targets: FCP under 2s, LCP under 2.5s, CLS under 0.1.
  2. Fix html lang="cs" (BCP 47) — not cz.
  3. Ship clean URLs (drop the .html extension).
  4. Register the site in Google Search Console. Submit the sitemap. Request indexing.
  5. Repeat for Bing Webmaster Tools and Seznam WMT.
  6. Add to robots.txt: User-agent: GPTBot / PerplexityBot / ClaudeBot / Google-Extended with Allow: /.
  7. Create llms.txt at the root — a short text overview of the company, pricing, people, contact.
  8. Add JSON-LD schema: at minimum Organization, ProfessionalService (with priceRange and areaServed), FAQPage if you have common questions.
  9. Validate with Google Rich Results Test and Schema.org Validator. Target: 0 errors.
  10. List the company on firmy.cz, Clutch, LinkedIn Company Page, Google Business Profile.

Advanced: Edge Middleware for AI crawler detection (code above).

Want GEO for your website?

We're Zenitho — a Czech agency that doesn't just teach GEO but actually ships it. On our own site and for clients across private clinics, B2B services, and local businesses.

Request GEO for your website

Frequently asked questions

Does a small Czech company need to work on GEO right now?

If you target B2B, professional services, or healthcare — yes, start now. The share of users who routinely search ChatGPT and Perplexity for information about companies has been growing year over year, including in the Czech market. B2C e-commerce has less urgency, but the first five steps (speed, sitemap, JSON-LD, Google indexation, clean URLs) pay off in classical SEO too — so do them anyway.

What's the effort ratio between classical SEO and GEO?

In practice, 80% of the work is "classical" — speed, indexation, content quality, schema. The remaining 20% is GEO-specific: llms.txt, AI crawler directives, entity mentions in directories. GEO doesn't work without solid classical SEO.

What if AI systems never adopt llms.txt?

Investment: ~15 minutes. Trivial maintenance. Even if the standard is fully rejected, you haven't lost more than an hour of work. Risk effectively zero, upside meaningful — which is why we recommend it.

When will we see results?

Classical SEO (Google ranking): 2–6 weeks after reindexing. GEO citations: very hard to measure. We recommend building a list of 20 relevant queries (e.g., "Prague digital agency for clinics") and testing them monthly in ChatGPT, Perplexity, and Gemini. You won't get absolute numbers, but you'll see a trend over 2–3 months.

Is there a tool that tracks AI citations?

Yes — Otterly.AI, Peec AI, AthenaHQ. They're paid (~$50–$200/month) and measure how often your domain appears in AI responses. Worth it for small companies only after 3–6 months of GEO work, when there's signal to measure.

What if I don't use Vercel?

Edge Middleware is Vercel-specific. Equivalents: Cloudflare Workers, AWS Lambda@Edge, Netlify Edge Functions. The concept is the same everywhere — intercept the request, parse User-Agent, log bot matches. The code stays around 14 lines on any of these platforms.

Controlled growth starts here

Fill out the form and in a free consultation, which we'll prepare for in advance, we'll show you
how to get more inquiries without raising your ad spend.

30 min consultation, free!
OPEN HAPPINESS