The practical handbook · 18 October 2026

Build it. Deploy it. Understand it.

A human-friendly, step-by-step guide to taking a website from your computer to the internet with Cloudflare. Learn the requirements, choose the right platform, deploy plain HTML/CSS/JavaScript or a framework, and prepare your project for real users.

01Understand the options
02Deploy step by step
03Secure the result

01 / Before you begin

What are you building?

Do not add complicated tools just because they are popular. First decide what the website needs to do.

A · STATIC

Plain HTML, CSS and JavaScript

A portfolio, landing page, business website, documentation site or browser-only tool. These files can be published directly; no React, Node server or build step is required.

Learn the static deployment path ↓
B · FRAMEWORK

Vite or another framework

React, Vue, Svelte, Angular, Astro and similar tools often compile source code into a folder of static files. The build command and output folder must match the project.

Learn framework settings ↓
C · FULL STACK

Website plus backend

Login, protected APIs, webhooks, database access, scheduled tasks and server-rendered routes need server-side logic. Cloudflare Workers can run that logic.

Learn Workers ↓
What you need at minimum: a Cloudflare account, website files, and a browser. GitHub is recommended for version control and automatic deployments. A custom domain is optional for the first deploy. You do not need to rent a traditional server to publish a static site.

02 / Choose the right product

Cloudflare Pages or Workers?

Both can deliver websites. The right choice depends on the project and the kind of runtime it needs.

Cloudflare Pages

Useful for straightforward static websites, static framework output and existing Pages projects. Git integration can rebuild the site whenever you push changes. Pages Functions can add server-side endpoints to a Pages project.

  • Static HTML, CSS, JS and images
  • Frameworks that produce static output
  • Git-connected builds and preview URLs
  • Functions for supported server-side routes
Official Pages documentation ↗

Cloudflare Workers

Useful for APIs, request handling, server-side logic, and modern full-stack applications. Workers Static Assets can serve frontend files and combine them with Worker code.

  • Static assets plus dynamic routes
  • APIs and webhook handlers
  • Bindings to supported data/storage services
  • Broader Workers platform capabilities
Official Workers documentation ↗
Practical recommendation: for a small HTML/CSS/JS website, Pages is a simple starting point, and Workers Static Assets is another valid route. Cloudflare's current guidance recommends Workers for new projects needing broader platform capabilities. For an existing Pages project, there is no reason to migrate without a real need. Check the current docs before committing to framework-specific features.

03 / Deployment tutorial

Publish plain HTML, CSS and JavaScript

Follow these steps in order. This is the simplest path for a site made of files such as index.html, styles.css and script.js.

1

Prepare the project folder

Keep your homepage at the top of the folder you intend to publish. For example:

my-website/
├── index.html
├── about.html
├── css/
│   └── styles.css
├── js/
│   └── app.js
└── images/
    └── logo.png

Check that paths in your HTML match the real folders and filenames. Deployed environments are case-sensitive, so Logo.png and logo.png may be different files.

2

Test it locally

Open index.html in a browser for a basic check. If your project uses JavaScript modules or fetch requests, use a local development server. Test on mobile and desktop; click every link; inspect the browser console for errors.

A form that looks correct is not automatically functional. Static hosting alone does not process submissions. A working form needs a backend, form service or suitable API.

3

Push the project to GitHub

Create a repository on GitHub. In a terminal opened inside the project folder, run:

git init
git add .
git commit -m "Add website"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY.git
git push -u origin main

Replace the sample URL with your own repository. If the project already has Git configured, check git status and git remote -v first instead of reinitializing it. Never commit access tokens or passwords.

4

Create a Pages project

Sign in to Cloudflare and open Workers & Pages. Choose to create an application, select Pages, then connect to Git. Authorize access to the right GitHub account/repository, select the repository and production branch (commonly main).

5

Set the build options correctly

For plain static files that need no build:

  • Production branch: main (or the branch you actually use)
  • Build command: exit 0 is the documented no-build option
  • Build output directory: the directory containing the deployed files and top-level index.html

If the files are at the repository root, use the dashboard's root-directory option. If they live in a folder such as site, use that folder. Do not enter dist unless the files really are in dist.

6

Deploy and test the live URL

Start the deployment and wait for the successful status. Cloudflare gives the project a *.pages.dev URL. Open it on your phone and computer. Check the homepage, navigation, stylesheets, images, links, mobile layout and any forms. A green deployment status does not guarantee every feature works.

7

Make future updates safely

With Git integration enabled, pushes to the configured production branch trigger deployments. A safer workflow is to create a branch, make a change, preview it, and merge when it looks right. Check the deployment result after every production update.

Official reference: Cloudflare's Static HTML deployment guide ↗

04 / Dynamic websites

Workers and APIs, explained simply

Your browser code is public. A Worker can perform trusted server-side work without asking you to manage a traditional server.

When you need a Worker

  • An API endpoint for your frontend
  • A payment-provider webhook
  • Server-side use of a private API key
  • Authentication and access checks
  • Data processing or scheduled work
  • Dynamic responses alongside static assets

What to prepare

  • Cloudflare account and project permissions
  • JavaScript or TypeScript source code
  • Node.js/npm and Wrangler for common CLI workflows
  • Configuration for routes and asset directories
  • Database/storage resources if needed
  • Server-side secrets and access policies

A tiny Worker API example

This example returns a JSON health response. It is a learning example, not a complete production API.

export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.pathname === "/api/health") {
      return Response.json({ status: "ok" });
    }

    return new Response("Not found", { status: 404 });
  }
};

The env argument provides configured bindings and secrets. The example does not use it yet. A real API may need authentication, authorization, input validation, rate limits, safe error handling and logging that avoids sensitive data.

Deploy static assets with Workers

For the CLI workflow, Cloudflare provides a project starter. One common starting command is:

npm create cloudflare@latest -- my-static-site

Follow the prompts and select a static-site or suitable full-stack starter. For an existing project, follow the current Workers Static Assets instructions and point the asset directory at the actual deployable files. Use npx wrangler dev to test locally and npx wrangler deploy when the project is configured and ready. Exact setup depends on the starter and its Wrangler configuration.

Never expose secrets: do not place private payment keys, privileged database credentials or private API tokens in HTML, frontend JavaScript, public Git history or browser-exposed environment variables. Store secrets using the platform's supported secret configuration and call the private service from server-side code.

Storage and data options

These resources are not automatically created just because you deploy a Worker. Create the resource, configure its binding securely, and design access permissions and data handling.

Official references: Workers Static Assets ↗ · Workers secrets ↗ · Pages Functions ↗

05 / Frameworks

Which frameworks can you use?

Cloudflare supports many frameworks. What matters is whether your app produces static files or requires server-side rendering and framework-specific runtime support.

Frontend / build tools

Vite, React, Vue, Angular, Svelte and similar frontend stacks. React is a UI library, so check whether the project uses Vite, Next.js or another build system.

Content and static sites

Astro, Hugo, Jekyll, Eleventy, Docusaurus, VitePress and other static site generators.

Full-stack / server-rendered

Next.js, Nuxt, SvelteKit, Remix and other frameworks with server routes or SSR. Confirm the current Cloudflare adapter and feature support before deploying.

API frameworks

Hono and other supported JavaScript frameworks can be used for Worker request handlers and APIs.

Build settings in plain English

Next.js note: a static export is not the same as a full server-rendered Next.js app. Cloudflare has distinct guidance for static Pages exports and Next.js on Workers. Read the guide for the framework's version and features instead of copying settings from a different tutorial.

Framework deployment checklist

  1. Read the official guide for the framework and version.
  2. Decide if the app is static or server-rendered.
  3. Check package.json scripts and the lockfile.
  4. Run a clean install and build locally.
  5. Confirm the output folder exists and contains the expected files.
  6. Configure the matching preset, root, command and output folder.
  7. Configure server-side bindings and secrets only when needed.
  8. Test routes, API calls, redirects and error states on the preview.

Official references: Cloudflare framework guides ↗ · Next.js static deployment ↗

06 / Go live

Domains, DNS, HTTPS and production checks

A successful first deployment is the start. Make sure people can find the right site, use it safely and recover when something breaks.

Connect a custom domain

  1. Own the domain or have permission from its owner.
  2. Open the relevant Pages project or Worker and find custom-domain settings.
  3. Add the exact hostname, such as www.example.com or example.com.
  4. Follow the DNS instructions shown for that project and wait for validation/certificate setup.
  5. Test HTTPS and decide which hostname should be canonical.

