| name | cloudflare |
| description | Build and deploy on Cloudflare's edge platform. Use when creating Workers, Pages, D1 databases, R2 storage, AI inference, or KV storage. Triggers on Cloudflare, Workers, Cloudflare Pages, D1, R2, KV, Cloudflare AI, Durable Objects, edge computing. |
Cloudflare Platform
Build globally distributed applications on Cloudflare's edge network.
Quick Start
npm install -g wrangler
wrangler login
wrangler init my-worker
wrangler deploy
Workers
Basic Worker
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === '/api/hello') {
return Response.json({ message: 'Hello from the edge!' });
}
return new Response('Not Found', { status: 404 });
},
};
wrangler.toml Configuration
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[vars]
ENVIRONMENT = "production"
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "def456"
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
[ai]
binding = "AI"
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
[[migrations]]
tag = "v1"
new_classes = ["Counter"]
Request Routing
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const { pathname } = url;
const routes: Record<string, () => Promise<Response>> = {
'/api/users': () => handleUsers(request, env),
'/api/posts': () => handlePosts(request, env),
};
const handler = routes[pathname];
if (handler) {
return handler();
}
if (pathname.startsWith('/api/users/')) {
const userId = pathname.split('/')[3];
return handleUser(userId, request, env);
}
return new Response('Not Found', { status: 404 });
},
};
KV Storage
interface Env {
MY_KV: KVNamespace;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
await env.MY_KV.put('key', 'value', {
expirationTtl: 3600,
metadata: { created: Date.now() },
});
const value = await env.MY_KV.get('key');
const { value: data, metadata } = await env.MY_KV.getWithMetadata('key');
const list = await env.MY_KV.list({ prefix: 'user:' });
env..();
.({ value });
},
};
D1 Database (SQLite)
interface Env {
DB: D1Database;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { results } = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(1).all();
const { meta } = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind('Alice', 'alice@example.com').run();
const batch = await env.DB.batch([
env.DB.prepare('INSERT INTO logs (action) VALUES (?)').bind('login'),
env.DB.prepare('UPDATE users SET last_login = ? WHERE id = ?').bind(Date.(), ),
]);
user = env..(
).().();
.({ results, : meta. });
},
};
Schema Example
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
content TEXT,
FOREIGN KEY (user_id) REFERENCES users(id)
);
R2 Object Storage
interface Env {
BUCKET: R2Bucket;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const key = url.pathname.slice(1);
switch (request.method) {
case 'PUT': {
const body = await request.arrayBuffer();
await env.BUCKET.put(key, body, {
httpMetadata: {
contentType: request.headers.get('content-type') || 'application/octet-stream',
},
customMetadata: {
uploadedBy: 'api',
},
});
return new Response('Uploaded', { status: 201 });
}
case 'GET': {
= env..(key);
(!) {
(, { : });
}
headers = ();
.(headers);
headers.(, .);
(., { headers });
}
: {
env..(key);
();
}
:
(, { : });
}
},
};
() {
listed = env..({
prefix,
: ,
});
listed..( ({
: obj.,
: obj.,
: obj.,
}));
}
Cloudflare AI
interface Env {
AI: Ai;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const { prompt } = await request.json();
const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: prompt },
],
max_tokens: 1024,
});
return Response.json(response);
},
};
async function generateImage(env: Env, prompt: string) {
const response = await env.AI.run('@cf/stabilityai/stable-diffusion-xl-base-1.0', {
prompt,
num_steps: ,
});
(response, {
: { : },
});
}
() {
response = env..(, {
: [text],
});
response.[];
}
() {
response = env..(, {
: [... (imageData)],
});
response;
}
() {
response = env..(, {
: [... (audioData)],
});
response.;
}
Durable Objects
export class Counter {
state: DurableObjectState;
constructor(state: DurableObjectState) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
let value = (await this.state.storage.get<number>('count')) || 0;
switch (url.pathname) {
case '/increment':
value++;
await this.state.storage.put('count', value);
break;
case '/decrement':
value--;
await this.state.storage.put('count', value);
break;
}
return .({ : value });
}
}
{
: ;
}
{
(: , : ): <> {
counterId = env..();
counter = env..(counterId);
counter.(request);
},
};
Cloudflare Pages
pages.toml (Functions Config)
[build]
command = "npm run build"
output_directory = "dist"
[[redirects]]
from = "/old-page"
to = "/new-page"
status = 301
[[headers]]
for = "/api/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Pages Functions
export const onRequestGet: PagesFunction = async (context) => {
return Response.json({ message: 'Hello!' });
};
export const onRequestPost: PagesFunction<Env> = async (context) => {
const body = await context.request.json();
await context.env.KV.put('key', JSON.stringify(body));
return Response.json({ success: true });
};
export const onRequestGet: PagesFunction = async (context) => {
const userId = context.params.id;
return Response.json({ userId });
};
export const onRequest: PagesFunction = (context) => {
auth = context...();
(!auth) {
(, { : });
}
context.();
};
Queues
interface Env {
MY_QUEUE: Queue;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
await env.MY_QUEUE.send({
type: 'email',
to: 'user@example.com',
subject: 'Welcome!',
});
await env.MY_QUEUE.sendBatch([
{ body: { task: 'process', id: 1 } },
{ body: { task: 'process', id: 2 } },
]);
return Response.json({ queued: true });
},
};
export default {
async queue(batch: MessageBatch<any>, env: ): <> {
( message batch.) {
{
(message.);
message.();
} (error) {
message.();
}
}
},
};
Cron Triggers
[triggers]
crons = ["0 0 * * *", "*/15 * * * *"]
export default {
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
switch (event.cron) {
case '0 0 * * *':
await dailyCleanup(env);
break;
case '*/15 * * * *':
await checkHealthStatus(env);
break;
}
},
};
WebSockets
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const upgradeHeader = request.headers.get('Upgrade');
if (upgradeHeader === 'websocket') {
const [client, server] = Object.values(new WebSocketPair());
server.accept();
server.addEventListener('message', (event) => {
server.send(`Echo: ${event.data}`);
});
return new Response(null, {
status: 101,
webSocket: client,
});
}
return new Response('Expected WebSocket', { status: 400 });
},
};
Resources