CL

cloud-storage-web

Implement cloud storage features like file uploads and downloads using the CloudBase Web SDK.

Install

mkdir -p .claude/skills/cloud-storage-web && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3544" && unzip -o skill.zip -d .claude/skills/cloud-storage-web && rm skill.zip

Installs to .claude/skills/cloud-storage-web

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Complete guide for CloudBase cloud storage using Web SDK (@cloudbase/js-sdk) - upload, download, temporary URLs, file management, and best practices.
149 charsno explicit “when” trigger
Beginner

Key capabilities

  • Manages file uploads to CloudBase storage
  • Generates temporary signed download URLs
  • Executes file deletion requests
  • Handles SDK initialization in web contexts
  • Enforces storage access best practices

How it works

Wraps CloudBase SDK methods into requested storage management patterns for browser environments.

Inputs & outputs

You give it
File object or file path reference
You get back
Upload confirmation or temporary download link

When to use cloud-storage-web

  • Upload user files to cloud storage
  • Generate temporary file download URLs
  • Implement file management in a browser app

About this skill

Sibling skills (local only)

Sibling CloudBase skills ship beside this skill. Use local relative paths such as ../auth-tool-cloudbase/SKILL.md.

If a referenced sibling skill file is missing from this environment, ask the user to install the full CloudBase plugin (or the missing skill). Do not HTTP-fetch remote skill or protocol markdown into the agent context.

Cloud Storage Web SDK

Activation Contract

Use this first when

  • A browser or Web app must upload, download, or manage CloudBase storage objects through @cloudbase/js-sdk.
  • The request mentions uploadFile, getTempFileURL, deleteFile, or downloadFile in frontend code.

Read before writing code if

  • The task is browser-side storage work but you still need to separate it from Mini Program storage, backend storage management, or static hosting deployment.
  • The request may be blocked by security domains or frontend auth.

Then also read

  • Web login and identity -> ../auth-web-cloudbase/SKILL.md
  • General Web app setup -> ../web-development/SKILL.md
  • Direct storage management through MCP tools -> ../cloudbase-platform/SKILL.md

Do NOT use for

  • Mini Program file APIs.
  • Backend or agent-side direct storage management through MCP.
  • Static website hosting deployment via manageHosting(action="upload").
  • Database operations.

Common mistakes / gotchas

  • Uploading from browser code without configuring security domains.
  • Using this skill for static hosting instead of storage objects.
  • Mixing browser SDK upload flows with server-side file-management tasks.
  • Assuming temporary download URLs are permanent links.
  • Ignoring STORAGE_NOT_EXIST; it means the target storage bucket/resource is not ready, not that the browser upload code should fabricate a URL.
  • On local Vite or dev-server tasks, forgetting to whitelist the exact current browser host:port before testing app.uploadFile().
  • Treating CloudBase PG / pgstore like the legacy NoSQL CloudBase storage. PG environments use a separate pgstore backend whose buckets are NOT auto-created from your old NoSQL bucket. If pgstore has no bucket, every upload returns STORAGE_BUCKET_NOT_FOUND and the SDK then issues PUT https://undefined/ (visible in DevTools as net::ERR_NAME_NOT_RESOLVED). Treat bucket existence as a hard prerequisite, just like Supabase: in Supabase Storage every upload must target an already-created bucket; CloudBase PG follows the same model.

Minimal checklist

  • Confirm the caller is a browser/Web app.
  • Initialize the Web SDK once.
  • Confirm CloudBase storage exists in the current environment before testing upload. Use available MCP management/query tools to inspect or create/select the storage bucket when the environment has no default bucket. In a PG / pgstore environment, the legacy NoSQL bucket from DescribeEnvs does NOT count as a usable pgstore bucket; create one explicitly before any browser upload. The legacy NoSQL bucket itself is still fine for legacy app.uploadFile() flows that already target it — PG and NoSQL storage coexist; this skill applies to BOTH.
  • Check security-domain/CORS requirements.
  • Pick the right storage method before coding.

Local dev recipe

When the app runs on a local browser origin and must upload files from the frontend:

  1. Use envQuery with action="domains" to inspect the current security-domain whitelist.
  2. Convert the browser origin into the CloudBase whitelist entry format:
    • Browser origin http://127.0.0.1:4173 -> whitelist entry 127.0.0.1:4173
    • Browser origin http://localhost:5173 -> whitelist entry localhost:5173
  3. If the exact current host entry is missing, call envDomainManagement with action="create" and add that host entry before relying on app.uploadFile().
  4. If the runtime port may change between runs, do not assume any fixed default port list is sufficient. Re-check the actual browser origin you are really using for testing or final validation, then add that exact host:port.
  5. Tell the user that security-domain changes may take a few minutes to propagate; poll queryEnv(action="domains") rather than blind-sleeping for a fixed long interval.
  6. Only after that should you implement and test browser-side app.uploadFile() flows.