Do not delete DNS records just to make the website work. MX, SPF, DKIM and DMARC records may be needed for business email. DNS changes can affect services other than the website.

Security checklist

These checkboxes are a local checklist for your browser; they do not change Cloudflare settings. For payment or personal-data systems, use a proper security review and follow applicable laws and provider requirements.

Troubleshooting common errors

My site returns 404

For a static site, confirm there is a top-level index.html in the deployed output directory. For a framework, check that the configured output directory matches the folder the build actually created.

CSS or images do not load

Inspect browser developer tools → Network, check capitalization and path spelling, and confirm the files were committed and included in the deployed output. A leading slash points to the domain root.

The deployment build fails

Read the first useful error in the build log. Confirm the branch, root directory, build command, dependencies, environment variables and output directory. Do not use a framework build command for plain static files.

It works locally but not online

Check for hard-coded localhost URLs, missing production variables, CORS/authentication settings, unsupported runtime APIs, and browser console/network errors.

My form looks right but sends nothing

Static hosting does not process a form by itself. Connect a real backend endpoint or form service, validate input, handle success and failure, and protect any sensitive operation on the server.

My API returns 500

Review Worker or Function logs, verify binding names and database permissions, and add safe error handling. Do not print secret values or expose raw stack traces to users.

My domain or certificate is pending

Review the domain status and exact DNS validation instructions in Cloudflare. Avoid repeatedly changing records or deleting email records without understanding their purpose.

07 / Business email

Email routing, domain records and sending mail

Your website domain and your email service share DNS, but they are different services. Set up email deliberately so a website change does not break business email.

Understand the difference: Cloudflare Email Routing forwards incoming messages sent to custom addresses (for example, hello@yourdomain.com) to an existing inbox. It is not, by itself, a full mailbox hosting service with a separate inbox, folders, IMAP/POP access, or a complete outbound email system.

A. Before you configure routing

  1. Add your domain to Cloudflare and use Cloudflare as its authoritative DNS provider. Email Service routing requires Cloudflare DNS.
  2. Decide which addresses you need, such as hello@yourdomain.com, support@yourdomain.com, sales@yourdomain.com and billing@yourdomain.com.
  3. Choose an existing mailbox that will receive forwarded messages, and make sure you can open and verify it.
  4. Inspect existing DNS records first. If the domain already uses Google Workspace, Microsoft 365 or another email provider, do not replace its MX records blindly.

B. Configure Cloudflare Email Service / Email Routing

  1. Open the Cloudflare dashboard and go to Compute → Email Service → Email Routing (the dashboard label may change).
  2. Choose the domain and start onboarding. Review the DNS records Cloudflare proposes to add, including the MX and relevant authentication records.
  3. Open Destination Addresses, add the inbox where you want to receive forwarded messages, and click the verification link sent to that mailbox.
  4. Create a custom address and choose the verified destination. Repeat for other addresses if needed.
  5. Send a test message from an unrelated email account. Confirm delivery to the destination inbox and check spam/junk if it does not arrive.
  6. Review routing analytics and troubleshoot DNS or verification warnings shown by Cloudflare.

Official setup: Route emails with Cloudflare Email Service ↗ · Email Service documentation ↗

C. DNS records in simple terms

MX

Tells other mail systems where incoming mail for your domain should be delivered. Incorrect MX records can stop mail from reaching your current provider.

SPF, DKIM and DMARC

Help receiving mail systems evaluate whether messages are authorized and authenticated. Follow the exact records supplied by your email provider; do not copy records from a different domain.

A and CNAME

Typically connect a website hostname to a hosting destination. These records do not create an email inbox. Keep web and mail records distinct.

DNS propagation

Changes may take time to appear across the internet. Check the record values and status before making repeated edits.

D. Can I send email from my website?

Incoming forwarding and outbound email are separate. A contact form, password reset, receipt or booking confirmation needs a sending service or a supported email API. Cloudflare Email Service includes sending capabilities, but you must configure the domain and sending workflow according to its current documentation. A third-party provider is also an option.

