How WPNuxt Works
WPNuxt connects three layers: WordPress stores your content, GraphQL exposes it as structured data, and Nuxt renders it as a fast, modern website. This page explains how the pieces fit together.
The Mental Model
WordPress (CMS) → WPGraphQL (API) → WPNuxt (bridge) → Nuxt (frontend)
- WordPress is your content management system — editors create posts, pages, and menus here
- WPGraphQL is a WordPress plugin that exposes content through a GraphQL API
- WPNuxt is a Nuxt module that generates type-safe composables from GraphQL queries
- Nuxt renders the content as server-rendered (or static) pages with Vue components
Request Flow
When a visitor opens a page on your site, here's what happens:
Browser
→ Nuxt route (e.g. /blog/my-post)
→ composable (e.g. useNodeByUri)
→ GraphQL middleware (Nitro server)
→ Server cache check
→ HIT: return cached response (~1-5ms)
→ MISS: fetch from WordPress GraphQL API (~200-500ms)
→ cache response, return to browser
On the first request, WPNuxt fetches data from WordPress via GraphQL. On subsequent requests, the server cache returns the response instantly. With SWR (stale-while-revalidate) enabled, visitors always get a fast response while fresh data is fetched in the background.
The Three Packages
| Package | What It Does | When You Need It |
|---|---|---|
@wpnuxt/core | GraphQL integration, auto-generated composables, caching | Always — this is the foundation |
@wpnuxt/blocks | Renders Gutenberg blocks as Vue components | When you want per-block control (custom styling, lazy images, interactive blocks) |
@wpnuxt/auth | WordPress authentication (password, OAuth) | When editors need to log in through your Nuxt frontend (e.g. preview mode, gated content) |
Most projects start with @wpnuxt/core alone. Add @wpnuxt/blocks when you need fine-grained control over how WordPress blocks render. Add @wpnuxt/auth when you need authentication.
How Composables Are Generated
WPNuxt's key feature is auto-generated composables. Here's the build-time pipeline that makes this work:
1. GraphQL files (.gql)
├── Default queries (src/runtime/queries/) ← ships with WPNuxt
└── Your custom queries (extend/queries/) ← you create these
2. Query merging
└── Both sets are copied to .queries/ folder
(your files override defaults with the same name)
3. Parsing
└── Each query is parsed to extract name, variables, and return type
4. Code generation
└── For each query "Foo", WPNuxt generates:
├── useFoo() — blocks navigation until data is ready (good for SEO)
└── useAsyncFoo() — loads in the background (good for secondary content)
5. Output
├── .nuxt/wpnuxt/index.mjs — composable implementations
└── .nuxt/wpnuxt/index.d.ts — TypeScript declarations
This is why pnpm nuxt prepare is needed after adding or changing .gql files — it triggers the pipeline that generates your composables and their types.
usePosts() is available in any component without an import statement.Caching Layers
WPNuxt uses three layers of caching, all enabled by default:
Layer 1: Client cache (per browser)
└── Deduplicates identical GraphQL queries during navigation
(e.g. navigating back to a page you already visited)
Layer 2: Server cache (Nitro, shared across all users)
└── Caches GraphQL responses server-side
First request: ~200-500ms (fetches from WordPress)
Cached request: ~1-5ms
Layer 3: Payload cache (per request)
└── Prevents refetch during SSR → client hydration
(the data fetched on the server is reused on the client)
For most sites, the defaults work well. See Caching for how to tune cache duration, disable caching for specific queries, or handle cache invalidation.
Where to Go Next
- Quick Start — Build a blog in 15 minutes
- Fetching Data — Learn about composable options (lazy loading, watching, refreshing)
- Custom Queries — Fetch exactly the data you need
- Configuration — All configuration options