# Configuration ## wrangler.jsonc ```jsonc { "name": "my-pages-project", "pages_build_output_dir": "./dist", "compatibility_date": "2026-01-01", // Use current date for new projects "compatibility_flags": ["nodejs_compat"], "placement": { "mode": "smart" // Optional: Enable Smart Placement }, "kv_namespaces": [{"binding": "KV", "id": "abcd1234..."}], "d1_databases": [{"binding": "DB", "database_id": "xxxx-xxxx", "database_name": "production-db"}], "r2_buckets": [{"binding": "BUCKET", "bucket_name": "my-bucket"}], "durable_objects": {"bindings": [{"name": "COUNTER", "class_name": "Counter", "script_name": "counter-worker"}]}, "services": [{"binding": "API", "service": "api-worker"}], "queues": {"producers": [{"binding": "QUEUE", "queue": "my-queue"}]}, "vectorize": [{"binding": "VECTORIZE", "index_name": "my-index"}], "ai": {"binding": "AI"}, "analytics_engine_datasets": [{"binding": "ANALYTICS"}], "vars": {"API_URL": "https://api.example.com", "ENVIRONMENT": "production"}, "env": { "preview": { "vars": {"API_URL": "https://staging-api.example.com"}, "kv_namespaces": [{"binding": "KV", "id": "preview-namespace-id"}] } } } ``` ## Build Config **Git deployment**: Dashboard → Project → Settings → Build settings Set build command, output dir, env vars. Framework auto-detection configures automatically. ## Environment Variables ### Local (.dev.vars) ```bash # .dev.vars (never commit) SECRET_KEY="local-secret-key" API_TOKEN="dev-token-123" ``` ### Production ```bash echo "secret-value" | npx wrangler pages secret put SECRET_KEY --project-name=my-project npx wrangler pages secret list --project-name=my-project npx wrangler pages secret delete SECRET_KEY --project-name=my-project ``` Access: `env.SECRET_KEY` ## Static Config Files ### _redirects Place in build output (e.g., `dist/_redirects`): ```txt /old-page /new-page 301 # 301 redirect /blog/* /news/:splat 301 # Splat wildcard /users/:id /members/:id 301 # Placeholders /api/* /api-v2/:splat 200 # Proxy (no redirect) ``` **Limits**: 2,100 total (2,000 static + 100 dynamic), 1,000 char/line **Note**: Functions take precedence ### _headers ```txt /secure/* X-Frame-Options: DENY X-Content-Type-Options: nosniff /api/* Access-Control-Allow-Origin: * /static/* Cache-Control: public, max-age=31536000, immutable ``` **Limits**: 100 rules, 2,000 char/line **Note**: Only static assets; Functions set headers in Response ### _routes.json Controls which requests invoke Functions (auto-generated for most frameworks): ```json { "version": 1, "include": ["/*"], "exclude": ["/build/*", "/static/*", "/assets/*", "/*.{ico,png,jpg,css,js}"] } ``` **Purpose**: Functions are metered; static requests are free. `exclude` takes precedence. Max 100 rules, 100 char/rule. ## TypeScript ```bash npx wrangler types --path='./functions/types.d.ts' ``` Point `types` in `functions/tsconfig.json` to generated file. ## Smart Placement Automatically optimizes function execution location based on request patterns. ```jsonc { "placement": { "mode": "smart" // Enable optimization (default: off) } } ``` **How it works**: System analyzes traffic over hours/days and places function execution closer to: - User clusters (e.g., regional traffic) - Data sources (e.g., D1 database primary location) **Benefits**: - Lower latency for read-heavy apps with centralized databases - Better performance for apps with regional traffic patterns **Trade-offs**: - Initial learning period: First requests may be slower while system optimizes - Optimization time: Performance improves over 24-48 hours **When to enable**: Global apps with D1/Durable Objects in specific regions, or apps with concentrated geographic traffic. **When to skip**: Evenly distributed global traffic with no data locality constraints. ## Remote Bindings (Local Dev) Connect local dev server to production bindings instead of local mocks: ```bash # All bindings remote npx wrangler pages dev ./dist --remote # Specific bindings remote (others local) npx wrangler pages dev ./dist --remote --kv=KV --d1=DB ``` **Use cases**: - Test against production data (read-only operations) - Debug binding-specific behavior - Validate changes before deployment **⚠️ Warning**: - Writes affect **real production data** - Use only for read-heavy debugging or with non-production accounts - Consider creating separate preview environments instead **Requirements**: Must be logged in (`npx wrangler login`) with access to bindings. ## Local Dev ```bash # Basic npx wrangler pages dev ./dist # With bindings npx wrangler pages dev ./dist --kv KV --d1 DB=local-db-id # Remote bindings (production data) npx wrangler pages dev ./dist --remote # Persistence npx wrangler pages dev ./dist --persist-to=./.wrangler/state/v3 # Proxy mode (SSR frameworks) npx wrangler pages dev -- npm run dev ``` ## Limits (as of Jan 2026) | Resource | Free | Paid | |----------|------|------| | **Functions Requests** | 100k/day | Unlimited (metered) | | **Function CPU Time** | 10ms/req | 30ms/req (Workers Paid) | | **Function Memory** | 128MB | 128MB | | **Script Size** | 1MB compressed | 10MB compressed | | **Deployments** | 500/month | 5,000/month | | **Files per Deploy** | 20,000 | 20,000 | | **File Size** | 25MB | 25MB | | **Build Time** | 20min | 20min | | **Redirects** | 2,100 (2k static + 100 dynamic) | Same | | **Header Rules** | 100 | 100 | | **Route Rules** | 100 | 100 | | **Subrequests** | 50/request | 1,000/request (Workers Paid) | **Notes**: - Functions use Workers runtime; Workers Paid plan increases limits - Free plan sufficient for most projects - Static requests always free (not counted toward limits) [Full limits](https://developers.cloudflare.com/pages/platform/limits/)