Important: Email routing is not an email marketing list, a mailbox, or a guarantee that outbound messages will be accepted. Before changing MX records on a domain that already receives mail, document the existing configuration and plan the migration.

Useful references: Cloudflare Email Service ↗ · Cloudflare DNS ↗

08 / Operating the site

SEO, analytics, forms, performance and maintenance

A professional website needs more than a successful deploy. Make it discoverable, measurable, accessible and maintainable.

Search engine basics

Analytics and privacy

Cloudflare Web Analytics can provide website traffic measurements. Enable it from the dashboard or follow the current setup guide, then check that the site is actually receiving data. Explain tracking honestly and follow privacy requirements applicable to your audience. Do not collect more personal information than you need.

Cloudflare Web Analytics guide ↗

Forms and integrations

HTML can display a contact form, but static hosting does not automatically store or deliver its submissions. Connect a secure Worker/Pages Function or a reputable form service. Validate fields on the server, protect against spam, show clear success and error states, and do not collect payment-card data yourself.

Speed and accessibility

Backups, monitoring and rollbacks

Keep the source in Git, document DNS and environment settings, and maintain a recovery path. Review deployment logs after changes, test critical journeys and keep secrets out of logs. Pages supports deployment history and rollbacks; use the dashboard to return to a known-good deployment when appropriate. A rollback does not automatically reverse database migrations or external side effects.

Costs and usage

Check current Cloudflare plan limits and the pricing of every connected service before launch. Domain registration, paid mailbox hosting, third-party APIs, databases and email sending may cost extra even if static hosting is inexpensive. Set usage alerts where available and avoid assuming every feature is unlimited or free.

09 / Files and object storage

R2: store images, documents, videos and downloads

R2 is object storage. Think of it as a place for files your application needs to save and retrieve, rather than a folder that automatically appears inside your website.

Use R2 for: user uploads, product photos, PDF documents, generated reports, backups and large files. Do not use it as a relational database, and do not make private files public just to make the URLs work.

Create your first bucket

  1. Open the Cloudflare dashboard and select R2 Object Storage. If asked, enable R2 for the account and review the current pricing and storage/operation allowances.
  2. Select Create bucket. Choose a clear name such as christech-public-assets-dev for development. Use separate buckets or clearly separated policies for production and private uploads.
  3. Choose the location options offered by the dashboard where applicable, and create the bucket.
  4. Open the bucket and upload a harmless test image or text file. Check its object key and metadata. Object keys are paths/names inside the bucket; they are not necessarily ordinary folders.
  5. Decide how your application will access objects: a Worker binding for server-side access, a presigned URL for temporary access, or a deliberately public custom domain for public assets.

Option A: use R2 from a Worker

  1. Create or open your Worker project and install/configure Wrangler using the current Cloudflare instructions.
  2. Add an R2 bucket binding in your Wrangler configuration. For example, the binding name might be ASSETS; your code then accesses env.ASSETS. Use the exact bucket name and configuration generated for your project.
  3. In the Worker, use the binding to put, get, list or delete objects only after validating the request and checking the caller's permissions.
  4. For uploads, enforce file-size limits, permitted content types, safe filenames/object keys and authorization. Do not trust a filename or MIME type supplied by the browser.
  5. Test with a small file locally, deploy to a development environment, then test upload, download, overwrite and unauthorized access before production.
// Illustrative Worker pattern — add the matching R2 binding first.
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname === "/health") {
      return Response.json({ ok: true });
    }
    if (url.pathname === "/example-file" && request.method === "GET") {
      const object = await env.ASSETS.get("demo/hello.txt");
      if (!object) return new Response("Not found", { status: 404 });
      return new Response(object.body, {
        headers: { "Content-Type": object.httpMetadata?.contentType || "text/plain" }
      });
    }
    return new Response("Not found", { status: 404 });
  }
};

This example assumes a binding called ASSETS exists and an object called demo/hello.txt has been uploaded. It is not a public upload endpoint and should not be mistaken for a complete file manager.

Option B: share a file with a presigned URL

  1. Keep the bucket private.
  2. Use the supported S3-compatible API or SDK from trusted server-side code to create a time-limited presigned URL.
  3. Give the URL only to the authorized person and keep its expiry short enough for the use case.
  4. Remember that anyone who obtains the URL can generally use it until it expires. Do not log or publish sensitive presigned URLs.

