Nuxt Blob Storage

Setup Blob Storage in your Nuxt application to store assets like images, videos, documents. Compatible with AWS S3, Cloudflare R2, Vercel Blob and more.

Getting Started

Enable blob storage

Enable blob storage in your project by setting blob: true in the NuxtHub config.

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    blob: true
  }
})

Set a driver

NuxtHub automatically configures the blob storage driver based on your environment variables or hosting provider.

By default, if NuxtHub cannot detect a driver, files are stored locally in the .data/blob directory.

To set the storage directory, you can set the dir option.

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    blob: {
      driver: 'fs',
      dir: '.data/my-blob-directory' // Defaults to `.data/blob`
    }
  }
})
The local filesystem driver is not suitable for production environments.

Upload a file

To upload a file, you can use the blob.put() method.

import { blob } from 'hub:blob'

const file = await blob.put('avatars/user-1.png', imageData)
Learn how to upload files with validation and progress tracking.

Driver options

You can set a custom driver by providing a configuration object to blob.

nuxt.config.ts
export default defineNuxtConfig({
  hub: {
    blob: {
      driver: 'fs',
      dir: '.data/blob'
    }
  },
  // or overwrite only in production
  $production: {
    hub: {
      blob: {
        driver: 'vercel-blob'
      }
    }
  }
})

Available drivers:

export default defineNuxtConfig({
  hub: {
    blob: {
      driver: 'fs',
      dir: '.data/files' // defaults to '.data/blob'
    }
  }
})

Nuxt Image Integration

@nuxt/image provides automatic image optimization. You can combine it with blob storage to serve optimized images from your storage.

Install @nuxt/image

Terminal
npx nuxt module add image
This command will install @nuxt/image and add it to your modules section of your nuxt.config.ts.

Expose your blobs on a route

Create a server route (for example /images/**) that serves blobs using blob.serve():

This route should exist in both development and production. In production, providers like Cloudflare and Vercel optimize by generating URLs that wrap this route.

server/routes/images/[...pathname].get.ts
import { blob } from 'hub:blob'
import { createError, eventHandler, getRouterParam } from 'h3'

export default eventHandler(async (event) => {
  const pathname = getRouterParam(event, 'pathname')
  if (!pathname) {
    throw createError({ statusCode: 404, statusMessage: 'Not Found' })
  }

  return blob.serve(event, pathname)
})
Learn more about serving blobs (headers, CSP, etc.) in the Serve a blob section.

Configure the image provider

Configure @nuxt/image to use the appropriate provider for your hosting platform:

nuxt.config.ts
export default defineNuxtConfig({
  image: { provider: 'none' },
  $production: {
    image: {
      provider: 'cloudflare'
    }
  }
})
See Cloudflare provider docs for requirements and options.
Cloudflare and Vercel providers generate URLs that only exist in production (/cdn-cgi/image/ for Cloudflare, /_vercel/image for Vercel), so enable them only in $production.In development, @nuxt/image defaults to the ipx provider if you don't configure it. IPX generates /_ipx/... URLs and tries to read the source from the filesystem, so it won't work with blob routes like /images/** (you may see IPX_FILE_NOT_FOUND errors). Use provider: 'none' in development to keep src="/images/..." working.

Use NuxtImg or NuxtPicture

Use the components to display optimized images from blob storage:

pages/gallery.vue
<template>
  <NuxtImg src="/images/photo.jpg" width="300" quality="80" />
</template>

The src path combines your route prefix (/images) with the blob pathname (photo.jpg).