Documentação

Armazenamento (Cloudflare R2)

Armazenamento de arquivos no Cloudflare R2 — setup do bucket, credenciais, uploads pré-assinados e API compatível com S3.

Abrir emChatGPT (abre em uma nova aba)Claude (abre em uma nova aba)Cursor (abre em uma nova aba)Armazenamento de arquivos no Cloudflare R2 — setup do bucket, credenciais, uploads pré-assinados e API compatível com S3.

O Motoko Base usa Cloudflare R2 para armazenamento de arquivos. O R2 é compatível com S3 — o app usa o AWS SDK com um endpoint customizado.

Official docs: Cloudflare R2 documentation

Setup

  1. Crie um bucket R2 no Cloudflare dashboard → R2
  2. Crie um R2 API token (Object Read & Write)
  3. Defina as env vars:
VariablePurpose
R2_ACCOUNT_IDCloudflare account ID
R2_ACCESS_KEY_IDAPI token access key
R2_SECRET_ACCESS_KEYAPI token secret
R2_BUCKET_NAMEBucket name (optional /prefix suffix)
R2_PREFIXOptional key prefix override
R2_ENDPOINTOptional custom endpoint

Sem as env vars do R2 o app sobe — o demo de Storage mostra uma mensagem de configuração.

How uploads work

Client → Server Action (presigned PUT URL)
   ↓
Browser uploads directly to R2
   ↓
Server validates (HEAD) → marks file ready in Postgres

Arquivos nunca são proxyados pelo Next.js. O servidor emite uma URL pré-assinada; o navegador faz upload para o R2. Metadados (nome, tamanho, dono) ficam na tabela files.

Limites de upload e MIME types permitidos: src/features/storage/config.ts.

S3-compatible API

Cliente R2: src/lib/r2.ts — usa @aws-sdk/client-s3 com:

  • Endpoint: https://{R2_ACCOUNT_ID}.r2.cloudflarestorage.com
  • Region: auto
  • Path-style URLs (forcePathStyle: true)

URLs pré-assinadas PUT (upload) e GET (download) expiram após 10–15 minutos.

Production

  • Use um bucket privado — acesso apenas via URLs pré-assinadas
  • Defina credenciais como env vars somente de servidor (nunca NEXT_PUBLIC_*)
  • Avatares (Settings) também usam R2 quando configurado — mesmas credenciais
  • Considere lifecycle rules no Cloudflare para objetos antigos — não incluídas no starter

Para CORS: se uploads do navegador falharem, adicione a origem do seu app à política CORS do bucket no Cloudflare. Veja R2 CORS docs.

Where to change this

WhatWhere
R2 client & presigned URLssrc/lib/r2.ts
Upload actions & validationsrc/features/storage/actions.ts
File metadata queriessrc/features/storage/queries.ts
Limits & MIME allowlistsrc/features/storage/config.ts
Storage UIsrc/features/storage/components/dashboard/storage-page.tsx

Importe @/lib/r2 apenas de código de servidor — nunca de client components.


Environment Variables — todas as env vars do R2.