Option C: serve public files

  1. Only use public access for content that is genuinely intended for everyone, such as public product images or static downloads.
  2. For testing, Cloudflare provides an r2.dev development URL, but it is rate-limited and intended for non-production use.
  3. For production, connect a domain you control using the R2 custom-domain workflow, then test HTTPS, cache behavior and object paths.
  4. Do not assume enabling a public bucket creates a browsable file listing at the root. Link to exact object paths.

R2 CORS, uploads and safety

Official guides: R2 quick start ↗ · Public buckets ↗ · Presigned URLs ↗ · R2 CORS ↗

10 / Databases and state

D1, KV, Durable Objects and Queues

These tools solve different problems. Choose based on the data shape and consistency you need, not because every Cloudflare project must use every service.

D1: a managed SQL database

D1 is a serverless SQL database built on SQLite. It is suitable for many small and medium application data models, such as users, products, posts, bookings and settings, when used within its documented limits.

  1. Install a supported Node.js version and use the project's current Wrangler CLI.
  2. From your Worker project directory, create a database with a command such as npx wrangler d1 create my-app-db. Follow the CLI output and official docs for the exact command and generated identifier.
  3. Add the returned D1 database configuration to wrangler.jsonc (or let Wrangler update it). Choose a clear binding name such as DB and reference it as env.DB in the Worker.
  4. Create a migrations folder and a numbered SQL migration file. Define tables, primary keys, constraints and indexes intentionally.
  5. Apply migrations to the local development database first. Inspect the schema and test the app with non-production sample data.
  6. Apply the migration to the remote database only after reviewing it. Keep schema changes in version control and use the documented remote migration command.
  7. Implement prepared/bound SQL parameters, input validation, authorization, pagination and safe error handling. Never concatenate untrusted input into SQL.
  8. Before production, review backups, restore procedures, database limits, indexes, query performance and data retention requirements.
