Building html-editor.registermysite.com

Complete step-by-step guide to the Cloudflare Workers AI + Vectorize + R2 RAG system that generates websites from stored HTML templates.

1. Overview

This project extends Cloudflare’s official llm-chat-app-template into a specialized HTML generator. When a user asks for a page, the Worker:

  1. Embeds the user request with Workers AI
  2. Searches a Vectorize index for similar HTML templates
  3. Loads the full HTML of the best matches from R2
  4. Injects those templates into the system prompt
  5. Streams a complete HTML document from an LLM

The frontend shows a live CodeMirror editor and iframe preview while the model generates, and users can save results to a personal dashboard (browser localStorage).

2. Architecture

1
Workers AI — embeddings @cf/baai/bge-base-en-v1.5 (768 dimensions)
2
Vectorize Index html-templates — semantic search over template embeddings + metadata
3
R2 Bucket html-templates — full HTML files (avoids Vectorize metadata size limits)
4
Workers AI — generation @cf/meta/llama-3.1-8b-instruct-fp8 (32k context) streams the final page
5
Static frontend Assets binding serves public/ — chat UI, dashboard, docs, admin

3. Prerequisites

4. Start from the official chat template

git clone https://github.com/cloudflare/templates.git
cd templates/llm-chat-app-template
npm install

Or use the project already structured under this repo (src/, public/, wrangler.jsonc).

If you hit a peer dependency conflict between wrangler and @cloudflare/workers-types, align workers-types to the version wrangler expects (e.g. ^5.20260811.1), then:

rm -rf node_modules package-lock.json
npm install

5. Create Vectorize index and R2 bucket

Run these once per account (names must match the bindings):

npx wrangler vectorize create html-templates \
  --dimensions=768 \
  --metric=cosine

npx wrangler r2 bucket create html-templates

768 dimensions matches @cf/baai/bge-base-en-v1.5. Cosine similarity is the usual choice for semantic search over text embeddings.

6. Add bindings in wrangler.jsonc

{
  "ai": { "binding": "AI" },
  "vectorize": [{
    "binding": "VECTORIZE",
    "index_name": "html-templates"
  }],
  "r2_buckets": [{
    "binding": "TEMPLATES_BUCKET",
    "bucket_name": "html-templates"
  }],
  "assets": {
    "binding": "ASSETS",
    "directory": "./public"
  }
}

Update src/types.ts so Env includes AI, VECTORIZE, TEMPLATES_BUCKET, and ASSETS.

7. Ingesting HTML templates

Templates are not loaded automatically from the sample-templates/ folder. That folder is only a local source of HTML. At runtime the Worker only sees what is in R2 + Vectorize.

Ingest API

POST /api/ingest body:

{
  "id": "saas-landing",
  "name": "Modern SaaS Landing Page",
  "description": "Dark SaaS landing with hero, features, and pricing…",
  "tags": "saas,landing,pricing,dark",
  "html": "<!DOCTYPE html>..."
}

What the Worker does

  1. Stores full HTML in R2 at templates/{id}.html
  2. Builds embed text: name + description + first 1,500 chars of HTML
  3. Runs the embedding model
  4. Upserts vector + metadata (name, description, r2Key, tags) into Vectorize

Example curl

HTML=$(cat sample-templates/saas-landing.html | jq -Rs .)

curl -X POST https://html-editor.registermysite.com/api/ingest \
  -H "Content-Type: application/json" \
  -d "{
    \"id\": \"saas-landing\",
    \"name\": \"Modern SaaS Landing Page\",
    \"description\": \"Dark-themed SaaS landing with hero, features, pricing\",
    \"tags\": \"saas,landing,pricing,dark\",
    \"html\": $HTML
  }"

Management

Security: Protect /api/ingest and delete routes in production (Cloudflare Access, secret header, or auth). They ship open for local development convenience.

Recommended template size

SizeGuidance
5–20 KBBest for quality + prompt fit
Up to ~50 KBStill usable
Much largerSplit into sections; only first 1.5k chars are embedded

8. RAG chat handler

On POST /api/chat the Worker:

  1. Reads the latest user message
  2. Embeds it with bge-base-en-v1.5
  3. Queries Vectorize (topK: 3, full metadata)
  4. Fetches each match’s HTML from R2 via r2Key
  5. Builds a system prompt that includes the retrieved HTML (capped ~6,000 chars each)
  6. Calls the chat model with streaming and returns SSE

If retrieval fails, chat still works without context — RAG is additive, not required for the request to succeed.

System prompt goals

9. Frontend features

Implemented under public/:

10. User dashboard (My Templates)

/dashboard.html stores user-generated pages in browser localStorage (per device, no account required yet).

Storage key: html_gen_saved_templates. Cap: 50 templates. When OAuth is added later, the same shape can move to R2/D1 per user.

11. Optimize HTML for embeddings

Retrieval quality depends heavily on ingest text:

12. Generation parameters

Model: @cf/meta/llama-3.1-8b-instruct-fp8 (32k context). Recommended inputs for full-page HTML with RAG:

const inputs = {
  messages,
  max_tokens: 6144,        // room left for RAG context in the 32k window
  temperature: 0.15,       // deterministic structure
  top_p: 0.9,
  top_k: 40,
  repetition_penalty: 1.08,
  stream: true,
};

Avoid setting max_tokens near half the context when the system prompt already contains multiple full templates — input + output must fit in 32k tokens total.

13. Admin page

sample-templates/admin-dashboard.html is a simple client-side password gate (default Password123) with links to the generator, template list API, and Cloudflare product dashboards.

Not real security. The password is visible in page source. For production admin, use Cloudflare Access or proper OAuth instead.

14. Deploy and operate

npm run deploy

After deploy:

  1. Ingest sample templates via /api/ingest
  2. Open the site and try an example prompt from the left drawer
  3. Save a result to My Templates and reopen it from the dashboard

Point a custom domain (e.g. html-editor.registermysite.com) at the Worker in the Cloudflare dashboard.

Useful routes

PathPurpose
/Generator UI
/dashboard.htmlSaved templates
/docs.htmlThis documentation
/api/chatStreaming RAG chat
/api/ingestAdd template (R2 + Vectorize)
/api/templatesList / delete templates

15. Quick checklist

Built on Cloudflare Workers AI · Vectorize · R2 · the official LLM chat template.