This page covers the standard setup for a site you host yourself behind Cloudflare. If your site lives on a site builder or e-commerce platform (Lovable, Base44, Shopify, and others), use the dedicated guide in Hosted platform guides below instead.
Prerequisites
- An Encited account and API key (Settings → API Keys)
- A domain added + verified in your Encited dashboard
- Cloudflare account with Workers enabled
- Your domain's DNS managed by that Cloudflare account, with the A/CNAME record proxied (orange cloud), since Worker routes only run on traffic that passes through Cloudflare's proxy
Standard setup
Create a new Worker
Open Cloudflare dashboard → choose a "Hello World" Worker → Deploy → Edit Code
Paste the snippet below into the Worker editor
// encited.js (Cloudflare Worker)export default {async fetch(req, env) {// Only handle public GET navigationsif (req.method !== 'GET') return fetch(req);// Treat missing/empty Accept and bare '*/*' as HTML so crawler tests// (curl without -H, default fetch) still route through prerender.// Asset requests from browsers send specific Accept (e.g. 'text/css,*/*;q=0.1')// so they won't match.const accept = (req.headers.get('accept') || '').trim();const isHtmlRequest = !accept || accept === '*/*' || accept.includes('text/html');if (!isHtmlRequest) return fetch(req);const headers = new Headers();headers.set('x-lovablehtml-api-key', env.LOVABLEHTML_API_KEY);headers.set('accept', 'text/html');const forward = ['accept-language','sec-fetch-mode','sec-fetch-site','sec-fetch-dest','sec-fetch-user','upgrade-insecure-requests','referer','user-agent',];for (const name of forward) {const v = req.headers.get(name);if (v) headers.set(name, v);}try {const r = await fetch('https://encited.com/api/prerender/render?url=' + encodeURIComponent(req.url),{ headers, redirect: 'manual' },);// 301 = configured redirect rule matched - forward to clientif (r.status === 301) {const loc = r.headers.get('location');if (loc) {return new Response(null, {status: 301,headers: { location: loc, 'cache-control': 'no-store' },});}}// 304 = not pre-rendered, pass through to originif (r.status === 304) {return fetch(req);}if (r.status === 200 && (r.headers.get('content-type') || '').includes('text/html')) {const responseHeaders = new Headers(r.headers);for (const name of ['content-encoding', 'content-length', 'transfer-encoding', 'connection', 'keep-alive']) {responseHeaders.delete(name);}responseHeaders.set('content-type', 'text/html; charset=utf-8');return new Response(r.body, { status: 200, headers: responseHeaders });}} catch {// Prerender unreachable → fall through so visitors still get the site}return fetch(req);},};
Add the API key secret
Under Variables and Secrets, add a secret named LOVABLEHTML_API_KEY or run: wrangler secret put LOVABLEHTML_API_KEY
Confirm your DNS record is proxied
Routes need your domain's DNS to be managed in the same Cloudflare account. In DNS → Records, the A or CNAME record for yourdomain.com must show an orange cloud (Proxied), not gray (DNS only). The Worker only runs on traffic that passes through Cloudflare's proxy.
Add a route to your Worker
Go to your Worker → Settings → Domains & Routes → Add Route → enter yourdomain.com/*. If your site is reachable on both yourdomain.com and www.yourdomain.com, enter *yourdomain.com/* instead so both are covered.
Hosting on a subdomain? Use blog.yourdomain.com/* for just that subdomain, or *.yourdomain.com/* to cover every subdomain.
Set Failure mode
Set to Fail open (proceed) and save. If the Worker ever errors, requests continue straight to your origin instead of failing.
Let crawlers through Cloudflare's bot settings
If you use Bot Fight Mode or AI crawler blocking (Security → Bots), allow the crawlers you want pre-rendered. Those protections run before your Worker, so a blocked crawler never reaches it.
Deploy the Worker
It can take a couple of minutes to start working.
How to Test
- Call the render API directly and verify
x-lovablehtml-render-cache: hit | miss - Hit your site as a crawler and verify the response carries
x-lovablehtml-render-cache. That header is what proves the Worker served rendered HTML - Verify a normal browser request falls through to your existing origin
# 1) Call the Encited render API directlycurl -sS -D - -o /dev/null \-H "x-lovablehtml-api-key: <API_KEY>" \-H "Accept: text/html" \"https://encited.com/api/prerender/render?url=https%3A%2F%2Fyour-domain.com%2Fyour-page"# Look for:# - HTTP/1.1 200# - x-lovablehtml-render-cache: hit | miss# - x-lovablehtml-snapshot-key: ...
# 2) Hit your site with an HTML Accept headercurl -sS -D - -o /dev/null \-H "Accept: text/html" \-A "Googlebot" \"https://your-domain.com/your-page"# Look for:# - HTTP/1.1 200# - x-lovablehtml-render-cache: hit | miss## A plain 200 with content-type: text/html is what your origin returns# too. The x-lovablehtml-render-cache header proves the Worker served# rendered HTML.
# 3) Browser passthrough (Encited returns 304; the Worker serves your origin)curl -sS -D - -o /dev/null \-A "Mozilla/5.0" \"https://your-domain.com/your-page"# Look for:# - no x-lovablehtml-* headers (the response came from your origin)
Best Practices
- Keep secrets out of git: Store keys in your platform's secret manager or env vars; rotate/revoke when compromised.
- Don't proxy static assets: Only call Encited for HTML document requests. Always pass through JS/CSS/images/fonts.
- Handle 304 passthrough: 304 means prerendering doesn't apply; fall back to your origin. If you get a
301instead, a redirect rule matched; forward itsLocationheader to the client. - Invalidate after content changes: Use the cache invalidation endpoints (optionally with prewarm) after deploys or CMS updates.
Hosted platform guides
Hosting on a site builder or e-commerce platform instead? Each guide below walks the Cloudflare setup for that platform end to end:
Site builders through Cloudflare
Keep Cloudflare in front of your custom domain with a Worker that serves crawlers pre-rendered HTML and forwards visitors to your hosted project.
E-commerce platforms through Cloudflare
Your DNS keeps pointing at the platform. A Worker route in your Cloudflare zone intercepts crawler requests before they reach the store.
Need help? Check the full API reference for prerender, cache, and analytics endpoint docs, or jump directly to Analytics API, or contact us if you run into issues.




