ZentimesENES
Case study · client in production

kenetg.com

The official site of a content creator, built and maintained by me, with the GEO layer on top: a linked entity graph, a machine-readable surface and open access for AI crawlers. Below are the numbers I measured — and, in the same size type, the ones I have not measured yet.

Client
KenetG — content creator (Twitch, League of Legends, VR)
My role
Development, infrastructure, technical SEO and GEO
Observable stack
Next.js (App Router) · headless CMS on a separate host · nginx · Google Cloud
Status
In production · implementation verifiable · GEO measurement still pending

Context

01

KenetG is a Spanish-speaking content creator: live on Twitch, League of Legends, community and VR sessions, and part of the esports organisation Nocturne Gale. Like most creators, his presence lived scattered across third-party platforms — Twitch, YouTube, TikTok, Instagram, X, Discord — and he owns none of them.

That has a concrete consequence for an AI engine. When someone asks who KenetG is, or where he streams, the model needs a first-party, stable, verifiable source to cite. A handful of platform profiles does not qualify: they declare no entity, they do not link to one another, and the engine has no way to know they refer to the same subject.

The brief was to build and maintain that source: the official site as the canonical point of the brand, written so a machine can read it, understand it and quote it — not only so a person can read it.

One constraint worth stating out loud up front: when the work started there was no measured citation baseline. Without that before, you cannot attribute an after. That is exactly why block 3 of this page is empty rather than filled in.

Method

02

What was shipped. Every item on this list is code in production and can be checked from the outside; the commands are in block 5.

01

An entity graph, not loose tags

JSON-LD with Organization, WebSite and Person linked by @id and carrying sameAs to the 7 official profiles. The point is that KenetG on Twitch, KenetG on TikTok and kenetg.com resolve to one node for the engine, rather than three strangers who happen to share a name.

02

A type layer on every page

On top of the entity graph, each page declares what it is: WebPage, CollectionPage, ProfilePage, ContactPage, FAQPage or BlogPosting, each with its BreadcrumbList. An extracting engine does not have to guess whether it is reading a profile, an index or an article.

03

Questions and answers in extractable form

The FAQ page ships FAQPage with 6 question/answer pairs in JSON-LD. It is the shape an engine can quote verbatim without having to interpret the layout.

04

A surface built for machines

llms.txt as a curated index of the brand — facts, main routes, official channels, blog — and llms-full.txt with the content dumped out. Both are announced from robots.txt and carry a generation stamp, so they cannot go stale in silence.

05

The door left open for AI crawlers

robots.txt contains not a single global Disallow: it closes only the admin panel and the internal API. The failure I see most often in audits — accidentally blocking GPTBot or PerplexityBot — does not happen here.

06

Server rendering and the boring foundation

Next.js with the App Router: the content arrives in the HTML rather than behind JavaScript, which is the difference between an extractor reading you and not. Underneath, the unglamorous necessities: a canonical per page, a sitemap with lastmod, a real 404, http→https and www→apex redirects, HTTP/2 and TLS 1.3.

Measurement

03

Pending — owned and run by the GEO layer

This is where the only evidence that actually proves GEO worked would go: a panel of real queries re-run across the engines. It does not exist today, so this block is deliberately empty. I would rather ship a page with a visible hole than a page with an invented number.

What has to live here once the panel exists

  • The query panel: the fixed set of real questions someone would type to reach this brand, and why those were chosen.
  • The engines it runs against, and the version or cut-off date of each.
  • Repetitions per query: AI answers are not deterministic, so a single run is not a measurement, it is an anecdote.
  • The citation rate: in how many of the target answers the brand appears, with what quote and in what position.
  • The baseline and the date of the previous run, so before-and-after is a comparison rather than a memory.
  • Who gets cited in that slot when the brand does not.

What can be claimed today, and what cannot

What can be claimed today: the work is shipped and verifiable with the commands below. What cannot be claimed today: that the brand is cited more often by an AI engine because of it. That sentence gets written here only when there is a panel behind it, with its date.

Result

04

What is measured today: the implementation, checked from the outside. Every number was taken on the same day, and each one carries its date and how it was obtained.

Measured with curl from a Google Cloud VM in europe-west1 — the same region as the origin. Treat the timings as a network floor, not as what a visitor sees from home.

Machine-readable surface

4,309 B

llms.txt served (HTTP 200, text/plain)

54 lines and 23 links across 7 sections: facts, main routes, official channels, blog, FAQ, full content and legal

5,455 B

llms-full.txt served (HTTP 200, text/plain)

stamped "Generado desde https://kenetg.com/ el 2026-09-04": it is regenerated, not a fossil file

0

global Disallow rules in robots.txt

215 B; only /admin/ and /api/ closed; it declares the sitemap and announces both llms files

12

URLs in sitemap.xml, all 12 with lastmod

2,252 B, application/xml; 11 pages plus 1 blog post

Structured data

12 of 12

pages with valid JSON-LD

