Elements
Pre-built React components for common patterns when working with Stack0. Copy, paste, and customize.
File Upload
Drag-and-drop file upload with progress tracking and multi-file support.
Avatar Upload
Circular avatar upload with preview, fallback initials, and remove functionality.
Logo Upload
Rectangular logo upload with multiple aspect ratios and SVG support.
Image Gallery
Responsive image grid with lightbox, selection, and action support.
Image
next/image wrapper optimized for Stack0 CDN with built-in transforms.
Installation
Choose your preferred installation method:
Recommended: shadcn CLI
Copy components directly into your project with full customization control:
npx shadcn@latest add https://www.stack0.dev/r/file-uploadnpx shadcn@latest add https://www.stack0.dev/r/avatar-uploadnpx shadcn@latest add https://www.stack0.dev/r/logo-uploadnpx shadcn@latest add https://www.stack0.dev/r/image-gallerynpx shadcn@latest add https://www.stack0.dev/r/image
Alternative: NPM Package
# Install the packagenpm install @stack0/elements# Or with pnpmpnpm add @stack0/elements# Or with bunbun add @stack0/elements
Required peer dependencies:
npm install class-variance-authority clsx tailwind-merge lucide-react
Stack0 Integration
Elements work with any upload backend. Create an API endpoint on your server that returns presigned URLs, then use the handler on the client:
// Client-side usageimport { FileUpload, createStack0Handler } from '@stack0/elements'const handler = createStack0Handler({endpoint: '/api/upload', // Your API endpoint})<FileUpload handler={handler} />
// Server-side API route (Next.js App Router)// app/api/upload/route.tsimport { stack0 } from '@stack0/sdk'export async function POST(request: Request) {const { filename, mimeType, size, folder } = await request.json()const result = await stack0.cdn.createUpload({filename,mimeType,size,folder,public: true, // Creates a public presigned URL})return Response.json({uploadUrl: result.uploadUrl,assetId: result.assetId,})}
Custom Handlers
Create your own upload handler for any backend:
import { FileUpload, type UploadHandler } from '@stack0/elements'const customHandler: UploadHandler = {// Get a presigned URL for uploadinggetUploadUrl: async (file) => {const response = await fetch('/api/upload', {method: 'POST',body: JSON.stringify({filename: file.name,mimeType: file.type,size: file.size,}),})const data = await response.json()return {uploadUrl: data.uploadUrl,assetId: data.assetId,}},// Called after upload completes (optional)onUploadComplete: async (assetId, file) => {await fetch(`/api/upload/${assetId}/confirm`, { method: 'POST' })return { url: `https://cdn.example.com/${assetId}` }},// Handle errors (optional)onError: (error, file) => {console.error(`Upload failed for ${file.name}:`, error)},}<FileUpload handler={customHandler} />
Styling & Theming
Elements use CSS variables compatible with shadcn/ui. Make sure your project has these variables defined:
/* In your global CSS */:root {--background: 0 0% 100%;--foreground: 222.2 84% 4.9%;--muted: 210 40% 96.1%;--muted-foreground: 215.4 16.3% 46.9%;--primary: 222.2 47.4% 11.2%;--primary-foreground: 210 40% 98%;--destructive: 0 84.2% 60.2%;--destructive-foreground: 210 40% 98%;/* ... other variables */}
Copy Individual Elements
Each element page includes the full source code that you can copy directly into your project. This gives you full control to customize the elements to your needs.