Storage

Blob

Store and upload images, videos and other unstructured data in your Nuxt application.

NuxtHub Blob is a layer on top of Cloudflare R2, allowing to store large amounts of unstructured data (images, videos, etc.).

Getting Started

Enable the blob storage in your NuxtHub project by adding the blob property to the hub object in your nuxt.config.ts file.

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

hubBlob()

Server composable that returns a set of methods to manipulate the blob storage.

list()

Returns a paginated list of blobs.

server/api/files.get.ts
export default eventHandler(async () => {
  return hubBlob().list()
})

Params

options
Object

The list options.

limit
Number

The maximum number of blobs to return per request. Defaults to 1000.

prefix
String

Filters the results to only those that begin with the specified prefix.

cursor
String

The cursor to continue from a previous list operation.

Return

Returns an array of BlobObject.

serve()

Returns a blob's data.

server/api/files/[...pathname].get.ts
export default eventHandler(async (event) => {
  const { pathname } = getRouterParams(event)

  return hubBlob().serve(event, pathname)
})

Params

event
H3Event

Handler's event, needed to set headers.

pathname
String

The name of the blob to serve.

Return

Returns the blob's raw data and sets Content-Type and Content-Length headers.

If you are fetching an image with a server route similar to the one above, you might simply want to use it this way:
<img :src="`/api/blob/${file.pathname}`">

Returns a blob's metadata.

const blob = await hubBlob().head(pathname)

Params

pathname
String

The name of the blob to serve.

Return

Returns a BlobObject.

put()

Uploads a blob to the storage.

server/api/files.post.ts
export default eventHandler(async (event) => {
  const form = await readFormData(event)
  const file = form.get('file') as File

  if (!file || !file.size) {
    throw createError({ statusCode: 400, message: 'No file provided' })
  }

  ensureBlob(file, { maxSize: '1MB', types: ['image' ]})

  return hubBlob().put(`images/${file.name}`, file, { addRandomSuffix: false })
})

Params

pathname
String

The name of the blob to serve.

body
String | ReadableStream<any> | ArrayBuffer | ArrayBufferView | Blob

The blob's data.

options
Object

The put options. Any other provided field will be stored in the blob's metadata.

contentType
String

The content type of the blob. If not given, it will be inferred from the Blob or the file extension.

contentLength
String

The content length of the blob.

addRandomSuffix
Boolean

If true, a random suffix will be added to the blob's name. Defaults to false.

Return

Returns a BlobObject.

del()

Delete a blob with its pathname.

server/api/files/[...pathname].delete.ts
export default eventHandler(async (event) => {
  const { pathname } = getRouterParams(event)

  await hubBlob().del(pathname)

  return sendNoContent(event)
})

You can also delete multiple blobs at once by providing an array of pathnames:

await hubBlob().del(['images/1.jpg', 'images/2.jpg'])
You can also use the delete() method as alias of del().

Params

pathname
String

The name of the blob to serve.

Return

Returns nothing.

ensureBlob()

ensureBlob() is a handy util to validate a Blob by checking its size and type:

// Will throw an error if the file is not an image or is larger than 1MB
ensureBlob(file, { maxSize: '1MB', types: ['image' ]})

Params

filerequired
Blob

The file to validate.

optionsrequired
Object

Note that at least maxSize or types should be provided.

maxSize
BlobSize

The maximum size of the file, should be:
(1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024) + (B | KB | MB | GB)
e.g. '512KB', '1MB', '2GB', etc.

types
BlobType[]

Allowed types of the file, e.g. ['image/jpeg'].

Return

Returns nothing.

Throws an error if file doesn't meet the requirements.

Types

BlobObject

interface BlobObject {
  pathname: string
  contentType: string | undefined
  size: number
  uploadedAt: Date
}