supabase-storage
ファイルアップロードやダウンロード、ストレージバケット管理、署名付きURL生成、画像処理など、Supabase Storageの機能を活用して、ビジネスに必要なファイル管理を効率化するSkill。
📜 元の英語説明(参考)
Supabase Storage for file uploads, downloads, buckets, and signed URLs. Use when uploading files, managing storage buckets, generating signed URLs, or handling images.
🇯🇵 日本人クリエイター向け解説
ファイルアップロードやダウンロード、ストレージバケット管理、署名付きURL生成、画像処理など、Supabase Storageの機能を活用して、ビジネスに必要なファイル管理を効率化するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o supabase-storage.zip https://jpskill.com/download/9505.zip && unzip -o supabase-storage.zip && rm supabase-storage.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9505.zip -OutFile "$d\supabase-storage.zip"; Expand-Archive "$d\supabase-storage.zip" -DestinationPath $d -Force; ri "$d\supabase-storage.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
supabase-storage.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
supabase-storageフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Supabase Storage Skill
ファイルストレージ、アップロード、ダウンロード、およびバケット管理。
クイックリファレンス
| タスク | メソッド |
|---|---|
| ファイルのアップロード | storage.from('bucket').upload(path, file) |
| ファイルのダウンロード | storage.from('bucket').download(path) |
| パブリック URL の取得 | storage.from('bucket').getPublicUrl(path) |
| 署名付き URL の取得 | storage.from('bucket').createSignedUrl(path, 3600) |
| ファイルの削除 | storage.from('bucket').remove([path]) |
| ファイルの一覧表示 | storage.from('bucket').list(folder) |
| ファイルの移動 | storage.from('bucket').move(from, to) |
| ファイルのコピー | storage.from('bucket').copy(from, to) |
バケットの設定
パブリック vs プライベート
- Public: 認証なしで URL 経由でアクセス可能なファイル
- Private: 認証または署名付き URL が必要
バケットの作成 (ダッシュボード)
- ダッシュボードの Storage に移動します。
- 「New bucket」をクリックします。
- 名前とパブリック/プライベートを設定します。
- ファイルサイズの制限と許可される MIME タイプを設定します。
バケットの作成 (SQL)
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
VALUES (
'avatars',
'avatars',
true,
5242880, -- 5MB
ARRAY['image/jpeg', 'image/png', 'image/webp']
);
バケットの作成 (config.toml)
[storage.buckets.avatars]
public = true
file_size_limit = "5MiB"
allowed_mime_types = ["image/png", "image/jpeg", "image/webp"]
[storage.buckets.documents]
public = false
file_size_limit = "50MiB"
allowed_mime_types = ["application/pdf"]
ファイルのアップロード
基本的なアップロード
const { data, error } = await supabase.storage
.from('avatars')
.upload('user-123/avatar.png', file)
オプション付きのアップロード
const { data, error } = await supabase.storage
.from('avatars')
.upload('user-123/avatar.png', file, {
cacheControl: '3600',
contentType: 'image/png',
upsert: true // Replace if exists
})
ブラウザからのアップロード
const fileInput = document.querySelector('input[type="file"]')
const file = fileInput.files[0]
const { data, error } = await supabase.storage
.from('uploads')
.upload(`${userId}/${file.name}`, file)
Base64 のアップロード
const base64Data = 'data:image/png;base64,iVBOR...'
const base64 = base64Data.split(',')[1]
const buffer = Uint8Array.from(atob(base64), c => c.charCodeAt(0))
const { data, error } = await supabase.storage
.from('images')
.upload('photo.png', buffer, {
contentType: 'image/png'
})
ファイルのダウンロード
Blob としてダウンロード
const { data, error } = await supabase.storage
.from('documents')
.download('report.pdf')
// data is a Blob
const url = URL.createObjectURL(data)
ブラウザへのダウンロード
const { data } = await supabase.storage
.from('documents')
.download('report.pdf')
const link = document.createElement('a')
link.href = URL.createObjectURL(data)
link.download = 'report.pdf'
link.click()
URL の取得
パブリック URL (パブリックバケット)
const { data } = supabase.storage
.from('avatars')
.getPublicUrl('user-123/avatar.png')
console.log(data.publicUrl)
// https://xxx.supabase.co/storage/v1/object/public/avatars/user-123/avatar.png
署名付き URL (プライベートバケット)
const { data, error } = await supabase.storage
.from('documents')
.createSignedUrl('private/report.pdf', 3600) // 1 hour
console.log(data.signedUrl)
複数の署名付き URL
const { data, error } = await supabase.storage
.from('documents')
.createSignedUrls(['doc1.pdf', 'doc2.pdf'], 3600)
署名付きアップロード URL
const { data, error } = await supabase.storage
.from('uploads')
.createSignedUploadUrl('user-123/file.pdf')
// data.signedUrl は 2 時間有効です
// data.token はアップロードトークンです
ファイルの一覧表示
フォルダ内のすべてを一覧表示
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123')
// data: [{ name, id, metadata, ... }]
オプション付き
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123', {
limit: 100,
offset: 0,
sortBy: { column: 'created_at', order: 'desc' }
})
ファイルの検索
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123', {
search: 'report' // Filename contains 'report'
})
ファイルの削除
単一ファイル
const { data, error } = await supabase.storage
.from('uploads')
.remove(['user-123/old-file.pdf'])
複数ファイル
const { data, error } = await supabase.storage
.from('uploads')
.remove([
'user-123/file1.pdf',
'user-123/file2.pdf',
'user-123/file3.pdf'
])
移動とコピー
ファイルの移動
const { data, error } = await supabase.storage
.from('uploads')
.move('old-path/file.pdf', 'new-path/file.pdf')
ファイルのコピー
const { data, error } = await supabase.storage
.from('uploads')
.copy('original/file.pdf', 'backup/file.pdf')
画像変換
Pro プラン以上で利用可能です。
サイズ変更
const { data } = supabase.storage
.from('avatars')
.getPublicUrl('user-123/photo.jpg', {
transform: {
width: 200,
height: 200,
resize: 'cover' // cover, contain, fill
}
})
品質
const { data } = supabase.storage
.from('images')
.getPublicUrl('photo.jpg', {
transform: {
width: 800,
quality: 75 // 20-100
}
})
フォーマット変換
const { data } = supabase.storage
.from('images')
.getPublicUrl('photo.png', {
transform: {
format: 'webp' // webp, jpeg, png
}
})
Storage RLS ポリシー
RLS の有効化
-- RLS は storage.objects でデフォルトで有効になっています
一般的なポリシー
-- ユーザーは自分のファイルを表示できます
CREATE POLICY "Users can view own files"
ON storage.objects FOR SELECT
TO authenticated
USING (bucket_id = 'up 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Supabase Storage Skill
File storage, uploads, downloads, and bucket management.
Quick Reference
| Task | Method |
|---|---|
| Upload file | storage.from('bucket').upload(path, file) |
| Download file | storage.from('bucket').download(path) |
| Get public URL | storage.from('bucket').getPublicUrl(path) |
| Get signed URL | storage.from('bucket').createSignedUrl(path, 3600) |
| Delete file | storage.from('bucket').remove([path]) |
| List files | storage.from('bucket').list(folder) |
| Move file | storage.from('bucket').move(from, to) |
| Copy file | storage.from('bucket').copy(from, to) |
Bucket Configuration
Public vs Private
- Public: Files accessible via URL without authentication
- Private: Requires authentication or signed URLs
Create Bucket (Dashboard)
- Go to Storage in Dashboard
- Click "New bucket"
- Set name and public/private
- Configure file size limits and allowed MIME types
Create Bucket (SQL)
INSERT INTO storage.buckets (id, name, public, file_size_limit, allowed_mime_types)
VALUES (
'avatars',
'avatars',
true,
5242880, -- 5MB
ARRAY['image/jpeg', 'image/png', 'image/webp']
);
Create Bucket (config.toml)
[storage.buckets.avatars]
public = true
file_size_limit = "5MiB"
allowed_mime_types = ["image/png", "image/jpeg", "image/webp"]
[storage.buckets.documents]
public = false
file_size_limit = "50MiB"
allowed_mime_types = ["application/pdf"]
Upload Files
Basic Upload
const { data, error } = await supabase.storage
.from('avatars')
.upload('user-123/avatar.png', file)
Upload with Options
const { data, error } = await supabase.storage
.from('avatars')
.upload('user-123/avatar.png', file, {
cacheControl: '3600',
contentType: 'image/png',
upsert: true // Replace if exists
})
Upload from Browser
const fileInput = document.querySelector('input[type="file"]')
const file = fileInput.files[0]
const { data, error } = await supabase.storage
.from('uploads')
.upload(`${userId}/${file.name}`, file)
Upload Base64
const base64Data = 'data:image/png;base64,iVBOR...'
const base64 = base64Data.split(',')[1]
const buffer = Uint8Array.from(atob(base64), c => c.charCodeAt(0))
const { data, error } = await supabase.storage
.from('images')
.upload('photo.png', buffer, {
contentType: 'image/png'
})
Download Files
Download as Blob
const { data, error } = await supabase.storage
.from('documents')
.download('report.pdf')
// data is a Blob
const url = URL.createObjectURL(data)
Download to Browser
const { data } = await supabase.storage
.from('documents')
.download('report.pdf')
const link = document.createElement('a')
link.href = URL.createObjectURL(data)
link.download = 'report.pdf'
link.click()
Get URLs
Public URL (Public Buckets)
const { data } = supabase.storage
.from('avatars')
.getPublicUrl('user-123/avatar.png')
console.log(data.publicUrl)
// https://xxx.supabase.co/storage/v1/object/public/avatars/user-123/avatar.png
Signed URL (Private Buckets)
const { data, error } = await supabase.storage
.from('documents')
.createSignedUrl('private/report.pdf', 3600) // 1 hour
console.log(data.signedUrl)
Multiple Signed URLs
const { data, error } = await supabase.storage
.from('documents')
.createSignedUrls(['doc1.pdf', 'doc2.pdf'], 3600)
Signed Upload URL
const { data, error } = await supabase.storage
.from('uploads')
.createSignedUploadUrl('user-123/file.pdf')
// data.signedUrl is valid for 2 hours
// data.token is the upload token
List Files
List All in Folder
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123')
// data: [{ name, id, metadata, ... }]
With Options
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123', {
limit: 100,
offset: 0,
sortBy: { column: 'created_at', order: 'desc' }
})
Search Files
const { data, error } = await supabase.storage
.from('uploads')
.list('user-123', {
search: 'report' // Filename contains 'report'
})
Delete Files
Single File
const { data, error } = await supabase.storage
.from('uploads')
.remove(['user-123/old-file.pdf'])
Multiple Files
const { data, error } = await supabase.storage
.from('uploads')
.remove([
'user-123/file1.pdf',
'user-123/file2.pdf',
'user-123/file3.pdf'
])
Move & Copy
Move File
const { data, error } = await supabase.storage
.from('uploads')
.move('old-path/file.pdf', 'new-path/file.pdf')
Copy File
const { data, error } = await supabase.storage
.from('uploads')
.copy('original/file.pdf', 'backup/file.pdf')
Image Transformations
Available on Pro plan and above.
Resize
const { data } = supabase.storage
.from('avatars')
.getPublicUrl('user-123/photo.jpg', {
transform: {
width: 200,
height: 200,
resize: 'cover' // cover, contain, fill
}
})
Quality
const { data } = supabase.storage
.from('images')
.getPublicUrl('photo.jpg', {
transform: {
width: 800,
quality: 75 // 20-100
}
})
Format Conversion
const { data } = supabase.storage
.from('images')
.getPublicUrl('photo.png', {
transform: {
format: 'webp' // webp, jpeg, png
}
})
Storage RLS Policies
Enable RLS
-- RLS is enabled by default on storage.objects
Common Policies
-- Users can view their own files
CREATE POLICY "Users can view own files"
ON storage.objects FOR SELECT
TO authenticated
USING (bucket_id = 'uploads' AND auth.uid()::text = (storage.foldername(name))[1]);
-- Users can upload to their folder
CREATE POLICY "Users can upload own files"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (bucket_id = 'uploads' AND auth.uid()::text = (storage.foldername(name))[1]);
-- Users can delete their files
CREATE POLICY "Users can delete own files"
ON storage.objects FOR DELETE
TO authenticated
USING (bucket_id = 'uploads' AND auth.uid()::text = (storage.foldername(name))[1]);
Public Bucket Policy
-- Anyone can view public files
CREATE POLICY "Public read"
ON storage.objects FOR SELECT
TO public
USING (bucket_id = 'public-images');
Error Handling
const { data, error } = await supabase.storage
.from('uploads')
.upload('file.pdf', file)
if (error) {
if (error.message === 'The resource already exists') {
console.log('File already exists')
} else if (error.message.includes('exceeded')) {
console.log('File too large')
} else if (error.message.includes('mime type')) {
console.log('Invalid file type')
} else {
console.error('Upload error:', error.message)
}
}
Size Limits
| Plan | Max File Size |
|---|---|
| Free | 50 MB |
| Pro+ | 500 GB |
References
- storage-policies.md - RLS policy patterns
- upload-patterns.md - Upload best practices