Skip to main content
Live. This area is documented as current, user-reliable behavior.

Goal

Embed a production upload experience without placing a permanent or publishable StackShift credential in browser code.

Prerequisites

  • Node.js 20 or newer for package builds
  • @stackshift-cloud/assets-widget 1.0.0 and @stackshift-cloud/sdk 1.1.0 or newer
  • A trusted backend with a StackShift token carrying assets:write
  • An existing Assets bucket and an HTTPS browser origin

Workflow

1
Create a host-backend endpoint authenticated by your application session.
2
For each file, have that endpoint create one short-lived upload capability with a server-chosen bucket, fixed key or prefix, MIME allowlist, byte limit, exact origin, and expiry.
3
Render the React or vanilla widget and provide an asynchronous getUploadCapability callback that calls only your host endpoint.
4
Subscribe to progress, completion, and error events and store the returned Asset ID in your application data.
5
Destroy a vanilla widget when its containing view is removed. The React wrapper handles teardown during unmount.

Install and import

The package publishes isolated ss-assets-widget CSS, ESM and CommonJS builds, source maps, TypeScript declarations, and separate vanilla and React entry points. Import the stylesheet exactly once in the application shell.

Issue capabilities on your backend

Authenticate the caller with your own application session and derive authorization from server-side identity. Do not accept the bucket, allowed origin, key prefix, byte limit, or MIME policy directly from an untrusted browser body. Return only the one-time capability token and expiry.
Backend route

Capability boundary

  • Creation accepts bucket, optional key_prefix or fixed_key, allowed_mime_types, one or more exact allowed_origins, max_bytes, allow_remote_url, and expires_in.
  • Expiry must be between one second and one hour. Origins must be HTTPS origins without a path, query, fragment, or embedded credentials.
  • The opaque token is shown only when created. The server stores its SHA-256 hash and binds the capability to one tenant, user, and upload session.
  • Widget routes accept the capability bearer token, not a general API key. They can create/read/complete/cancel only the bound session, upload its parts, or perform an explicitly allowed remote-URL ingestion.
  • Part requests include X-Content-SHA256. Completion revokes the capability; cancellation cancels the session and revokes it.

React integration

Vanilla JavaScript integration

Inputs, crop metadata, resume, and accessibility

  • Local picker and drag/drop respect accept; maxFiles defaults to 20. Camera capture uses the environment-facing mobile file input and falls back to the device file picker.
  • Remote URL controls appear only when allowRemoteUrl is true. The backend capability must separately set allow_remote_url: true; source redirects and private/reserved networks are rejected.
  • Cropping supports JPEG, PNG, or WebP output, quality, aspect ratio, keyboard-operable numeric geometry, and “Use original.” The uploaded asset metadata receives stackshift_crop with source dimensions and pixel x, y, width, and height.
  • Queue concurrency defaults to 2 and is bounded to 1–6. Chunk concurrency defaults to 4 and is bounded to 1–8. Chunk and completion attempts default to 4 and are bounded to 1–8 with exponential backoff.
  • IndexedDB stores the file fingerprint and session state. Reload reconciliation asks the server for received parts and re-hashes matching local parts before skipping them. Expired, mismatched, or invalid sessions are discarded safely.
  • The widget supplies keyboard activation, labeled controls, focus restoration after queue rendering, native progress semantics, polite live announcements, responsive styles, and reduced-motion rules.

Expected result

Browser files upload directly through the capability-only widget routes, resume safely after reload, and complete as normal StackShift Assets.

Common failures

  • The backend returns a capability created for a different HTTPS origin, key prefix, MIME type, or maximum size.
  • A capability is reused after it has already been bound to one session, completed, canceled, revoked, or expired.
  • Remote URL ingestion is requested without allow_remote_url, or the remote host redirects or resolves to a private address.
  • Browser storage is blocked; uploads still run, but resume state falls back to memory and will not survive a reload.

Direct browser uploads

Upload browser files directly with short-lived sessions, per-part checksums, progress callbacks, retries, resume, and cancellation.

Assets platform API, SDK, CLI, and operations

A complete interface and recovery reference for storage connections, S2, imports, relocation, OCR, browser capabilities, reports, scopes, events, billing, and durable worker behavior.

Storage connections, BYOB, and StackShift S2

Configure AWS S3, Cloudflare R2, Wasabi, MinIO, generic S3, or native StackShift S2 without exposing customer storage credentials or changing delivery URLs.