Nuxt Vue Query
Features
- Adds all Tanstack Vue Query composables:
useQuery
, useMutation
, etc.
- Add extra composables
useApiGet
, useApiPost
, useApiPut
and useApiDelete
to easy access to Nuxt APIs.
- Generates and returns Query Keys automatically.
- Type safety for Nuxt API
query
, post
, parameters
and responses
.
- Uses
useFetch()
under the hood to support SSR. (Why not $fetch
? See)
- Clears queries from Nuxt cache immediately, because TanStack Query provides its own cache.
Quick Setup
- Add
nuxt-vue-query
and @tanstack/vue-query
dependency to your project
npm install --save-dev nuxt-vue-query
npm install @tanstack/vue-query
- Add
nuxt-vue-query
to the modules
section of nuxt.config.ts
. Provide vue-query
configuration.
export default defineNuxtConfig({
modules: ['nuxt-vue-query'],
vueQuery: { queryClientConfig: { defaultOptions: { queries: { staleTime: 60000 } } } }
})
Usage
All Tanstack Vue Query features can be used as is:
const { isLoading, isError, data, error } = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList })
const { isLoading, isError, error, isSuccess, mutate } = useMutation({
mutationFn: (newTodo) => axios.post('/todos', newTodo),
})
mutate({ id: new Date(), title: 'Do Laundry' })
Extra Features
Typed Server Routes
Add type to server routes. For example /api/item/[id]/[category]
import type { H3Event } from "h3";
// Export `Query` and `Body` types.
export type Query = { language: string };
export type Body = { status: string };
export default eventHandler(async (event: H3Event) => {
});
Using with Zod
Zod adds runtime data validation in addition to Type Script's type safety.
// Zod is optional, but really useful.
import type { H3Event } from "h3";
import { z, parseQueryAs, parseBodyAs, parseParamsAs } from "@sidebase/nuxt-parse";
const querySchema = z.object({ language: z.string().default("tr") });
const bodySchema = z.object({ status: z.string().default("ok") });
const parametersSchema = z.object({ id: z.preprocess(Number, z.number()), category: z.string() }).required({ id: true, name: true });
// Export `Query`, `Body` and `Parameters` types using Zod.
export type Query = z.infer<typeof querySchema>;
export type Body = z.infer<typeof bodySchema>;
export type Parameters = z.infer<typeof parametersSchema>;
export default eventHandler(async (event: H3Event) => {
const { language } = parseQueryAs(event, querySchema);
const { status } = parseBodyAs(event, bodySchema);
const { id, name } = await parseParamsAs(event, parametersSchema);
});
Using on Components
Query for Nuxt API (get)
const id = ref(123);
const category = ref("new-arrivals")
const query = reactive({ draft: true })
// Pass URL parameters:
const { isLoading, isError, data, error, queryKey } = await useApiGet(["/api/item/:category/:id", category, id], query, options);
// Without URL parameters:
const { isLoading, isError, data, error, queryKey } = await useApiGet("/api/prefs", query, options);
Query for Nuxt API (post, put, delete)
// Pass URL parameters:
const { isLoading, isError, error, isSuccess, mutate, mutateAsync } = await useApiPost("/api/item/:category/:id", options);
const data = await mutateAsync([category, id, { color: "red" }]);
// Without URL parameters:
const { isLoading, isError, error, isSuccess, mutate, mutateAsync } = await useApiPost("/api/prefs", options);
const data = await mutateAsync({ theme: "dark" });
const { isLoading, isError, error, isSuccess, mutate, mutateAsync } = await useApiPut("/api/prefs", options);
const { isLoading, isError, error, isSuccess, mutate, mutateAsync } = await useApiDelete("/api/prefs", options);