Nuxt
Framework
A module plus a request-scoped runtime plugin for server rendering.
- Package
- @queryweave/nuxt
- Runtime
- Nuxt server and client
- Depends on
- @queryweave/core, @queryweave/vue, @queryweave/vue-router
- Requires
- nuxt
The Nuxt package does two separable things: it configures your application at build time, and it creates one adapter per Vue application instance at runtime. Those live in different entry points because they run at different times.
Install
Section titled “Install”pnpm add @queryweave/core @queryweave/vue @queryweave/nuxtexport default defineNuxtConfig({ modules: ["@queryweave/nuxt"],});Requires Nuxt 4.
Example
Section titled “Example”<script setup lang="ts">import { defineQueryModel, param } from "@queryweave/core";
const products = defineQueryModel({ search: param.text().optional(), page: param.integer({ min: 1 }).default(1),});
// useQueryModel is auto-imported by the module.const filters = useQueryModel(products);const search = filters.field("search", { navigation: "replace" });</script>
<template> <input v-model="search" type="search" /> <p>Page {{ filters.values.page }}</p></template>No adapter is provided by hand. The module registers a plugin that installs one for you, and the Vue binding finds it through injection.
Module options
Section titled “Module options”export default defineNuxtConfig({ modules: ["@queryweave/nuxt"], queryweave: { autoImports: true, // register useQueryModel and provideQueryAdapter — default true enabled: true, // register the runtime plugin at all — default true },});Setting enabled: false disables the module entirely, which is useful when you want to install an
adapter yourself.
Request scoping
Section titled “Request scoping”This is the part that matters for server rendering.
Nuxt creates a fresh Vue application for every server-rendered request. The QueryWeave plugin creates its adapter inside that application’s setup and installs it on that instance:
// packages/nuxt/src/runtime/plugin.ts, in essenceconst adapter = createNuxtQueryAdapter(nuxtApp.$router);installQueryAdapter(nuxtApp.vueApp, adapter);Nothing is stored at module scope. A server handling two requests concurrently therefore has two adapters, each bound to its own router, and neither can observe the other.
SSR and hydration
Section titled “SSR and hydration”The adapter is backed by Vue Router, which Nuxt initializes from the request URL on the server and
from location on the client. Both sides therefore decode the same query with the same model, and
the first client render matches the server’s.
There is no state-transfer payload for query state, and none is needed: the URL is the transfer.
History1 / 1
- SSR initial query
- Vue Router runtime
- hydration-safe state
One adapter per Vue application instance, which on the server means one per request.
Type a query, press Enter.
Typed state
{
"page": 1,
"sort": "created_at",
"status": "all"
}Canonical URL
Valid/productsRuntime exports
Section titled “Runtime exports”For applications that want to wire things themselves:
import { createNuxtQueryAdapter, installQueryAdapter } from "@queryweave/nuxt/runtime";
export default defineNuxtPlugin((nuxtApp) => { const adapter = createNuxtQueryAdapter(nuxtApp.$router as Router); installQueryAdapter(nuxtApp.vueApp, adapter);});installQueryAdapter accepts any QueryAdapter, so an application can substitute its own — a
memory adapter in a test, for example — without leaving the module.
The plugin also exposes the adapter as $queryWeaveAdapter on the Nuxt app, for code that needs it
outside a component.
Edge cases
Section titled “Edge cases”useQueryModeloutside a component cannot use injection. Pass an adapter or a runtime explicitly.- Static generation decodes the query at request time in the browser; a pre-rendered page has no query of its own.
- Disabling auto-imports means importing
useQueryModelfrom@queryweave/vueyourself; the behavior is identical. isolatedDeclarationsis off for this package alone, because the Nuxt module type cannot be expressed without it. This is recorded in ADR 0007.
How it is tested
Section titled “How it is tested”tests/nuxt/module.test.ts and tests/nuxt/registration.test.ts cover module setup and plugin
registration. The stronger check is the nuxt consumer fixture, which installs the packed archive
into a clean project, builds it, server-renders two concurrent requests with different queries,
asserts they do not leak into each other, and then hydrates.