@stackshift-cloud/assets-widget
v1.0.0
Published
Accessible, resumable Stackshift Assets uploads for React and vanilla JavaScript.
Readme
@stackshift-cloud/assets-widget
Embeddable local-file, drag/drop, URL, camera, crop, preview, and resumable multipart uploads for Stackshift Assets. The browser receives only a short-lived, one-session upload capability from your backend; never expose a Stackshift API key in frontend code.
Install
npm install @stackshift-cloud/assets-widget @stackshift-cloud/sdkImport the isolated stylesheet once:
import '@stackshift-cloud/assets-widget/style.css'Backend capability endpoint
Create the capability with your server-side Stackshift SDK. Bind it to the browser origin, bucket, key prefix, MIME types, size, and a short expiry.
const created = await stackshift.assets.uploadCapabilities.create({
bucket: 'customer-uploads',
key_prefix: `users/${user.id}`,
allowed_mime_types: ['image/jpeg', 'image/png'],
allowed_origins: ['https://app.example.com'],
max_bytes: 25 * 1024 * 1024,
allow_remote_url: true,
expires_in: '15m',
})
return Response.json({ token: created.token, expiresAt: created.capability.expires_at })Authorize this host endpoint with your own application session. Return a fresh capability for each file. Capabilities are bound to a single upload session and become unusable after completion or cancellation.
Vanilla JavaScript
import { createAssetsWidget } from '@stackshift-cloud/assets-widget'
import '@stackshift-cloud/assets-widget/style.css'
const widget = createAssetsWidget(document.querySelector('#asset-upload')!, {
getUploadCapability: async (file) => {
const response = await fetch('/api/assets/upload-capability', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(file),
})
if (!response.ok) throw new Error('Could not authorize upload')
return response.json()
},
accept: 'image/*,application/pdf',
allowCamera: true,
allowRemoteUrl: true,
crop: { enabled: true, aspectRatio: 1 },
onComplete: (asset) => console.log(asset.id),
})
// Call when removing the containing view.
widget.destroy()React
import { StackshiftAssetsWidget } from '@stackshift-cloud/assets-widget/react'
import '@stackshift-cloud/assets-widget/style.css'
export function AssetUpload() {
return <StackshiftAssetsWidget getUploadCapability={authorizeUpload} accept="image/*" />
}Multipart session metadata is stored in IndexedDB. Selecting the same file after a reload reconciles uploaded parts with Stackshift before continuing. Expired or file-mismatched records are discarded. The widget includes keyboard-operable selection, focus retention, screen-reader progress announcements, responsive layouts, and reduced-motion behavior.
