Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/r2/configuration.md
1# R2 Configuration23## Workers Binding45**wrangler.jsonc:**6```jsonc7{8"r2_buckets": [9{10"binding": "MY_BUCKET",11"bucket_name": "my-bucket-name"12}13]14}15```1617## TypeScript Types1819```typescript20interface Env { MY_BUCKET: R2Bucket; }2122export default {23async fetch(request: Request, env: Env): Promise<Response> {24const object = await env.MY_BUCKET.get('file.txt');25return new Response(object?.body);26}27}28```2930## S3 SDK Setup3132```typescript33import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';3435const s3 = new S3Client({36region: 'auto',37endpoint: `https://${accountId}.r2.cloudflarestorage.com`,38credentials: {39accessKeyId: env.R2_ACCESS_KEY_ID,40secretAccessKey: env.R2_SECRET_ACCESS_KEY41}42});4344await s3.send(new PutObjectCommand({45Bucket: 'my-bucket',46Key: 'file.txt',47Body: data,48StorageClass: 'STANDARD' // or 'STANDARD_IA'49}));50```5152## Location Hints5354```bash55wrangler r2 bucket create my-bucket --location=enam5657# Hints: wnam, enam, weur, eeur, apac, oc58# Jurisdictions (override hint): --jurisdiction=eu (or fedramp)59```6061## CORS Configuration6263CORS must be configured via S3 SDK or dashboard (not available in Workers API):6465```typescript66import { S3Client, PutBucketCorsCommand } from '@aws-sdk/client-s3';6768const s3 = new S3Client({69region: 'auto',70endpoint: `https://${accountId}.r2.cloudflarestorage.com`,71credentials: {72accessKeyId: env.R2_ACCESS_KEY_ID,73secretAccessKey: env.R2_SECRET_ACCESS_KEY74}75});7677await s3.send(new PutBucketCorsCommand({78Bucket: 'my-bucket',79CORSConfiguration: {80CORSRules: [{81AllowedOrigins: ['https://example.com'],82AllowedMethods: ['GET', 'PUT', 'HEAD'],83AllowedHeaders: ['*'],84ExposeHeaders: ['ETag'],85MaxAgeSeconds: 360086}]87}88}));89```9091## Object Lifecycles9293```typescript94import { PutBucketLifecycleConfigurationCommand } from '@aws-sdk/client-s3';9596await s3.send(new PutBucketLifecycleConfigurationCommand({97Bucket: 'my-bucket',98LifecycleConfiguration: {99Rules: [100{101ID: 'expire-old-logs',102Status: 'Enabled',103Prefix: 'logs/',104Expiration: { Days: 90 }105},106{107ID: 'transition-to-ia',108Status: 'Enabled',109Prefix: 'archives/',110Transitions: [{ Days: 30, StorageClass: 'STANDARD_IA' }]111}112]113}114}));115```116117## API Token Scopes118119When creating R2 tokens, set minimal permissions:120121| Permission | Use Case |122|------------|----------|123| Object Read | Public serving, downloads |124| Object Write | Uploads only |125| Object Read & Write | Full object operations |126| Admin Read & Write | Bucket management, CORS, lifecycles |127128**Best practice:** Separate tokens for Workers (read/write) vs admin tasks (CORS, lifecycles).129130## Event Notifications131132```jsonc133// wrangler.jsonc134{135"r2_buckets": [136{137"binding": "MY_BUCKET",138"bucket_name": "my-bucket",139"event_notifications": [140{141"queue": "r2-events",142"actions": ["PutObject", "DeleteObject", "CompleteMultipartUpload"]143}144]145}146],147"queues": {148"producers": [{ "binding": "R2_EVENTS", "queue": "r2-events" }],149"consumers": [{ "queue": "r2-events", "max_batch_size": 10 }]150}151}152```153154## Bucket Management155156```bash157wrangler r2 bucket create my-bucket --location=enam --storage-class=Standard158wrangler r2 bucket list159wrangler r2 bucket info my-bucket160wrangler r2 bucket delete my-bucket # Must be empty161wrangler r2 bucket update-storage-class my-bucket --storage-class=InfrequentAccess162163# Public bucket via dashboard164wrangler r2 bucket domain add my-bucket --domain=files.example.com165```166