the 12 sitemap URLs, each downloaded and parsed with json.loads; none fails to parse

2

JSON-LD blocks on the 9 content pages

one entity graph, identical across all 12; one specific to the page. The 3 legal pages carry the first one only

16

distinct Schema.org types declared

Organization, WebSite, Person, ImageObject, ContactPoint, WebPage, ProfilePage, CollectionPage, ContactPage, FAQPage, Question, Answer, BlogPosting, BreadcrumbList, ItemList and ListItem

7

official profiles linked with sameAs

declared on both the Organization node and the Person node of the graph

6

question/answer pairs in FAQPage

counted on the JSON-LD of /faq/

8 of 12

pages carrying a BreadcrumbList

the 9 content pages minus the front page, which is the root and has no trail to declare; the 3 legal pages do not carry one either

Availability and performance

17 of 17

endpoints answering HTTP 200

the 12 sitemap URLs plus robots.txt, sitemap.xml, llms.txt, llms-full.txt and the RSS feed

64.5 ms

median TTFB of the front page

5 consecutive curl samples: 62.1 · 64.5 · 62.6 · 66.1 · 66.5 ms

57–173 ms

TTFB range across the 16 endpoints

one sample each; the slowest is /privacidad/

−83.3 %

front-page HTML weight under gzip

59,415 B uncompressed against 9,940 B with Accept-Encoding: gzip

404

response to a URL that does not exist

a real 404, not a soft 200 that pollutes the index

2 of 2

canonical redirects behaving

http→https returns 301 and www→apex returns 301

Security and stack

10

security headers present

HSTS with preload, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, COOP, CORP, X-Permitted-Cross-Domain-Policies and Origin-Agent-Cluster

TLS 1.3

transport, over HTTP/2

TLS_AES_256_GCM_SHA384 cipher, Let's Encrypt certificate for kenetg.com

0

X-Powered-By headers

none is emitted. The stack is not hidden either, and the headers show it: server: nginx, the Vary listing next-router-* (Next.js App Router) and the Auth.js cookies. The CMS does live on a separate host: /admin 301s to admin.kenetg.com

2

self-referential hreflang links per page

es and x-default pointing at the URL itself, on all 12. The site is monolingual (<html lang="es">), so they are redundant rather than wrong: there is no translation to announce

One number that is NOT above: today robots.txt declares no dedicated groups for GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot or Google-Extended. They come in through the User-agent: * wildcard, so they do have access today — but naming them one by one documents the intent and protects against a future Disallow shutting them out by accident. It is an open improvement, and it appears here because a case study that only shows what went well is not a case study, it is an ad.

Validation

05

None of the above has to be taken on trust. These commands run in any terminal and return the same numbers as block 4 — or whatever the numbers are on the day you run them, which is why each one carries a date.

  1. curl -sI https://kenetg.com/ | grep -i -E 'strict-transport|content-security|x-frame'

    the security headers, served on every response

  2. curl -s https://kenetg.com/robots.txt

    no global Disallow, the sitemap declared and both llms files announced

  3. curl -s https://kenetg.com/sitemap.xml | grep -c '<loc>'

    12

  4. curl -s https://kenetg.com/ | grep -c '<script type="application/ld+json">'

    2 — the entity graph and the page layer

  5. curl -s -o /dev/null -w '%{http_code} %{time_starttransfer}s\n' https://kenetg.com/llms.txt

    200, and whatever time it takes from where you are

  6. curl -s -o /dev/null -w '%{http_code}\n' https://kenetg.com/una-url-que-no-existe/

    404

What is missing from this page, plainly

  • The GEO measurement panel from block 3: it does not exist yet. It is the most important work left.
  • The client testimonial: waiting on KenetG to give it in his own words. I would rather leave a gap than write a sentence myself and sign someone else's name to it.
  • Screenshots of the AI answers: they go here once the panel has run and there is something real to capture.

What I learned

06

The technical half of GEO is the easy half. A properly linked entity graph, a curated llms.txt, unblocked crawlers and server rendering are known work: you ship it, you check it from outside, and it is done. The whole of block 4 on this page is generated with curl in two minutes.

The hard half is the other one: knowing whether it did anything. And here this case arrives carrying a debt I will put in writing — it was shipped before the measurement was set up, and with no prior baseline there is no honest way to attribute a result. I can show you what was built; I cannot show you the effect.

So the order changes for the next one. First the query panel and its reference run, with a date; then the code. It costs an extra week up front and it is the difference between a case study and a brochure.

Which is where the rule that governs this entire page comes from: "shipped and verifiable" can be written down; "shipped, and therefore working" does not get written until there is a panel behind it. If someone sells you GEO and cannot tell you how they will measure it, they are selling you the easy half at the price of the hard one.

Want yours, with block 3 filled in from day one?

I will run a free mini-audit: a handful of real queries from your category, run live, to see who gets cited today and where you are invisible. That run is your baseline — and with it, before-and-after becomes something you can actually measure.

Email me

Visit the client siteCanonical link to this case