Skip to main content

Storage URLs

Resolve a Convex storage ID to a reactive URL for display or download.

Store Convex storage IDs in product data. Resolve a URL when the UI needs it.

Backend query

convex/files.ts
import { query } from './_generated/server'
import { v } from 'convex/values'

export const getUrl = query({
  args: { storageId: v.string() },
  handler: async (ctx, args) => {
    return await ctx.storage.getUrl(args.storageId)
  },
})

Add identity and document-ownership checks before returning URLs for private files.

Reactive URL

ts
const storageId = ref<string | null>(null)
const imageUrl = useConvexStorageUrl(api.files.getUrl, storageId, {
  auth: 'required',
})

The query skips while the storage ID is null or undefined and runs again when it changes.

The auth default for this helper is none for compatibility. Pass required for the common private-file pattern.

Display after upload

ts
const uploadState = useConvexFileUpload(api.files.generateUploadUrl)
const imageUrl = useConvexStorageUrl(api.files.getUrl, uploadState.data, {
  auth: 'required',
})
vue
<img v-if="imageUrl" :src="imageUrl" alt="Uploaded preview" />

URL lifetime

Treat the resolved URL as presentation data. Store the storage ID as the durable reference and resolve again when needed. A deleted or unauthorized object can return null.