Context API
The CloudwerkContext object provides access to bindings, utilities, and request information throughout your application.
Overview
Section titled “Overview”Context is available in loaders, handlers, and middleware:
// In a loaderexport async function loader({ context }: LoaderArgs) { const user = await context.auth.getUser(); return { user };}
// In a handlerexport async function GET(request: Request, { context }: CloudwerkHandlerContext) { return context.json({ message: 'Hello' });}
// In middlewareexport const middleware: Middleware = async (request, next, context) => { console.log('Request:', request.url); return next(request);};Properties
Section titled “Properties”Access to all Cloudflare bindings:
interface CloudwerkContext { env: { DB: D1Database; // D1 binding KV: KVNamespace; // KV binding R2: R2Bucket; // R2 binding MY_QUEUE: Queue; // Queue binding DURABLE_OBJECT: DurableObjectNamespace; [key: string]: unknown; // Custom bindings };}Query builder for D1 database:
// Selectconst users = await context.db .selectFrom('users') .where('status', '=', 'active') .orderBy('created_at', 'desc') .limit(10) .execute();
// Insertconst user = await context.db .insertInto('users') .values({ email: 'user@example.com', name: 'John' }) .returning(['id', 'email']) .executeTakeFirst();
// Updateawait context.db .updateTable('users') .set({ name: 'Jane' }) .where('id', '=', userId) .execute();
// Deleteawait context.db .deleteFrom('users') .where('id', '=', userId) .execute();KV namespace helper:
// Get valueconst value = await context.kv.get('key');const jsonValue = await context.kv.get<User>('key', 'json');
// Set valueawait context.kv.put('key', 'value');await context.kv.put('key', JSON.stringify(data), { expirationTtl: 3600,});
// Deleteawait context.kv.delete('key');R2 bucket helper:
// Get objectconst object = await context.r2.get('path/to/file.txt');if (object) { const text = await object.text();}
// Put objectawait context.r2.put('path/to/file.txt', content, { httpMetadata: { contentType: 'text/plain' },});
// Deleteawait context.r2.delete('path/to/file.txt');queues
Section titled “queues”Queue producers:
// Send messageawait context.queues.MY_QUEUE.send({ type: 'email', to: 'user@example.com' });
// Send batchawait context.queues.MY_QUEUE.sendBatch([ { body: { type: 'email', to: 'user1@example.com' } }, { body: { type: 'email', to: 'user2@example.com' } },]);Authentication utilities:
interface AuthContext { // Get current user (null if not authenticated) getUser(): Promise<User | null>;
// Require user (throws RedirectError if not authenticated) requireUser(): Promise<User>;
// Session management createSession(data: SessionData): Promise<void>; destroySession(): Promise<void>; getSession(): Promise<Session | null>;
// OAuth helpers getOAuthUrl(provider: string): string; exchangeOAuthCode(provider: string, code: string): Promise<OAuthTokens>; getOAuthProfile(provider: string, tokens: OAuthTokens): Promise<OAuthProfile>;}Usage:
// Get current userconst user = await context.auth.getUser();if (!user) { throw new RedirectError('/login');}
// Or use requireUserconst user = await context.auth.requireUser(); // Throws if not authenticated
// Create sessionawait context.auth.createSession({ userId: user.id, email: user.email,});
// Destroy session (logout)await context.auth.destroySession();request
Section titled “request”The incoming Request object:
// Access request propertiesconst url = new URL(context.request.url);const method = context.request.method;const headers = context.request.headers;
// Parse bodyconst json = await context.request.json();const formData = await context.request.formData();const text = await context.request.text();waitUntil
Section titled “waitUntil”Extend request lifetime for background tasks:
export async function POST(request: Request, { context }: CloudwerkHandlerContext) { // Respond immediately const response = json({ success: true });
// Continue processing in background context.waitUntil( sendAnalyticsEvent({ type: 'api_call', endpoint: '/api/users' }) );
return response;}Cloudflare-specific request properties:
interface CfProperties { asn: number; // ASN of the incoming request asOrganization: string; // Organization name city: string; // City colo: string; // Cloudflare data center continent: string; // Continent code country: string; // Country code latitude: string; // Latitude longitude: string; // Longitude postalCode: string; // Postal code region: string; // Region/state regionCode: string; // Region code timezone: string; // Timezone tlsVersion: string; // TLS version tlsCipher: string; // TLS cipher}
// Usageconst { country, city, timezone } = context.cf;console.log(`Request from ${city}, ${country} (${timezone})`);Response Helpers
Section titled “Response Helpers”json()
Section titled “json()”Create JSON response:
export async function GET(request: Request, { context }: CloudwerkHandlerContext) { return context.json({ message: 'Hello' }); return context.json({ error: 'Not found' }, { status: 404 }); return context.json(data, { status: 201, headers: { 'X-Custom': 'value' }, });}redirect()
Section titled “redirect()”Create redirect response:
return context.redirect('/dashboard');return context.redirect('/login', 302); // Temporary redirectreturn context.redirect('https://example.com', 301); // Permanent redirecthtml()
Section titled “html()”Create HTML response:
return context.html('<h1>Hello, World!</h1>');return context.html(htmlContent, { status: 200 });text()
Section titled “text()”Create text response:
return context.text('Hello, World!');return context.text('Not found', { status: 404 });stream()
Section titled “stream()”Create streaming response:
const stream = new ReadableStream({ start(controller) { controller.enqueue('Hello, '); controller.enqueue('World!'); controller.close(); },});
return context.stream(stream, { headers: { 'Content-Type': 'text/plain' },});Type Definitions
Section titled “Type Definitions”interface CloudwerkContext { env: Env; db: DatabaseClient; kv: KVHelper; r2: R2Helper; queues: Record<string, Queue>; auth: AuthContext; request: Request; waitUntil: (promise: Promise<unknown>) => void; cf: CfProperties;
// Response helpers json<T>(data: T, init?: ResponseInit): Response; redirect(url: string, status?: number): Response; html(content: string, init?: ResponseInit): Response; text(content: string, init?: ResponseInit): Response; stream(stream: ReadableStream, init?: ResponseInit): Response;}
interface CloudwerkHandlerContext { params: Record<string, string>; context: CloudwerkContext;}
interface LoaderArgs { request: Request; params: Record<string, string>; context: CloudwerkContext;}Next Steps
Section titled “Next Steps”- Bindings Reference - All Cloudflare bindings
- Authentication Guide - Auth patterns
- Database Guide - D1 database usage