zudo-cloudflare-wisdom

Type to search...

to open search from anywhere

Pages Functions

CreatedApr 4, 2026Takeshi Takatsudo

Serverless API endpoints with file-based routing

Overview

Pages Functions are serverless functions that deploy alongside your static site. They use file-based routing from a functions/ directory at the project root.

File-Based Routing

The file path determines the URL:

functions/api/search.ts      → /api/search
functions/api/users/[id].ts  → /api/users/:id
functions/pj/my-site/api/search.ts → /pj/my-site/api/search

⚠️ Path Matches Deploy Structure

If your site uses a base path like /pj/my-site/, the functions directory must mirror that path: functions/pj/my-site/api/search.ts serves at /pj/my-site/api/search.

Function Format

Functions export an onRequest handler (or method-specific handlers like onRequestGet, onRequestPost):

interface Env {
  KEYWORD_LOGS: KVNamespace;
}

export const onRequestGet: PagesFunction<Env> = async (context) => {
  const url = new URL(context.request.url);
  const query = url.searchParams.get("q");

  // Access KV binding
  const logs = context.env.KEYWORD_LOGS;

  return new Response(JSON.stringify({ results: [] }), {
    headers: { "Content-Type": "application/json" },
  });
};

Bindings

Pages Functions access Cloudflare services through bindings defined in wrangler.toml:

compatibility_date = "2024-12-01"

[[kv_namespaces]]
binding = "KEYWORD_LOGS"
id = "abc123def456"

The Env interface in your TypeScript code must match the binding names:

interface Env {
  KEYWORD_LOGS: KVNamespace;   // matches binding name in wrangler.toml
  DB: D1Database;              // D1 binding
  FILES: R2Bucket;             // R2 binding
}

Importing Modules

Functions can import from node_modules. However, the bundler behavior differs from regular Node.js:

// Works -- importing npm packages
import MiniSearch from 'minisearch';

// Works -- importing JSON (with @ts-expect-error for type safety)
// @ts-expect-error JSON import bundled by esbuild
import searchData from './search-data.json';

💡 Tip

For functions that need npm packages, install them before deploying. In CI:

pnpm add -w minisearch  # Add the dependency
pnpm dlx wrangler@4 pages deploy deploy --project-name=my-site

Local Development

Test functions locally with:

npx wrangler pages dev dist --port 8788

This starts a local server that serves both the static files and the functions.