Documentation

Stockage (Cloudflare R2)

Stockage de fichiers Cloudflare R2 — configuration du bucket, credentials, uploads présignés et API compatible S3.

Ouvrir dansChatGPT (s’ouvre dans un nouvel onglet)Claude (s’ouvre dans un nouvel onglet)Cursor (s’ouvre dans un nouvel onglet)Stockage de fichiers Cloudflare R2 — configuration du bucket, credentials, uploads présignés et API compatible S3.

Motoko Base utilise Cloudflare R2 pour le stockage de fichiers. R2 est compatible S3 — l'app utilise le AWS SDK avec un endpoint personnalisé.

Official docs: Cloudflare R2 documentation

Setup

  1. Créez un bucket R2 dans le Cloudflare dashboard → R2
  2. Créez un R2 API token (Object Read & Write)
  3. Définissez les variables d'environnement :
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

Sans les variables R2, l'app démarre — le demo Storage affiche un message de configuration.

How uploads work

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

Les fichiers ne sont jamais proxyifiés via Next.js. Le serveur émet une URL présignée ; le navigateur upload vers R2. Les métadonnées (nom, taille, propriétaire) vivent dans la table files.

Limites d'upload et MIME types autorisés : src/features/storage/config.ts.

S3-compatible API

Client R2 : src/lib/r2.ts — utilise @aws-sdk/client-s3 avec :

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

Les URLs présignées PUT (upload) et GET (download) expirent après 10–15 minutes.

Production

  • Utilisez un bucket privé — accès uniquement via URLs présignées
  • Définissez les credentials comme variables serveur uniquement (jamais NEXT_PUBLIC_*)
  • Les avatars (Settings) utilisent aussi R2 lorsqu'il est configuré — mêmes credentials
  • Envisagez des règles de lifecycle Cloudflare pour les anciens objets — non livrées dans le starter

Pour CORS : si les uploads navigateur échouent, ajoutez l'origine de votre app à la politique CORS du bucket dans Cloudflare. Voir 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

Importez @/lib/r2 uniquement depuis le code serveur — jamais depuis des client components.


Environment Variables — toutes les variables R2.