CWA 2 is a prerelease (2.0.0-alpha), heading for a beta. It runs production sites; configuration can still change between releases, always with upgrade notes. View versions and support
Utilities

useQueryBoundModel

Binds a reactive ref to a URL query parameter — changes update the URL; URL changes update the ref.

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

ParameterTypeDescription
queryParamstring | string[]A single key, an array of keys (all written together), or a base key whose bracketed variants — order[createdAt] — are matched
opsobject?Options — see below
OptionTypeDescription
defaultValueanyValue used when the parameter is absent from the URL
delaynumberDebounce in ms before the URL is replaced (default: 10)
asNumberbooleanCoerce the query value to a number (used for page)

Return Values

ReturnTypePurpose
modelRef<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>
Assign a new object rather than changing a key. The URL is only updated when the ref itself is reassigned, so 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: [] })