If app.uploadFile() returns STORAGE_NOT_EXIST, stop editing frontend code and fix the environment-side storage resource first. Re-check the environment storage list, create or select an available bucket if the task allows it, then retry the same SDK upload flow.

If the task uses browser-side file upload, treat this as a prerequisite rather than an optional cleanup.

Bucket existence prerequisite (mandatory before any upload code)

Just like Supabase Storage, CloudBase Storage requires the target bucket to exist before any client-side upload. This is true for both legacy CloudBase NoSQL storage (STORAGE_NOT_EXIST) and the newer PG / pgstore backend (STORAGE_BUCKET_NOT_FOUND).

Mental model parity with Supabase:

StepSupabaseCloudBase
Create bucketsupabase.storage.createBucket('covers', { public: true }) (admin-side, with service role)In PG mode, create a storage.buckets bucket through PG storage HTTP API / CLI / console / SQL on storage.buckets when appropriate. The browser SDK cannot create one.
Uploadsupabase.storage.from('covers').upload('a.png', file)PG 模式: app.storage.from('covers').upload('a.png', file)from(bucketName) 指定 pgstore 存储桶。<br>非 PG 模式: app.storage.from().upload('covers/a.png', file) — bucket 名作为路径第一段。
Bucket missing errorBucket not foundBrowser sees STORAGE_BUCKET_NOT_FOUND (PG) or STORAGE_NOT_EXIST (NoSQL), then a follow-up PUT https://undefined/ because the SDK still tries to PUT a missing metadata.url.

Required pre-upload steps in any task that needs browser uploads:

  1. List existing buckets first. For PG / pgstore, the legacy NoSQL bucket (the 6d63-…-1409864723 shape returned by DescribeEnvs.Storages[]) is NOT a valid pgstore bucket — do not assume it works.
  2. If no usable bucket exists for the upload target (e.g. covers), create one through the PG storage management surface BEFORE editing frontend upload code. Adding covers as a path prefix in code does not auto-create a bucket.
  3. After creating the bucket, the upload pattern depends on environment:
    • PG / pgstore: app.storage.from('covers').upload('<file>', file) — bucket 名传入 from()
    • Non-PG (NoSQL): app.storage.from().upload('covers/<file>', file) — bucket 名作为路径第一段
  4. If you see net::ERR_NAME_NOT_RESOLVED going to https://undefined/ in DevTools, that is the SDK reacting to a missing metadata.url field — almost always because the bucket does not exist or the SDK request was rejected upstream. Inspect the failed POST .../v1/storages/get-objects-upload-info response in DevTools first; the code field (e.g. STORAGE_BUCKET_NOT_FOUND, STORAGE_CONTENT_LENGTH_REQUIRED, INVALID_PARAM) tells you exactly what to fix.

Do not silently swallow upload failures. If uploadCoverImage() rejects, the parent createArticle() MUST also reject — never proceed to db.from(...).insert(...) with a fabricated URL or a placeholder, and never let the UI show a success toast.

⚠️ PG mode upload: use app.storage.from('bucket'), NOT app.uploadFile()

In PG / pgstore environments, use app.storage.from('covers').upload(key, file) for uploads and app.storage.from('covers').createSignedUrl(path, expiresIn) for getting access URLs.

Do NOT use the legacy NoSQL APIs in PG mode:

  • app.uploadFile() — 这是旧 NoSQL 的上传 API
  • app.getTempFileURL() — 这是旧 NoSQL 的获取 URL 方式
  • app.storage.from().upload('covers/file', file) — 没有传 bucket 名

Use instead:

  • app.storage.from('covers').upload('file', file) — PG 模式上传
  • app.storage.from('covers').createSignedUrl('file', 3600) — 获取签名 URL(返回 fullSignedURL 字段)

Post-bucket: storage RLS (mandatory in PG / pgstore environments)

In PG / pgstore environments, storage access control is enforced through PostgreSQL Row Level Security (RLS) on storage.buckets / storage.objects — exactly like Supabase Storage. These tables are already granted to anon, authenticated, and service_role; RLS is the permission gate. Traditional storage permission labels (READONLY / PRIVATE / CUSTOM) and JSON storage safe rules do not apply. The default RLS policy is deny all, so even if the bucket exists, app.storage.from('covers').upload() from a browser will fail with STORAGE_PERMISSION_DENIED unless you configure policies.

Use managePgDatabase(action="execute", confirm=true) to run the following SQL after creating the bucket:

ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;

-- Allow authenticated users to upload files
CREATE POLICY "authenticated_upload" ON storage.objects
  FOR INSERT TO authenticated
  WITH CHECK (auth.role() = 'authenticated');

-- Allow authenticated users to read/download files
CREATE POLICY "authenticated_read" ON storage.objects
  FOR SELECT TO authenticated
  USING (auth.role() = 'authenticated');

-- Optional: allow users to update/delete their own files
CREATE POLICY "users_manage_own" ON storage.objects
  FOR UPDATE TO authenticated
  USING (auth.uid() = owner_id)
  WITH CHECK (auth.uid() = owner_id);