-- Example migration: migrations/0001_create_notes.sql
CREATE TABLE notes (
  id TEXT PRIMARY KEY,
  title TEXT NOT NULL,
  body TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_notes_created_at ON notes(created_at);

Migration files are the source of truth for schema evolution. Do not make undocumented dashboard-only schema edits and then forget to reproduce them in the project.

KV: fast key-value lookups

Workers KV is a distributed key-value store for data that is read frequently and can tolerate its documented eventual-consistency behavior. Common examples include public configuration, cached lookup data and feature flags. It is not a substitute for SQL joins, transactions or a strongly consistent account balance.

  1. Create a KV namespace in the dashboard or with Wrangler.
  2. Add a binding to your Worker configuration, for example SETTINGS.
  3. Use env.SETTINGS.get() and put() from server-side code, setting expiration or TTL where appropriate.
  4. Keep secrets and private user data out of public/cacheable keys, and design invalidation and stale-data behavior.
  5. Test misses, expired values, serialization and concurrent updates.

Durable Objects: coordinated state

Durable Objects provide a unique, addressable coordination point with strongly consistent storage. They are useful for room-based collaboration, multiplayer sessions, WebSocket coordination, rate-limiting coordination and other workloads that need one authoritative state owner.

  1. Identify the state that needs a single coordinator, such as one chat room or one shared counter.
  2. Design a stable object identity (for example, a room ID) so requests for the same logical room reach the same object.
  3. Configure the Durable Object class, binding and any required migration in the current Wrangler configuration.
  4. Implement validation and authorization inside the object; never assume that knowing an object ID grants permission.
  5. Test concurrent requests, disconnects, retries, persistence and deployment migrations before production.

Queues: process work asynchronously

Queues let a producer send a message for later processing by a consumer. Use them for tasks that should not hold up the original web request, such as email jobs, image processing, webhook follow-up work or batch tasks.

  1. Create a queue and configure producer/consumer bindings.
  2. Define a small, versioned message schema. Do not place unnecessary sensitive information in messages.
  3. Send the message after validating the original request.
  4. Make the consumer idempotent because retries can cause a message to be processed more than once.
  5. Set retry and dead-letter behavior, observe failures and provide a safe way to replay messages.
Choosing quickly: D1 = relational SQL records; KV = distributed key/value lookup; Durable Objects = coordinated state; Queues = background work. They can work together, but each has its own limits, pricing and consistency model.

Official guides: D1 getting started ↗ · D1 migrations ↗ · Workers KV ↗ · Durable Objects ↗ · Queues ↗

11 / AI on Cloudflare

AI Gateway, Workers AI and Vectorize

AI Gateway helps you observe and control model traffic. Workers AI runs supported models. Vectorize stores embeddings for semantic search. They are related, but they are not the same service.

AI Gateway: observe and manage AI requests

AI Gateway sits between your application and supported AI providers. It can provide analytics, request logging, caching, rate limiting, retries and related controls. It does not magically make every provider free, and it does not replace your application's authorization.

  1. Open AI Gateway in the Cloudflare dashboard and create a gateway with a recognizable name, such as christech-learning.
  2. Choose the provider and model your application already uses, or follow the gateway's current integration instructions for the provider.
  3. Update the server-side API URL/SDK configuration to route requests through that gateway. Keep provider API keys in Worker secrets or another server-side secret manager.
  4. Send a small test prompt and verify that the request appears in the gateway's analytics/logs.
  5. Enable caching only for requests where reuse is safe and appropriate. Be careful with personalized prompts, private data and responses that must always be fresh.
  6. Set appropriate rate limits and retry behavior. Avoid retry storms, duplicated billable requests and overly generous limits for anonymous users.
  7. Monitor request volume, tokens, errors and costs. Check log retention and privacy settings before sending personal or confidential data.

Official guide: AI Gateway overview ↗ · AI Gateway pricing and logging ↗

Workers AI: run supported AI models

Workers AI lets your Worker call models available in Cloudflare's model catalog without you managing a GPU server. Model availability, context sizes, features, quotas and pricing can change, so check the current catalog before choosing a model.

  1. Create a Worker project using the Cloudflare starter or open your existing Worker project.
  2. In the Wrangler configuration, add the Workers AI binding using the documented name (many examples use AI).
  3. Call the chosen model from server-side Worker code through env.AI, following the model's required input and output schema.
  4. Test with a short, non-sensitive prompt and handle errors, timeouts, invalid model output and usage limits.
  5. Put authentication and per-user usage controls in front of public AI endpoints so anonymous visitors cannot consume unlimited resources.
  6. Evaluate model quality for your actual task and language. Do not assume an AI answer is factually correct; validate important outputs and disclose limitations to users.
  7. Deploy, test under expected traffic and monitor usage and costs.

Official guide: Workers AI getting started ↗ · Workers AI with Wrangler ↗

Vectorize: semantic search and retrieval

Vectorize is a vector database. An embedding model turns text or other supported inputs into arrays of numbers that represent semantic features. Vectorize stores and searches those vectors; it does not automatically store or secure all of the original documents for you.

  1. Decide what you need to search: product descriptions, help articles, course notes or documents.
  2. Choose an embedding model and create a Vectorize index with the model's exact vector dimensions and a suitable similarity metric. Those index settings are fixed, so verify them before creating the production index.
  3. Add the Vectorize binding and Workers AI binding to your Worker configuration.
  4. Prepare clean source content and stable IDs. Generate embeddings for each document and upsert vectors with useful metadata.
  5. For a search, embed the user's query using the same compatible embedding model and query the index for nearest matches.
  6. Fetch the matched source text from an authorized database or object store, filter by the user's permissions, and then use the selected context in your application.
  7. Evaluate relevance, stale-content removal, duplicate documents, metadata filters and access-control boundaries. Never let a vector match bypass document permissions.

For retrieval-augmented generation (RAG), the common flow is: user question → query embedding → vector search → permission-filtered source passages → model prompt → answer with source references. Keep the original sources so the answer can be checked.

Official guide: Vectorize getting started ↗ · Vectorize with Workers AI embeddings ↗

A sensible AI application architecture

  1. The browser calls your authenticated Worker endpoint.
  2. The Worker validates the user, request size, permissions and rate limits.
  3. AI Gateway routes supported provider traffic and provides monitoring controls; Workers AI can run supported Cloudflare-hosted models.
  4. Vectorize can retrieve relevant passages if your app needs semantic search.
  5. D1 or R2 can store application records and original documents according to their access requirements.
  6. The Worker returns a safe response and logs only what is necessary.
AI safety: treat model output and retrieved documents as untrusted input. Protect against prompt injection, data leakage, excessive tool permissions, high-cost loops and requests that attempt to expose secrets. Require human review for consequential decisions.

12 / More platform services

Turnstile, Images, Stream, Hyperdrive, Browser Rendering and scheduled jobs

These services solve specific problems. Start with the smallest tool that fits, and check feature availability and pricing before building around it.

Turnstile: help protect forms from automated abuse

  1. Create a Turnstile widget in the dashboard and add the intended hostnames.
  2. Copy the public site key into the frontend widget. It is designed to be public.
  3. Keep the secret key on the server in a Worker secret or protected environment variable.
  4. When the form is submitted, send the token to your Worker and validate it server-side with Cloudflare's Siteverify endpoint.
  5. Reject missing, invalid, expired or replayed tokens. Also validate the form and apply rate limits; Turnstile is one layer, not a complete anti-abuse system.
  6. Test the real production hostname and failure path. Show a useful error if verification is unavailable, rather than silently accepting a failed check.

Turnstile getting started ↗

Images: image delivery and transformation

Cloudflare Images can help manage and deliver images with transformations. Before using it, decide whether you need a managed image product, transformations for public images, or simply R2 storage for files. Uploading an image to R2 does not automatically grant the same transformation features as Cloudflare Images.

  1. Choose the image workflow and review current product pricing and limits.
  2. Configure permitted upload paths and authorization if users upload images.
  3. Use appropriate responsive sizes and formats, and provide alt text in your website content.
  4. Test caching, access to private images, and image delivery on mobile networks.

Cloudflare Images documentation ↗

Stream: host and deliver video

Stream is designed for video upload, storage, encoding and delivery. It is different from simply placing an MP4 in R2. Use access controls or signed playback when the video should not be public, and review encoding, storage and delivery costs before launching a video-heavy product.

Cloudflare Stream documentation ↗

Hyperdrive: connect to an existing database

Hyperdrive helps Workers connect to supported external PostgreSQL or MySQL databases with connection pooling and related optimizations. It is not itself a database. Use it when you already have a compatible database and need to connect from Workers; use D1 when its SQL model and limits fit your app better.

  1. Confirm your external database engine, network access, TLS requirements and credentials.
  2. Create a Hyperdrive configuration in the dashboard or with the current Wrangler CLI.
  3. Store database credentials securely and configure the binding using the generated settings.
  4. Use a compatible database driver and follow the current Workers compatibility instructions.
  5. Test migrations, connection handling, query performance, database permissions and failure behavior.

Hyperdrive documentation ↗

Browser Rendering: controlled browser automation

Browser Rendering provides browser-based automation capabilities for supported tasks such as rendering pages, screenshots and browser-driven workflows. It is not a reason to expose a public endpoint that lets anyone navigate arbitrary websites. Restrict who can trigger jobs, validate targets, set limits and review the provider's acceptable-use and security guidance.

Browser Rendering documentation ↗

Cron Triggers: run work on a schedule

Cron Triggers can invoke a Worker on a schedule for tasks such as periodic cleanup, summaries or synchronization. Configure the schedule in the Worker configuration, deploy it, and inspect execution logs. Schedules are generally defined in UTC, so convert carefully when planning local Kenyan time. Make scheduled tasks idempotent and safe to retry.

Cron Triggers documentation ↗

WAF, rate limiting and caching

Cloudflare's network features can help protect and accelerate websites. Begin by understanding which DNS records are proxied, then review security events and caching behavior. Add WAF/custom rules and rate limits carefully; a broad rule can block legitimate users or APIs. Do not cache private account pages or personalized API responses as public content.

WAF documentation ↗ · Cache documentation ↗ · Waiting Room documentation ↗

07 / Official references

Keep the documentation close

Cloudflare updates its dashboard and supported framework workflows. Use official documentation to verify the exact steps for your project.

Keep learning

You do not need to know everything before you publish.

Start small, deploy a working version, test it with real devices and add complexity only when the project needs it.

Found this guide useful? You can support more practical learning resources through Chris Tech.