unno 프로젝트에서 명함을 이미지로 저장할 때, 다음과 같은 경로로 Supabase Storage에 PNG 파일을 저장하도록 설계하였다.
const fileName = `${label}_${lastSlug}_img.png`;
const filePath = `${userId}/${lastSlug}/${fileName}`;
즉, 하나의 slug에 대해 front_img.png, back_img.png 같은 고정된 경로에 저장되는 구조다.
같은 slug로 다시 저장(즉, 이미지 덮어쓰기)하면 다음 문제가 발생했다:
(Cmd+Shift+R)을 해야만 새로운 이미지가 반영됨| 항목 | 설명 |
|---|---|
| 저장 방식 | 동일 경로(/cards/{slug}_img.png)에 파일을 덮어씀 |
| 브라우저 반응 | 이전 이미지가 계속 캐시되어 보임 |
| Supabase 상태 | 파일은 분명 최신 버전으로 저장됨 |
| 사용자 경험 | "왜 저장했는데 반영이 안 돼?" 라는 혼란 발생 |
Supabase는 Cloudflare 기반 CDN을 통해 전 세계에 분산된 이미지 서버를 제공한다.
출처: Supabase Smart CDN 소개


사용자가 업로드한 이미지가 Supabase Storage에 저장된다.
Supabase는 이를 Cloudflare CDN에 자동 복제(Cache) 한다.
이후 동일한 URL 요청이 들어오면 CDN에서 캐시된 이미지를 반환한다.
즉, 원본이 변경되어도, 캐시가 만료되기 전까지는 이전 이미지가 계속 반환된다.
참고 문서:
Supabase Smart CDN 공식 문서
const timestamp = new Date().getTime();
const imageUrl = `https://.../cards/${fileName}?v=${timestamp}`;
Supabase는 URL 쿼리를 무시하고 동일한 리소스를 반환하지만,
브라우저는 ?v=12345678이 붙은 걸 새 파일로 취급하며 캐시를 우회한다.
const fileName = `${label}_${lastSlug}_${Date.now()}_img.png`;
경로 자체를 변경함으로써 캐시를 완전히 피할 수 있다.
다만 기존 파일을 수동으로 정리해줘야 하고, 저장소 관리가 복잡해질 수 있다.
현재는 사용자가 TTL(Time To Live) 값을 설정하거나 purge(강제 초기화)하는 기능은 제공되지 않는다.
Smart CDN은 Pro 요금제에서만 자동 무효화를 제공하며, Free 요금제에서는 직접 우회 처리를 해야 한다.