I wanted to learn the full surface area of Next.js 16 while it was still in canary. Vercel Blob was the vehicle. I tried to integrate every optimization I could at the time: React 19 hooks, multi-tier CDN caching, image optimization, the full @vercel/blob SDK, dynamic OG/sitemap/robots, WCAG accessibility. This is what I ended up with.
Next.js 16 + React 19 starter exercising every client-side Vercel Blob SDK feature.
- Next.js 16 (App Router)
- React 19 (
useOptimistic,useReducer,useId,startTransition) - TypeScript strict
- Tailwind CSS v4
- shadcn/ui
@vercel/blobv2
git clone https://github.com/ramonclaudio/vercel-blob-client-starter.git my-blob-app
cd my-blob-app
pnpm install
cp .env.example .env.localIn .env.local:
BLOB_READ_WRITE_TOKEN=your_blob_token_hereGet a token from the Vercel Storage Dashboard. Then:
pnpm devFor onUploadCompleted to fire during local dev, you need a public URL. Expose localhost with ngrok:
npm install -g ngrok
ngrok http 3000Add the ngrok URL to .env.local:
VERCEL_BLOB_CALLBACK_URL=https://your-ngrok-id.ngrok-free.appRestart the dev server. In production on Vercel the callback URL is auto-configured.
GOOGLE_SITE_VERIFICATION=your_code
BING_SITE_VERIFICATION=your_code
YANDEX_VERIFICATION=your_codeGet codes from Google Search Console, Bing Webmaster, Yandex Webmaster.
Upload: upload() with onUploadProgress, AbortSignal for cancellation, automatic multipart for large files, bulk support with per-file error handling.
Config: folder pathnames, cache-control max-age, random suffix, overwrite permissions, custom metadata, content-type overrides.
Management: copy(), head(), list() with pagination, del(), BlobAccessError handling.
Caching: multi-tier CDN cache-control, geo-adaptive 2x cache for optimal regions, stale-while-revalidate, 1-year static asset cache.
Images: Next.js Image with WebP output, 4 responsive breakpoints, fixed quality 75, 31-day TTL, skip optimization below 10KB.
SEO: dynamic opengraph-image.tsx and twitter-image.tsx, dynamic robots.txt and sitemap.xml via App Router route handlers.
Accessibility: WCAG 2.1, skip links, semantic HTML, 44px touch targets, prefers-reduced-motion, navigation-blocker to prevent data loss during uploads.
Errors: global and per-page error boundaries, retry with exponential backoff, custom 404.
'use cache' wiring is in place but commented out for stable Next.js. To enable:
pnpm add next@canary- In
next.config.ts:experimental: { useCache: true, cacheComponents: true } - Uncomment cache directives in
app/layout.tsx,lib/cached-utils.ts,lib/cache-config.ts,lib/cache-tags.ts,lib/cache-invalidation.ts - Restart dev server
MIT