Getting Started

How WPNuxt Works

Understand the architecture behind WPNuxt

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

Why This Architecture?

Each layer in the stack exists for a specific reason:

Why GraphQL over REST? WordPress has a built-in REST API, but it returns fixed data shapes — every post response includes all fields whether you need them or not. GraphQL lets WPNuxt request exactly the fields each page needs, resulting in smaller payloads and fewer round trips. You have full control over which data to fetch by writing your own queries or extending the defaults. More importantly, the GraphQL schema is machine-readable, which enables WPNuxt to generate TypeScript types automatically.

Why build-time code generation? WPNuxt generates composables and their TypeScript types at build time (during nuxt prepare), not at runtime. This means your editor knows the exact shape of usePosts() return data while you're writing code — you get autocomplete, type checking, and compile-time error detection. The trade-off is that you need to run pnpm nuxt prepare after changing .gql files to regenerate types.

Why server-side caching by default? WordPress typically responds in 200-500ms per GraphQL query. For a page that makes multiple queries, this adds up quickly. Server-side caching with SWR (stale-while-revalidate) means visitors always get a near-instant response (~1-5ms) from the cache, while fresh data is fetched in the background. The trade-off is that content may be up to maxAge seconds stale (5 minutes by default). See Data Freshness Trade-offs for how to tune this balance.

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

PackageWhat It DoesWhen You Need It
@wpnuxt/coreGraphQL integration, auto-generated composables, cachingAlways — this is the foundation
@wpnuxt/blocksRenders Gutenberg blocks as Vue componentsWhen you want per-block control (custom styling, lazy images, interactive blocks)
@wpnuxt/authWordPress 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.

You never import composables manually. Nuxt auto-imports them, so 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

Copyright © 2026