Supabase Storage : Gérer les Fichiers et Images avec Supabase

Supabase Storage est un service de stockage de fichiers compatible S3, intégré nativement avec Auth et RLS. Il permet de stocker images, vidéos, PDFs et tout type de fichier, avec des transformations d’images à la volée.

Pour les fondations, consultez notre guide complet Supabase. Pour sécuriser l’accès aux fichiers, voir Supabase RLS. Pour l’authentification des uploads, voir Supabase Auth. Pour optimiser les uploads côté serveur, voir Edge Functions Supabase. Pour les migrations du bucket schema, voir Supabase Migrations.

Concepts Clés : Buckets, Objets et Policies

  • Bucket : conteneur de fichiers (comme un dossier racine S3)
  • Objet : fichier stocké avec ses métadonnées
  • Policy : règles d’accès (comme la RLS pour les fichiers)

Créer un Bucket

// Via le client JavaScript
const { data, error } = await supabase.storage.createBucket('avatars', {
  public: true, // Fichiers publiquement accessibles
  fileSizeLimit: 1024 * 1024 * 2, // 2MB max
  allowedMimeTypes: ['image/jpeg', 'image/png', 'image/webp']
})

// Via SQL (pour les migrations)
INSERT INTO storage.buckets (id, name, public)
VALUES ('avatars', 'avatars', true);

Upload de Fichiers

async function uploadAvatar(file: File, userId: string) {
  const fileExt = file.name.split('.').pop()
  const filePath = `avatars/${userId}.${fileExt}`

  const { data, error } = await supabase.storage
    .from('avatars')
    .upload(filePath, file, {
      cacheControl: '3600',
      upsert: true // Écraser si le fichier existe
    })

  if (error) throw error
  
  const { data: { publicUrl } } = supabase.storage
    .from('avatars')
    .getPublicUrl(filePath)
  
  await supabase
    .from('profiles')
    .update({ avatar_url: publicUrl })
    .eq('id', userId)
  
  return publicUrl
}

Transformations d’Images à la Volée

// Transformer une image via le client (plan Pro)
const { data } = supabase.storage
  .from('photos')
  .getPublicUrl('path/to/image.jpg', {
    transform: {
      width: 400,
      height: 400,
      resize: 'cover', // cover, contain, fill
      format: 'webp',  // Convertir en WebP
      quality: 80
    }
  })

URLs Signées pour Fichiers Privés

// URL signée (expire après N secondes)
const { data } = await supabase.storage
  .from('documents')
  .createSignedUrl('facture-123.pdf', 3600) // Expire dans 1h

console.log('URL temporaire:', data?.signedUrl)

// Télécharger un fichier
const { data: fileData } = await supabase.storage
  .from('documents')
  .download('rapport-2024.pdf')

if (fileData) {
  const url = URL.createObjectURL(fileData)
  const link = document.createElement('a')
  link.href = url
  link.download = 'rapport-2024.pdf'
  link.click()
}

Lister et Supprimer des Fichiers

// Lister les fichiers
const { data: files } = await supabase.storage
  .from('avatars')
  .list('userId123', {
    limit: 100,
    sortBy: { column: 'created_at', order: 'desc' }
  })

// Supprimer des fichiers
const { error } = await supabase.storage
  .from('photos')
  .remove(['photo1.jpg', 'photo2.jpg'])

// Déplacer/renommer
const { error } = await supabase.storage
  .from('photos')
  .move('ancien-nom.jpg', 'nouveau-nom.jpg')

Policies de Sécurité Storage

-- Permettre à chaque utilisateur de gérer ses propres fichiers

CREATE POLICY "users_own_files"
ON storage.objects FOR SELECT
TO authenticated
USING (bucket_id = 'avatars' AND auth.uid()::TEXT = (storage.foldername(name))[1]);

CREATE POLICY "users_upload_own"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (bucket_id = 'avatars' AND auth.uid()::TEXT = (storage.foldername(name))[1]);

CREATE POLICY "users_delete_own"
ON storage.objects FOR DELETE
TO authenticated
USING (bucket_id = 'avatars' AND auth.uid()::TEXT = (storage.foldername(name))[1]);

👉 Articles du guide Supabase

Cet article fait partie du Guide Complet Supabase 2026. Retrouvez les autres articles :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *