useQueryBoundModel
useQueryBoundModel binds a ref to a URL query parameter, for sorting, filtering and searching a collection.
import { useQueryBoundModel } from '#imports'
const { model: sortOrder } = useQueryBoundModel('order[createdAt]', { defaultValue: 'desc' })
It returns { model } — a writable ref that stays in sync with a URL query parameter. When you write to model, the URL updates (triggering a collection re-fetch). When the user navigates with a query string (e.g. a shared link), model reads from the URL.
Signature
useQueryBoundModel(queryParam: string | string[], ops?: { defaultValue?: any, delay?: number, asNumber?: boolean })
Parameters
| Parameter | Type | Description |
|---|---|---|
queryParam | string | string[] | A single key, an array of keys (all written together), or a base key whose bracketed variants — order[createdAt] — are matched |
ops | object? | Options — see below |
| Option | Type | Description |
|---|---|---|
defaultValue | any | Value used when the parameter is absent from the URL |
delay | number | Debounce in ms before the URL is replaced (default: 10) |
asNumber | boolean | Coerce the query value to a number (used for page) |
Return Values
| Return | Type | Purpose |
|---|---|---|
model | Ref<any> | Writable, two-way bound to the URL |
Usage with Collections
Use it to let visitors control sorting and filtering on collection components:
import { useCwaComponent, withCollection, useQueryBoundModel } from '#imports'
const { collectionItems, totalPages, pageModel } = useCwaComponent(props, [withCollection()])
// Bind sort order to URL
const { model: sortOrder } = useQueryBoundModel('order[createdAt]', { defaultValue: 'desc' }) <select v-model="sortOrder">
<option value="desc">Newest first</option>
<option value="asc">Oldest first</option>
</select>
Changing sortOrder updates the URL to ?order[createdAt]=asc, which triggers the collection component's resource to re-fetch with the new parameter. The default query parameters set on the PHP Collection entity are the baseline; useQueryBoundModel lets visitors override them.
Choosing the Sort Field Too
Pass the base key, 'order', and the model value becomes an object of the bracketed parameters: { createdAt: 'asc' } writes ?order[createdAt]=asc. Writing a new object removes the order[…] parameters it no longer contains, so one select can switch between sort fields. That's how the admin's list filter works.
const { model: sortOrder } = useQueryBoundModel('order', { defaultValue: { createdAt: 'desc' } })
<select
:value="sortOrder.createdAt"
@change="sortOrder = { createdAt: ($event.target as HTMLSelectElement).value }"
>
<option value="desc">Newest first</option>
<option value="asc">Oldest first</option>
</select>
sortOrder.value.createdAt = 'asc' does nothing.Use the bracketed key, as in the example above, when the field is fixed. Don't pass the base key with a plain string default: useQueryBoundModel('order', { defaultValue: 'desc' }) writes ?order=desc, which doesn't sort by any field.
Array Values
Give an array defaultValue to support multi-value parameters:
const { model: selectedTags } = useQueryBoundModel('tags[]', { defaultValue: [] })