Supabase Storage ile React'te Dosya Yükleme: Drag & Drop Rehberi
Supabase Storage ile React'te dosya yükleme nasıl yapılır? Drag & drop, boyut validasyonu, progress bar, signed URL ve RLS ile güvenli dosya yönetimi.
Supabase Storage Nedir?
Supabase Storage, S3 uyumlu bir dosya depolama servisidir. Resim, PDF, video — her türlü dosyayı yükleyebilir, RLS ile güvenlik sağlayabilirsiniz.
Bucket Oluşturma
-- Supabase SQL Editor
INSERT INTO storage.buckets (id, name, public)
VALUES ('documents', 'documents', false);
-- Public bucket (herkes okuyabilir)
INSERT INTO storage.buckets (id, name, public)
VALUES ('avatars', 'avatars', true);
RLS Politikaları
-- Kullanıcı kendi dosyalarını yükleyebilsin
CREATE POLICY "Users upload own files" ON storage.objects
FOR INSERT
TO authenticated
WITH CHECK (
bucket_id = 'documents' AND
(storage.foldername(name))[1] = auth.uid()::text
);
-- Kullanıcı kendi dosyalarını okuyabilsin
CREATE POLICY "Users read own files" ON storage.objects
FOR SELECT
TO authenticated
USING (
bucket_id = 'documents' AND
(storage.foldername(name))[1] = auth.uid()::text
);
React Dosya Yükleme Bileşeni
import { useState, useCallback } from 'react';
import { supabase } from '../lib/supabase';
interface FileUploadProps {
bucket: string;
folder: string;
accept?: string;
maxSizeMB?: number;
onUpload: (url: string) => void;
}
export function FileUpload({
bucket, folder, accept = '*', maxSizeMB = 5, onUpload
}: FileUploadProps) {
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const [error, setError] = useState('');
const [dragOver, setDragOver] = useState(false);
const uploadFile = useCallback(async (file: File) => {
setError('');
// Boyut kontrolü
if (file.size > maxSizeMB * 1024 * 1024) {
setError(`Dosya ${maxSizeMB}MB'dan büyük olamaz.`);
return;
}
setUploading(true);
setProgress(0);
const filePath = `${folder}/${Date.now()}_${file.name}`;
const { data, error: uploadError } = await supabase.storage
.from(bucket)
.upload(filePath, file, {
cacheControl: '3600',
upsert: false,
});
if (uploadError) {
setError(uploadError.message);
setUploading(false);
return;
}
// Public URL al
const { data: { publicUrl } } = supabase.storage
.from(bucket)
.getPublicUrl(data.path);
setProgress(100);
setUploading(false);
onUpload(publicUrl);
}, [bucket, folder, maxSizeMB, onUpload]);
const handleDrop = useCallback((e: React.DragEvent) => {
e.preventDefault();
setDragOver(false);
const file = e.dataTransfer.files[0];
if (file) uploadFile(file);
}, [uploadFile]);
return (
<div
onDragOver={e => { e.preventDefault(); setDragOver(true); }}
onDragLeave={() => setDragOver(false)}
onDrop={handleDrop}
style={{
border: `2px dashed ${dragOver ? '#3b82f6' : '#d1d5db'}`,
borderRadius: '12px',
padding: '2em',
textAlign: 'center',
transition: 'border-color 0.2s',
backgroundColor: dragOver ? '#eff6ff' : 'transparent',
}}
>
<input
type="file"
accept={accept}
onChange={e => e.target.files?.[0] && uploadFile(e.target.files[0])}
style={{ display: 'none' }}
id="file-input"
/>
<label htmlFor="file-input" style={{ cursor: 'pointer' }}>
{uploading ? (
<p>Yükleniyor... {progress}%</p>
) : (
<p>Dosyayı sürükleyin veya <strong>tıklayarak seçin</strong></p>
)}
</label>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
Signed URL ile Geçici Erişim
Private bucket’taki dosyalara süreli erişim:
// 1 saatlik erişim URL'i oluştur
const { data, error } = await supabase.storage
.from('documents')
.createSignedUrl('user123/report.pdf', 3600);
// data.signedUrl → 1 saat geçerli URL
Dosya Silme
const { error } = await supabase.storage
.from('documents')
.remove(['user123/old-file.pdf']);
Dosya Tip ve Boyut Validasyonu
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
const MAX_SIZE = 10 * 1024 * 1024; // 10MB
function validateFile(file: File): string | null {
if (!ALLOWED_TYPES.includes(file.type)) {
return `Desteklenmeyen dosya tipi: ${file.type}`;
}
if (file.size > MAX_SIZE) {
return `Dosya çok büyük: ${(file.size / 1024 / 1024).toFixed(1)}MB (max: 10MB)`;
}
return null;
}
İlgili Yazılar
- Supabase Auth — Auth + Storage entegrasyonu
- Supabase RLS — Dosya erişim politikaları
- .env Güvenli Yönetimi — Storage key güvenliği
Bu rehber Supabase Storage Docs dokümantasyonuna dayanarak hazırlanmıştır.