Skip to content

Installation

Deploy the AI Pages middleware on your hosting platform. Nine paths, all generated for you, plus how to prove the install works.

11 min read
On this page

Installing AI Pages means putting a small piece of middleware in front of your site. It reads the user agent on every request, and for the ones that match a crawler in your list it asks Trakkr for the optimized version of that page. Everything else, including all human traffic, goes straight to your origin.

The code runs to well under 100 lines on most platforms, the deploy is usually one file, and the setup wizard generates the snippet with your API key already in it. The wizard walks you through it. This page is the reference: which path fits your site, what the code does, and how to prove it is working.

The five setup steps

Open /ai-pages on a brand that has no AI Pages configuration and the wizard starts.

StepWhat you do
ConfigureEnter the domain you want optimized
PlatformPick where your site is hosted
CrawlersChoose which of the sixteen crawler signatures to optimize for
FeaturesTurn the five optimizations on or off
InstallCopy the generated code, follow the platform steps, click Complete setup

The wizard estimates about five minutes end to end, which is honest for everything except the DNS proxy path.

After setup, the Settings button on the dashboard reopens the wizard. Changing the platform generates different code. Changing the crawler list or the feature set changes server-side configuration, but the crawler list is compiled into your deployed snippet, so a crawler change means redeploying the code as well.

Pick a platform

Nine paths. The right one depends on where requests actually terminate, not on which CMS you write in.

PathRuntimeUse when
Cloudflare WorkersCloudflare EdgeCloudflare already fronts your domain
Vercel Edge MiddlewareVercel EdgeYour Next.js app is deployed on Vercel
Netlify Edge FunctionsNetlify Edge (Deno)You are on Netlify
Next.js MiddlewareNext.js Edge RuntimeNext.js, hosted somewhere other than Vercel
AWS CloudFrontLambda@Edge (Node.js)CloudFront sits in front of your site
WordPress PluginPHPWordPress with file or FTP access
Node.js / ExpressNode.jsYou run your own Node server
Nginx / OpenRestyOpenResty (Lua)Self-hosted behind Nginx with OpenResty
Other / ManualCloudflare DNS proxyWebflow, Squarespace and other hosts that allow a Cloudflare proxy but will not run your code. Not Shopify or Wix

Cloudflare Workers and Other end in the same place: a worker at Cloudflare's edge. The difference is whether Cloudflare is already in front of you. If it is, take the Cloudflare path. If it is not, take Other and the wizard adds the DNS migration to the steps.

Before you start

  • A brand on Growth or Scale. A Growth trial counts, and access unlocks on its own.
  • The domain you want optimized, apex (nike.com) or subdomain (shop.nike.com), where you control DNS or hosting.
  • Deploy access for the path you chose: Cloudflare worker permissions, a Vercel project, FTP for WordPress, and so on.
  • Fifteen minutes, more on the DNS proxy path because nameserver changes take time to propagate.

The generated code contains your API key as a literal constant, not an environment variable. Treat the file like any other deploy secret. If it leaks, regenerate the key from AI Pages settings and redeploy.

What the middleware does

Every path runs the same five checks. Only the syntax and the file location change.

  1. 1.If the path ends in a static asset extension (.js, .css, an image, .pdf, .xml, .txt), pass through and stop.
  2. 2.Lowercase the User-Agent header and look for any of your selected crawler signatures in it.
  3. 3.No match: pass through to your origin.
  4. 4.Match: POST to https://prism.trakkr.ai with the URL, pathname and crawler name, and your key in an X-API-Key header. The timeout is 1 second on Cloudflare and 1.5 seconds elsewhere.
  5. 5.If Trakkr returns optimized HTML, serve it with X-Prism-Optimized: true and X-Prism-Cache, plus Cache-Control: no-cache, no-store, private, max-age=0 and Vary: User-Agent. On anything else, including a 202 response, serve your original page.

The cache headers matter. A page cache or CDN that stores the crawler's optimized response would hand it to every later visitor, people and search engines included. If you merge the logic into your own code, keep them.

Cloudflare Workers

Deploy one worker and bind it to every hostname a crawler can reach. Cloudflare only runs a worker on a matching route, and a route for the apex does not cover www:

Text
yourdomain.com/*
www.yourdomain.com/*

Keep both when your site redirects between them, check that both DNS records are proxied (orange cloud, not grey), and check that no more specific route is assigned to a different worker or to none. Cloudflare's free Workers plan is enough to verify an install; review their current limits before running a high-traffic site through it.

Vercel and Next.js

Save the generated code as middleware.ts at the project root, next to package.json, then commit and push. The snippet ships its own config.matcher and skips /_next/ and /api/ internally. If you already have a middleware file, merge the logic into your existing function rather than replacing the file.

Netlify Edge Functions

Save the file as netlify/edge-functions/prism.ts and register it in netlify.toml:

toml
[[edge_functions]]
  function = "prism"
  path = "/*"

Edge functions run on Deno, which is why the generated imports are Deno-style.

AWS CloudFront

Create a Node.js 20.x Lambda function in us-east-1, paste the code, publish a version rather than using $LATEST, then attach that version to your distribution as a viewer-request trigger. Viewer-request responses are capped at 40 KB, and the generated code checks the size and falls through to your origin when the optimized HTML is larger.

WordPress

Save the generated file as wp-content/mu-plugins/trakkr-prism.php. Must-use plugins load with no activation step; confirm Trakkr Prism appears under Plugins → Must-Use. It hooks send_headers at priority 1 and skips admin, AJAX, REST, cron and non-GET requests. Managed hosts that block writes to mu-plugins/ need the DNS proxy path instead.

Most WordPress hosts cache whole pages (SiteGround, WP Engine, Kinsta, LiteSpeed servers, and plugins such as WP Rocket). Version 1.1.0 of the plugin, shown in the file header, marks every optimized response as uncacheable for all of them, so purge your page cache once after you upload it. Two things follow from the cache sitting in front of WordPress:

  • A crawler that hits a cached page gets your original page, because WordPress never runs. Pages a crawler reaches first are optimized. To optimize every crawl, ask your host to bypass the page cache for the crawler user agents you selected.
  • Version 1.0.0 did not send these headers. If your file header says Version: 1.0.0, replace the file with the current code from View integration code, then purge the cache.

Node.js and Nginx

For Express, save the file as prism-middleware.js and register it ahead of your routes with app.use(prism) so it runs before your handlers. For Nginx you need OpenResty and lua-resty-http (opm get ledgetech/lua-resty-http), then drop the generated access_by_lua_block into your server {} block and reload. Nginx is the most involved path and only worth it if you already run OpenResty.

Other (Cloudflare DNS proxy)

For platforms that will not run your code. You are not modifying your site, you are putting Cloudflare in front of it: sign up for Cloudflare (no cost), add your domain, make sure your main A or CNAME record is proxied, move your nameservers at your registrar, then deploy the worker and add the routes exactly as in the Cloudflare path above.

Verifying the install

While AI Pages has no data yet, the page shows a status screen with a Check status button. That runs a real probe: it requests your homepage with a GPTBot user agent and a __trakkr_prism_probe parameter, then waits up to twelve seconds for the resulting event to arrive.

You get back three dots, API key, Domain and Middleware, plus a message and a specific suggestion. The suggestions are specific by design: a Cloudflare domain on grey-cloud DNS is told to switch to proxied, a worker running an old key is told to redeploy, and a missing worker is shown the exact routes it needs.

You can also probe the Cloudflare path by hand. Keep the probe parameter, because the worker only adds its diagnostic headers when it is there:

Terminal
curl -sS -D - -o /dev/null \
  -A "Mozilla/5.0 (compatible; GPTBot/1.0; +https://openai.com/gptbot)" \
  "https://yourdomain.com/?__trakkr_prism_probe=manual"

An optimized response carries X-Prism-Optimized: true and may include the diagnostic X-Prism-Cache header. If your original page is served, use X-Prism-Middleware: active and X-Prism-Forwarding to check whether the worker ran. Test the URL again later before assuming optimization is unavailable. If the middleware header is missing entirely, fix the deployment and routes before touching the API key.

Where crawler hits appear, and how fast

WhereSourceLag
AI Pages → Recent CrawlsTrakkr's live storeSeconds
CrawlersA scheduled pullUp to 30 minutes

Setup creates a crawler tracking connection for the domain automatically, and that connection is pulled on a 30-minute cadence because it merges with every other source you have connected. So an empty Crawlers feed right after a fresh install usually means the first pull has not run yet. Recent Crawls is the one to watch in the first few minutes.

When the install does not work

The middleware never runs

Either it did not deploy, or it deployed somewhere the request does not go. On Cloudflare, confirm the current version is deployed to production, add exact routes for both apex and www, confirm both DNS records are proxied, and look for a more specific route overriding yours. Elsewhere, confirm middleware.ts is at the project root, check wp-content/mu-plugins/, or run nginx -t. The usual cause is a deploy to the wrong hostname or environment.

Visitors see the optimized page

Request a page with a normal browser user agent. If the response carries X-Prism-Optimized: true, a page cache stored a crawler's response and is serving it to everyone:

Terminal
curl -sS -D - -o /dev/null \
  -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" \
  "https://yourdomain.com/about/"

Deploy the current code from View integration code, which sends Cache-Control: no-cache, no-store and Vary: User-Agent with optimized pages, then purge your host, plugin and CDN caches. On SiteGround, use Speed Optimizer → Purge SG Cache or run wp sg purge.

Trakkr rejects the key

The check reports the forwarding status as unauthorized. Your deployed code holds an old key, most often because it was regenerated in Trakkr afterwards. Copy the current code from View integration code, deploy it, and check again.

The optimized page looks wrong

Run the URL through Test Your Pages on the Overview tab and read the analysis. The usual causes are content that only appears after a scroll, content behind a consent banner that auto-dismisses for people but not bots, and lazy-loaded sections that need a trigger.

The site is down after installing

Roll back first: remove the worker, delete middleware.ts, or remove the plugin file. Your site returns immediately. The middleware is built to fail open, but a syntax error in the file itself can break the whole deploy, so debug it outside production.

Common questions

Do I have to redeploy when I change settings?

Yes, if you change the crawler list or the platform, because both are compiled into the generated snippet. Changing the five optimization toggles does not require redeploying the integration, but may not appear immediately on every URL. Check the served response after changing them.

Why is the dashboard still empty a day after installing?

Because real crawlers arrive on their own schedule and cannot be summoned. A correct install can sit quiet for a day or two. Use Check status and the curl probe to confirm the wiring, then wait.

Does the middleware slow the site down for people?

No. A request that does not match a crawler signature is passed to your origin with no extra network call, and static assets are skipped before the user-agent check even runs.

Can I run this alongside crawler tracking I already installed?

Yes, and AI Pages sets up its own crawler tracking connection for the domain during setup. If you also run the standalone tracker described in Install crawler tracking, keep one connection per domain so requests are not counted twice.