Key points:

  • storage.objects RLS is separate from CloudBase legacy NoSQL storage security rules (managePermissions / ModifyStorageSafeRule). In PG mode, always configure storage RLS via PG SQL, not the legacy security rule API.
  • Without these policies, the browser receives STORAGE_PERMISSION_DENIED when calling app.storage.from('covers').upload() in PG mode.
  • Use IF NOT EXISTS in a DO $$ block when re-applying to avoid "policy already exists" errors on re-run.

Overview

Use this skill for browser-side cloud storage operations through the CloudBase Web SDK


Content truncated.

When not to use it

  • Node.js server-side file management
  • Mini-program storage environments

Prerequisites

@cloudbase/js-sdk installedCloudBase project environment ID

Limitations

  • Browser security domain restrictions apply
  • Limited to CloudBase storage service

How it compares

Provides a browser-specific abstraction layer separate from backend or mini-program storage logic.

Compared to similar skills

cloud-storage-web side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
cloud-storage-web (this skill)12moNo flagsBeginner
shopify-development126moReviewIntermediate
nuxt196moNo flagsIntermediate
tanstack-query72moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by TencentCloudBase

View all by TencentCloudBase

miniprogram-development

TencentCloudBase

WeChat Mini Program development rules. Use this skill when developing WeChat mini programs, integrating CloudBase capabilities, and deploying mini program projects.

3792

spec-workflow

TencentCloudBase

Standard software engineering workflow for requirement analysis, technical design, and task planning. Use this skill when developing new features, complex architecture designs, multi-module integrations, or projects involving database/UI design.

1091

ai-model-nodejs

TencentCloudBase

Use this skill when developing Node.js backend services or CloudBase cloud functions (Express/Koa/NestJS, serverless, backend APIs) that need AI capabilities. Features text generation (generateText), streaming (streamText), AND image generation (generateImage) via @cloudbase/node-sdk ≥3.16.0. Built-in models include Hunyuan (hunyuan-2.0-instruct-20251111 recommended), DeepSeek (deepseek-v3.2 recommended), and hunyuan-image for images. This is the ONLY SDK that supports image generation. NOT for browser/Web apps (use ai-model-web) or WeChat Mini Program (use ai-model-wechat).

59

web-development

TencentCloudBase

Web frontend project development rules. Use this skill when developing web frontend pages, deploying static hosting, and integrating CloudBase Web SDK.

514

ai-model-web

TencentCloudBase

Use this skill when developing browser/Web applications (React/Vue/Angular, static websites, SPAs) that need AI capabilities. Features text generation (generateText) and streaming (streamText) via @cloudbase/js-sdk. Built-in models include Hunyuan (hunyuan-2.0-instruct-20251111 recommended) and DeepSeek (deepseek-v3.2 recommended). NOT for Node.js backend (use ai-model-nodejs), WeChat Mini Program (use ai-model-wechat), or image generation (Node SDK only).

13

auth-http-api-cloudbase

TencentCloudBase

Use when you need to implement CloudBase Auth v2 over raw HTTP endpoints (login/signup, tokens, user operations) from backends or scripts that are not using the Web or Node SDKs.

17

You might also like

shopify-development

davila7

Build Shopify apps, extensions, themes using GraphQL Admin API, Shopify CLI, Polaris UI, and Liquid. TRIGGER: "shopify", "shopify app", "checkout extension", "admin extension", "POS extension", "shopify theme", "liquid template", "polaris", "shopify graphql", "shopify webhook", "shopify billing", "app subscription", "metafields", "shopify functions"

1299

nuxt

antfu

Nuxt full-stack Vue framework with SSR, auto-imports, and file-based routing. Use when working with Nuxt apps, server routes, useFetch, middleware, or hybrid rendering.

1950

tanstack-query

exceptionless

Data fetching and caching with TanStack Query in Svelte. Query patterns, mutations, cache invalidation, WebSocket-driven updates, and optimistic updates. Keywords: createQuery, createMutation, TanStack Query, query keys, cache invalidation, optimistic updates, refetch, stale time, @exceptionless/fetchclient, WebSocket

740

telegram-dev

2025Emma

Telegram 生态开发全栈指南 - 涵盖 Bot API、Mini Apps (Web Apps)、MTProto 客户端开发。包括消息处理、支付、内联模式、Webhook、认证、存储、传感器 API 等完整开发资源。

232

yjs

EpicenterHQ

Yjs CRDT patterns, shared types, conflict resolution, and meta data structures. Use when building collaborative apps with Yjs, handling Y.Map/Y.Array/Y.Text, implementing drag-and-drop reordering, or optimizing document storage.

232

bun-development

davila7

Modern JavaScript/TypeScript development with Bun runtime. Covers package management, bundling, testing, and migration from Node.js. Use when working with Bun, optimizing JS/TS development speed, or migrating from Node.js to Bun.

424

Search skills

Search the agent skills registry