Vue Guide
File Storage
Configure the Vue storage plugin, upload files, and read file URLs reactively.
Use this guide when you want storage helpers in a standalone Vue app.
Before you begin
Make sure:
- the base
convexVueplugin is already installed - you already have generated Convex types
- your Convex backend exposes storage functions you can pass to the storage plugin
Create the backend functions
convex/storage.ts
import { v } from 'convex/values'
import { mutation, query } from './_generated/server'
export const generateUploadUrl = mutation(async (ctx) => {
return await ctx.storage.generateUploadUrl()
})
export const getUrl = query({
args: { storageId: v.id('_storage') },
handler: async (ctx, { storageId }) => {
return await ctx.storage.getUrl(storageId)
},
})
export const remove = mutation({
args: { storageId: v.id('_storage') },
handler: async (ctx, { storageId }) => {
await ctx.storage.delete(storageId)
},
})
Register the storage plugin
src/main.ts
import { convexVue } from 'vue-convex'
import { convexVueStorage } from 'vue-convex/storage'
import { createApp } from 'vue'
import { api } from '../convex/_generated/api'
import App from './App.vue'
const app = createApp(App)
app.use(convexVue, {
url: import.meta.env.VITE_CONVEX_URL,
})
app.use(convexVueStorage, {
generateUploadUrl: api.storage.generateUploadUrl,
getUrl: api.storage.getUrl,
remove: api.storage.remove,
})
app.mount('#app')
Upload a file
src/components/FileUpload.vue
<script setup lang="ts">
import { useConvexUpload } from 'vue-convex/storage'
const { upload, isUploading, progress, error } = useConvexUpload({
onSuccess(storageId, file) {
console.log(`Uploaded ${file.name} as ${storageId}`)
},
})
async function onSelect(event: Event) {
const file = (event.target as HTMLInputElement).files?.[0]
if (file)
await upload(file)
}
</script>
Read the file URL
src/components/AvatarUpload.vue
<script setup lang="ts">
import { useConvexStorage, useConvexUpload } from 'vue-convex/storage'
const storage = useConvexStorage()
const storageId = ref<string | null>(null)
const url = computed(() => storageId.value ? storage.getUrl(storageId.value) : null)
const { upload } = useConvexUpload({
onSuccess(id) {
storageId.value = id
},
})
</script>
useConvexStorage().getUrl(storageId) returns a reactive ref that updates when the underlying file URL changes.
Verify the result
The setup is working when:
- the storage plugin installs without errors
upload(file)returns astorageIdgetUrl(storageId)resolves to a public URL
Uploads are client-only. Calling upload() during SSR returns null and sets an error.
Next steps
- Read Controller if the storage setup depends on delayed connection
- Read
useConvexStorageanduseConvexUploadfor the exact API surface