Integrating llms.txt with Convert’s Server-Side JavaScript SDK (How-To)
Learn how to A/B test llms.txt with Convert’s server-side JS SDK. Decide variants per request, keep assignments consistent, and measure AI traffic.
Author: | Ahmed Abbas |
IN THIS ARTICLE YOU WILL
- Understand why llms.txt matters right now
- Set up your environment
- Understand the prerequisites
- Discover the architecture
- Implement the integration step by step
- Configure caching and CDN
- Troubleshoot common issues
- Review key FAQs
- Access deeper implementation resources
Audience: Developers and tech-savvy marketers who want consistent experiment decisions for every HTTP request—including /llms.txt—so AI crawlers and humans are assigned the same variant.
Why this matters (right now)
AI assistants and search tools are beginning to look for a plain-text endpoint called /llms.txt
to understand and cite your site. These crawlers don’t execute JavaScript, so client-side A/B testing won’t change what they see. To test and learn what content in /llms.txt
drives quality AI referrals, you need to decide variations on the server and ensure the same visitor ID is used across routes like /page/*
and /llms.txt
.
Looking for the deep dive with full code? See the public SDK wiki:
Deeper implementation: https://github.com/convertcom/javascript-sdk/wiki/LLMTesting
What you’ll build
A small server-side integration that:
-
Creates a single SDK instance at app start.
-
Generates a consistent visitor ID (cookie first; deterministic hash fallback).
-
Decides all active experiments for every request (not just
/llms.txt
). -
Serves a text/plain response for
/llms.txt
using the decided variant. -
Adds caching headers for consistency and UTM tags for analytics.
References you may need while implementing analytics & privacy later:
- Pushing experiment metadata to analytics platforms (client side patterns you can adapt): “Complete Guide: Creating Integrations with Convert.com”. Source: Complete Guide: Creating Integrations with Convert.com
- Hiding experiment names (IDs instead of names): Data Anonymization. Source: Prevent Experiment Details Data Leak with Data Anonymization
Prerequisites
- SDK & docs: You’ll use Convert’s JavaScript SDK in a server context (Node.js, Edge, etc.).
Source (SDK reference): Convert JavaScript SDK Docs - An experiment (A/B/n) in Convert for your llms.txt content (e.g.,
llms-txt-content-test
). - Two or more variant files (or templates) you’ll serve as
text/plain
. - Ability to set/read a first-party cookie (fallback hash for crawlers that ignore cookies). Privacy/cookie consent considerations: see CMP guidance. Source: Integrate with Cookie Consent Management Platforms (Cookiebot)
Architecture at a glance
-
Every request passes through middleware that:
-
Reads/set a visitor ID (cookie → deterministic hash fallback).
-
Creates an SDK context and calls
runExperiences()
to decide all active experiments. -
Stores the decisions so any route (pages, APIs,
/llms.txt
) sees the same variation.
-
-
/llms.txt
route:-
Reads the decided variation for your
llms-txt-content-test
experiment. -
Returns the matching plain-text content (
Content-Type: text/plain; charset=utf-8
). -
Adds private caching and
Vary: Cookie
(or bypasses CDN) to prevent cross-visitor mixing.
-
Why decide on every route?
It guarantees consistent bucketing when a crawler or a user hits /page
and /llms.txt
in any order, and prevents drift from stale cookie/storage state across endpoints. Source (analytics patterns you’ll connect to afterwards): Complete Guide: Creating Integrations with Convert.com
Quick start (lightweight)
Below are conceptual snippets to keep this page approachable. Full, runnable examples (Express/Laravel, data stores, edge runtimes, UTM injection, race-condition guards, CDN examples) are in the SDK wiki:
Deeper implementation: https://github.com/convertcom/javascript-sdk/wiki/LLMTesting
1) Decide on every request
-
Initialize one SDK instance at startup.
-
Middleware:
-
Ensure
visitorId
(cookie → UA/IP hash fallback for crawlers). -
context = sdk.createContext(visitorId)
-
variations = context.runExperiences()
-
Attach
{ visitorId, variations }
toreq
(or framework equivalent).
-
Tip: When privacy requirements demand it, enable Data Anonymization so experiment/variation IDs (not names) flow into any analytics tags you add later.
Source: Prevent Experiment Details Data Leak with Data Anonymization
2) Serve plain text at /llms.txt
-
Find your llms.txt experiment in
variations
(by key or ID). -
Pick the matching content (file, KV, DB, or template).
-
Return with:
-
Content-Type: text/plain; charset=utf-8
-
Recommended cache:
Cache-Control: private, max-age=86400
andVary: Cookie
-
Avoid public/CDN caching or configure a custom cache key per visitor.
-
Why private caching? It preserves per-visitor consistency (statistical validity) while avoiding global CDN mixing.
Source (server-side considerations for non-JS surfaces): Google AMP and Convert Experiences
3) Add measurable UTM tags
Because plain-text endpoints can’t run trackers, add UTMs to links inside your llms.txt
variants, e.g.:?utm_source=llm&utm_medium=llms-txt&utm_campaign=ai-discovery&utm_content={variation_key}
.
Then read these on landing pages to attribute sessions and conversions. Source (how to move experiment context into analytics): Complete Guide: Creating Integrations with Convert.com
Caching & CDN guidance
Do:
-
Cache-Control: private, max-age=86400
-
Vary: Cookie
(or bypass CDN / custom cache key per visitor)
Avoid:
-
public
caching (mixes variants across visitors) -
no-store
for/llms.txt
(hurts consistency for low-frequency crawlers)
On cookie policies/consent gates that may block cookies, keep your hash fallback for crawlers to maintain consistency without personal data. Source: Integrate with Cookie Consent Management Platforms (Cookiebot)
Troubleshooting
-
Different variants on
/llms.txt
vs pages
Ensure the SDK middleware runs before all routes and always callsrunExperiences()
. -
No traffic attributed to variants
Verify yourllms.txt
URLs include UTMs; confirm they’re captured in your analytics tool.
Source (analytics data patterns to adapt): Complete Guide: Creating Integrations with Convert.com - Privacy concerns about exposing names
Turn on Data Anonymization to send IDs to third parties instead of names.
Source: Prevent Experiment Details Data Leak with Data Anonymization - Consent-first sites
If your CMP delays/blocks cookies, keep your deterministic hash fallback for crawlers (and consider running llms.txt decisions in a consent-agnostic scope since it’s plain text and doesn’t set client storage).
Source: Integrate with Cookie Consent Management Platforms (Cookiebot)
FAQs
Does server-side deciding change stats validity?
No—random assignment + consistent exposure + enough sample = valid inference. (Server-side simply moves the decision earlier.)
Can I test structure as well as content?
Yes—try different formats (markdown vs. plain text), link density, or section order. Use UTMs to measure downstream quality.
Source (analytics plumbing you’ll use): Complete Guide: Creating Integrations with Convert.com
Where do I find SDK reference and API shapes?
Use the Convert JavaScript SDK docs for server contexts.
Source: Convert JavaScript SDK Docs
Implementation references (full code & diagrams)
-
Primary deep dive (with Express, Laravel, Edge, caching, UTM injection, concurrency guards, and SVG diagrams):
https://github.com/convertcom/javascript-sdk/wiki/LLMTesting - SDK reference (methods, context, data store contracts):
https://convertcom.github.io/javascript-sdk/