jpskill.com
🛠️ 開発・MCP コミュニティ

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本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
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
🪟 Windows (PowerShell)
$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. 1. 下の青いボタンを押して supabase-storage.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → supabase-storage フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

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 が必要

バケットの作成 (ダッシュボード)

  1. ダッシュボードの Storage に移動します。
  2. 「New bucket」をクリックします。
  3. 名前とパブリック/プライベートを設定します。
  4. ファイルサイズの制限と許可される 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)

  1. Go to Storage in Dashboard
  2. Click "New bucket"
  3. Set name and public/private
  4. 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