Backend
Queries
Read data from your Convex database with reactive queries.
Queries read data from your database. They are reactive — the UI updates automatically when underlying data changes.
Queries are read-only and cannot modify data. Use mutations to write data.
Basic Query
Create a query in your convex/ directory:
convex/tasks.ts
import { v } from 'convex/values'
import { query } from './_generated/server'
export const list = query({
args: { userId: v.string() },
handler: async (ctx, { userId }) => {
return await ctx.db
.query('tasks')
.withIndex('by_user', q => q.eq('userId', userId))
.order('desc')
.collect()
},
})
The query function defines a server-side function that:
- Accepts typed arguments
- Accesses the database through
ctx.db - Returns data to the client
Fetching a Single Document
Use ctx.db.get() to fetch a document by ID:
convex/tasks.ts
export const get = query({
args: { id: v.id('tasks') },
handler: async (ctx, { id }) => {
return await ctx.db.get(id)
},
})
Query Methods
The database query builder provides several methods:
| Method | Description |
|---|---|
.query('table') | Start a query on a table |
.withIndex() | Filter using an index |
.filter() | Filter with a predicate |
.order('asc'/'desc') | Sort results |
.collect() | Return all matching documents |
.first() | Return first matching document |
.take(n) | Return first n documents |
Using in Components
Call queries from Vue components with useConvexQuery:
app/pages/tasks.vue
<script setup lang="ts">
import { api } from '#convex/api'
const { data: tasks, isLoading } = useConvexQuery(api.tasks.list, { userId: 'user_123' })
</script>
<template>
<ul v-if="!isLoading">
<li v-for="task in tasks" :key="task._id">
{{ task.title }}
</li>
</ul>
</template>
See useConvexQuery for full documentation.