The CWA is in heavy development
The CWA is still in alpha and not ready for production - some code and implementations are likely to change. If you would like to try out the CWA, please enjoy what we have provided and feel free to provide feedback, or get involved on GitHub.
DraftUtilities

useQueryBoundModel

Binds a reactive ref to a URL query parameter — changes update the URL; URL changes update the ref.
import { useQueryBoundModel } from '#imports'

const { model: sortOrder } = useQueryBoundModel('order', { defaultValue: 'desc' })

useQueryBoundModel 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.

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.

Pass the base key instead ('order') and the model value becomes an object of the bracketed variants — { createdAt: 'asc' } writes ?order[createdAt]=asc. That's how the admin's list filter binds a single select to whichever sort field is chosen.

Array Values

Give an array defaultValue to support multi-value parameters:

const { model: selectedTags } = useQueryBoundModel('tags[]', { defaultValue: [] })