Fetching Data
Without WPNuxt, fetching WordPress content means writing GraphQL queries, managing loading states, handling SSR hydration, and defining TypeScript types — all manually. WPNuxt composables handle all of this for you: one function call returns typed data with built-in caching, SSR support, and error handling.
Each composable supports both blocking and non-blocking modes via the lazy option. To understand how composables are generated from .gql files at build time, see How WPNuxt Works.
Basic Usage
<script setup lang="ts">
const { data: posts, pending, error } = await usePosts()
</script>
<template>
<div v-if="pending">Loading...</div>
<div v-else-if="error">{{ error.message }}</div>
<article v-for="post in posts" :key="post.id">
<h2>{{ post.title }}</h2>
</article>
</template>
With Parameters
// By URI
const { data: post } = await usePostByUri({ uri: '/my-post' })
// By ID
const { data: page } = await usePageById({ id: '123' })
// With variables
const { data: posts } = await usePostsByCategoryName({
categoryName: 'news'
})
Reactive Params
Pass a ref, computed, or getter function as variables to auto-refetch when the value changes:
<script setup lang="ts">
const category = ref<string>()
const params = computed(() => ({
categoryName: category.value
}))
const { data: posts, pending } = usePostsByCategoryName(params)
</script>
<template>
<select v-model="category">
<option :value="undefined">All</option>
<option value="news">News</option>
<option value="tutorials">Tutorials</option>
</select>
<div v-if="pending">Loading...</div>
<article v-for="post in posts" :key="post.id">
<h2>{{ post.title }}</h2>
</article>
</template>
No watch option needed — the composable detects the reactive source and refetches automatically. Undefined values are simply not sent in the GraphQL request, so unset filters don't affect the query.
Lazy Loading
Use the lazy: true option for non-critical content. This allows navigation to happen immediately while data loads in the background:
<script setup lang="ts">
// Navigation happens immediately, data loads in background
const { data: posts, pending } = usePosts({}, { lazy: true })
</script>
<template>
<div v-if="pending">Loading posts...</div>
<PostList v-else :posts="posts" />
</template>
Options
const { data } = usePosts(variables, {
lazy: true, // Non-blocking navigation, show loading state
server: false, // Skip SSR, fetch on client only
immediate: false, // Don't fetch until execute() is called
watch: [slug], // Refetch when slug changes
})
Choosing the Right Options
| Scenario | Options | Why |
|---|---|---|
| Page content (blog post, page) | default (no options) | Blocks navigation, best for SEO |
| Sidebar / secondary content | lazy: true | Loads in background, doesn't block navigation |
| Client-only interactive widget | server: false | Skips SSR, saves server resources |
| Form-triggered fetch | immediate: false | Fetches only when execute() is called |
| Content that depends on route | watch: [() => route.path] | Auto-refetches on navigation |
| Filtered listing with reactive UI | computed(() => ({ where: ... })) as params | Auto-refetches when filters change |
Refreshing Data
const { data, refresh } = usePosts()
// Manually refetch
await refresh()
Available Composables
| Composable | Description |
|---|---|
usePosts() | All posts (default limit: 10) |
usePostByUri({ uri }) | Single post by URI |
usePostById({ id }) | Single post by ID |
usePostsByCategoryName({ categoryName }) | Posts in category by name |
usePostsByCategoryId({ categoryId }) | Posts in category by ID |
usePages() | All pages (default limit: 10) |
usePageByUri({ uri }) | Single page by URI |
usePageById({ id }) | Single page by ID |
useNodeByUri({ uri }) | Any content type by URI |
useMenu({ name }) | Navigation menu by name |
useGeneralSettings() | Site title, description, URL, and language |
useViewer() | Current authenticated user (requires @wpnuxt/auth) |
useRevisions() | Post revisions |
All composables support the { lazy: true } option for non-blocking navigation.
Related Pages
- Quick Start Tutorial — Build a blog from scratch using these composables
- Custom Queries — Create your own composables for custom data
- Pagination — Cursor-based pagination with loadMore and page navigation
- Caching — Control how responses are cached
- How WPNuxt Works — Understand the composable generation pipeline