一键导入
frontend-supabase-sdk
Use when making direct Supabase SDK calls in TypeScript files (hooks, components, routes, utilities)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when making direct Supabase SDK calls in TypeScript files (hooks, components, routes, utilities)
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | frontend-supabase-sdk |
| description | Use when making direct Supabase SDK calls in TypeScript files (hooks, components, routes, utilities) |
const sb_Service[StringParam]_Operation = await supabase.service.method()
Components:
sb_ - Prefix for all Supabase SDK responsesService - The Supabase service: Auth, From, Functions, Storage[StringParam] - String parameters converted to PascalCase and concatenated directly (no underscore)Operation - The primary operation: Select, Insert, Update, Delete, Invoke, etc.snake_case → PascalCase
"organization_members" → OrganizationMembers
"rel_files_tags" → RelFilesTags
kebab-case → PascalCase
"generate-upload-url" → GenerateUploadUrl
"delete-file" → DeleteFile
Concatenation: String parameters are concatenated directly with the service/method name (no underscore between them)
Use only the main operation, ignore modifiers like .single(), .eq(), .maybeSingle(), etc.
// ✅ Correct - primary operation only
const sb_FromProjects_Select = await supabase.from("projects").select().eq("id", id).single();
// ❌ Wrong - don't include modifiers
const sb_FromProjects_SelectEqSingle = await supabase
.from("projects")
.select()
.eq("id", id)
.single();
// Insert
const sb_FromProjects_Insert = await supabase.from("projects").insert(body).select().single();
// Select
const sb_FromOrganizationMembers_Select = await supabase
.from("organization_members")
.select("*, organizations(*)")
.eq("user_id", userId);
// Update
const sb_FromProjects_Update = await supabase
.from("projects")
.update(body)
.eq("id", id)
.select()
.single();
// Delete
const sb_FromRelFilesTags_Delete = await supabase
.from("rel_files_tags")
.delete()
.eq("file_id", fileId);
const sb_Auth_GetUser = await supabase.auth.getUser();
const user = sb_Auth_GetUser.data.user;
const sb_Auth_GetSession = await supabase.auth.getSession();
const session = sb_Auth_GetSession.data.session;
const sb_Auth_SignOut = await supabase.auth.signOut();
const sb_Functions_InvokeGenerateUploadUrl = await supabase.functions.invoke(
"generate-upload-url",
{ body: { fileName, projectId } }
);
const sb_StorageProjectFiles_Upload = await supabase.storage
.from("project-files")
.upload(path, file);
const sb_StorageProjectFiles_Download = await supabase.storage.from("project-files").download(path);
const sb_FromProjects_Select = await supabase.from("projects").select();
if (sb_FromProjects_Select.error) {
console.error(sb_FromProjects_Select.error);
throw sb_FromProjects_Select.error;
}
const projects = sb_FromProjects_Select.data;
Naming Conflicts:
const { data, error } = await supabase.from("projects").insert();
const { data, error } = await supabase.from("files").select(); // ❌ Conflict!
Ugly Inline Renaming:
const { data: uploadData, error: urlError } =
await supabase.functions.invoke("generate-upload-url");
const {
data: { user },
error: userError,
} = await supabase.auth.getUser();
const { data: metadata, error: metadataError } = await supabase.from("files").insert();
Inconsistent Patterns:
const { data: projects, error: projectsError }; // One dev's choice
const { data: projectData, error: projectErr }; // Another dev's choice
const sb_FromProjects_Insert = await supabase.from("projects").insert(body);
if (sb_FromProjects_Insert.error) {
console.error("Failed to create project:", sb_FromProjects_Insert.error);
throw sb_FromProjects_Insert.error;
}
return sb_FromProjects_Insert.data;
const sb_Auth_GetUser = await supabase.auth.getUser();
if (sb_Auth_GetUser.error || !sb_Auth_GetUser.data.user) {
return null;
}
const user = sb_Auth_GetUser.data.user;
const sb_Auth_GetSession = await supabase.auth.getSession();
const session = sb_Auth_GetSession.data.session;
In Query Hooks (useQ_*):
const queryFn = async (projectId: string) => {
const sb_FromFiles_Select = await supabase
.from("files")
.select("*, rel_files_tags(file_tags(*))")
.eq("project_id", projectId);
if (sb_FromFiles_Select.error) throw sb_FromFiles_Select.error;
return sb_FromFiles_Select.data;
};
In Mutation Hooks (useM_*):
const mutationFn = async (body: CreateProjectBody) => {
const sb_FromProjects_Insert = await supabase.from("projects").insert(body).select().single();
if (sb_FromProjects_Insert.error) throw sb_FromProjects_Insert.error;
return sb_FromProjects_Insert.data;
};
In Route Guards:
export const loader = async () => {
const sb_Auth_GetSession = await supabase.auth.getSession();
const session = sb_Auth_GetSession.data.session;
if (!session) {
throw redirect({ to: "/login" });
}
return { session };
};
For additional examples: .claude/skills/frontend-supabase-sdk/examples.md
Use when deploying Cloudflare Workers, managing R2 storage, or working with Cloudflare infrastructure
Use when working with ANTD components, theme tokens, icons, forms, or feedback components (message/notification/modal)
Use when adding, referencing, or serving static assets (images, fonts, videos, 3D models) through the R2 CDN pipeline with type-safe imports
Use when writing or reviewing JavaScript/TypeScript code for style patterns like concise arrows, inline handlers, expression formatting, or when tempted to use eslint-disable
Use when working with environment variables in frontend code
Use when creating or modifying keyboard shortcuts/hotkeys in frontend code