---
title: "What's New in v2"
description: "Everything new in WPNuxt v2 — a complete rewrite for modern Nuxt"
canonical_url: "https://wpnuxt.com/getting-started/whats-new"
---
# What's New in v2

> Everything new in WPNuxt v2 — a complete rewrite for modern Nuxt

WPNuxt v2 is a complete rewrite built for Nuxt 4. The API is simpler, the architecture is faster, and three packages now ship from a single monorepo. This page covers all major changes.

<callout type="info">

**Migrating from v1?** See the [Migration Guide](https://wpnuxt.com/migration/v1-to-v2) for a step-by-step checklist.

</callout>

## Nuxt 4 Foundation

WPNuxt v2 requires Nuxt 4.1+ and Node.js 20+. The codebase uses the Nuxt 4 directory structure (`app/` for client code, `server/` for server code) and benefits from Nuxt 4's improved performance and module system.

<table>
<thead>
  <tr>
    <th>
      Dependency
    </th>
    
    <th>
      v1
    </th>
    
    <th>
      v2
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Nuxt
    </td>
    
    <td>
      3.x
    </td>
    
    <td>
      <strong>
        4.1+
      </strong>
    </td>
  </tr>
  
  <tr>
    <td>
      Node.js
    </td>
    
    <td>
      18+
    </td>
    
    <td>
      <strong>
        20+
      </strong>
    </td>
  </tr>
  
  <tr>
    <td>
      nuxt-graphql-middleware
    </td>
    
    <td>
      4.x
    </td>
    
    <td>
      <strong>
        5.x
      </strong>
    </td>
  </tr>
</tbody>
</table>

## Simplified Composable API

Composable names are shorter and more intuitive. The configurable `composablesPrefix` is gone — every composable uses the `use` prefix.

```diff
- const { data } = await useWPPosts()
+ const { data } = await usePosts()

- const { data } = await useWPPageByUri({ uri })
+ const { data } = await usePageByUri({ uri })
```

The separate `useAsync*` composables are replaced by a `lazy` option:

```diff
- const { data } = useAsyncWPPosts()
+ const { data } = usePosts(undefined, { lazy: true })
```

### Retry and Timeout

Composables now support automatic retry with exponential backoff and request timeouts:

```ts
const { data, retryCount, isRetrying } = await usePosts(undefined, {
  retry: 3,
  retryDelay: 1000,
  timeout: 5000
})
```

## Multi-Layer Caching

WPNuxt v2 introduces a structured caching system with three layers that work together automatically.

<table>
<thead>
  <tr>
    <th>
      Layer
    </th>
    
    <th>
      Scope
    </th>
    
    <th>
      Purpose
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Server (Nitro)
    </td>
    
    <td>
      All users
    </td>
    
    <td>
      Cache GraphQL responses server-side with SWR
    </td>
  </tr>
  
  <tr>
    <td>
      Client (GraphQL)
    </td>
    
    <td>
      Per browser
    </td>
    
    <td>
      Deduplicate identical queries during navigation
    </td>
  </tr>
  
  <tr>
    <td>
      Payload
    </td>
    
    <td>
      Per request
    </td>
    
    <td>
      Prevent refetch during SSR-to-client hydration
    </td>
  </tr>
</tbody>
</table>

Server caching is enabled by default. Configure it in `nuxt.config.ts`:

```ts [nuxt.config.ts]
wpNuxt: {
  cache: {
    enabled: true,
    maxAge: 300,
    swr: true
  }
}
```

Per-query control gives you fine-grained options for real-time or authenticated content:

```ts
const { data } = usePosts(undefined, { clientCache: false })
```

See [Caching](https://wpnuxt.com/guide/caching) for the full guide.

## WPContent Component

The new `<WPContent>` component is the recommended way to render WordPress content. It automatically chooses the best rendering strategy and intercepts internal links for client-side navigation.

```vue [app/pages/[...slug].vue]
<script setup lang="ts">
const route = useRoute()
const { data: page } = await usePageByUri({ uri: route.path })
</script>

<template>
  <WPContent v-if="page" :node="page" />
</template>
```

When `@wpnuxt/blocks` is installed, `<WPContent>` renders structured `editorBlocks` via `BlockRenderer`. Without it, the component falls back to `v-sanitize-html` for safe HTML rendering. Internal WordPress links are intercepted and handled via `navigateTo()` for instant client-side navigation.

## Serverless-Compatible Sanitization

The `v-sanitize-html` directive is rebuilt from the ground up. The previous implementation depended on `@radya/nuxt-dompurify`, which pulled in jsdom (~5.7 MB) and broke SSR on serverless platforms like Vercel.

The new built-in plugin:

- **Server:** passes HTML through as-is (trusted WordPress source)
- **Client:** lazy-loads DOMPurify with the native browser `window`

The directive API stays the same — no changes needed in your templates.

## Gutenberg Block Rendering

The `@wpnuxt/blocks` package is rewritten with 10 built-in block components, automatic `@nuxt/image` integration, and optional Nuxt UI support.

<table>
<thead>
  <tr>
    <th>
      Component
    </th>
    
    <th>
      Block Type
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        CoreParagraph
      </code>
    </td>
    
    <td>
      <code>
        core/paragraph
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreHeading
      </code>
    </td>
    
    <td>
      <code>
        core/heading
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreImage
      </code>
    </td>
    
    <td>
      <code>
        core/image
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreButton
      </code>
    </td>
    
    <td>
      <code>
        core/button
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreButtons
      </code>
    </td>
    
    <td>
      <code>
        core/buttons
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreQuote
      </code>
    </td>
    
    <td>
      <code>
        core/quote
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreGallery
      </code>
    </td>
    
    <td>
      <code>
        core/gallery
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreSpacer
      </code>
    </td>
    
    <td>
      <code>
        core/spacer
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        CoreDetails
      </code>
    </td>
    
    <td>
      <code>
        core/details
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        EditorBlock
      </code>
    </td>
    
    <td>
      Fallback for unsupported blocks
    </td>
  </tr>
</tbody>
</table>

Override any block component by creating your own in `components/blocks/`. The module auto-detects `@nuxt/ui` and uses UI components (like `UButton` for `CoreButton`) when available.

See [Rendering Blocks](https://wpnuxt.com/guide/rendering-blocks) for custom component examples.

## Authentication Module

The `@wpnuxt/auth` package provides three authentication methods, all using secure httpOnly cookies for token storage.

<table>
<thead>
  <tr>
    <th>
      Method
    </th>
    
    <th>
      Flow
    </th>
    
    <th>
      WordPress Plugin
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Password
    </td>
    
    <td>
      Username/password via GraphQL
    </td>
    
    <td>
      Headless Login for WPGraphQL
    </td>
  </tr>
  
  <tr>
    <td>
      External OAuth
    </td>
    
    <td>
      Google, GitHub, etc.
    </td>
    
    <td>
      Headless Login for WPGraphQL
    </td>
  </tr>
  
  <tr>
    <td>
      WordPress OAuth
    </td>
    
    <td>
      Redirect to WordPress login
    </td>
    
    <td>
      miniOrange WP OAuth Server
    </td>
  </tr>
</tbody>
</table>

The `useWPAuth()` composable provides a unified API across all three methods:

```ts
const { user, isAuthenticated, login, logout, refresh } = useWPAuth()
```

Authentication works seamlessly with SSR — cookies are included in server-side requests, so protected pages render correctly on the first load.

See [Authentication](https://wpnuxt.com/auth) for setup guides per provider.

## Vercel Auto-Configuration

WPNuxt auto-detects Vercel deployments and applies the right configuration:

- Native SWR for proper ISR handling
- SSR forced for all routes (fixes catch-all route issues)
- WordPress uploads proxy (`/wp-content/uploads/**` forwarded to WordPress)
- `@nuxt/image` IPX configuration with WordPress domain alias

No manual Vercel configuration is needed.

See [Deploy to Vercel](https://wpnuxt.com/deploy/vercel) for details.

## Authenticated Schema Introspection

Some WordPress sites disable public GraphQL introspection. The new `schemaAuthToken` option lets WPNuxt download the schema with a Bearer token during builds, without exposing the token in client bundles.

```ts [nuxt.config.ts]
wpNuxt: {
  schemaAuthToken: process.env.WPNUXT_SCHEMA_AUTH_TOKEN
}
```

## AI-Powered Development

WPNuxt ships with a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that enables AI assistants to interact with your WordPress site and generate WPNuxt code.

Add a single line to `.mcp.json` and your AI assistant can:

- Connect to your WordPress site and explore content types, menus, taxonomies, and blocks
- Generate pages, components, and custom GraphQL queries
- Help migrate from v1 to v2

```json [.mcp.json]
{
  "mcpServers": {
    "wpnuxt": {
      "type": "sse",
      "url": "https://wpnuxt.com/mcp"
    }
  }
}
```

The MCP server also proxies Nuxt and Nuxt UI documentation, so you only need one MCP server configured.

See [AI Tooling](https://wpnuxt.com/ai) for the full tool reference.

## Interactive Setup

Running `nuxt prepare` for the first time triggers an interactive setup that:

- Prompts for your WordPress URL
- Creates `.env` and `.env.example` files
- Sets up `.mcp.json` for AI assistant integration
- Adds `.queries/` to `.gitignore`
- Creates the `extend/queries/` folder with a README

## Unified Monorepo

All three packages (`@wpnuxt/core`, `@wpnuxt/blocks`, `@wpnuxt/auth`) now live in a single repository. Versions are synchronized, and the packages are designed to work together seamlessly.

<table>
<thead>
  <tr>
    <th>
      Package
    </th>
    
    <th>
      Purpose
    </th>
    
    <th>
      Required
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        @wpnuxt/core
      </code>
    </td>
    
    <td>
      GraphQL integration, composables, caching
    </td>
    
    <td>
      Always
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @wpnuxt/blocks
      </code>
    </td>
    
    <td>
      Gutenberg block rendering
    </td>
    
    <td>
      When you need per-block control
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @wpnuxt/auth
      </code>
    </td>
    
    <td>
      WordPress authentication
    </td>
    
    <td>
      When you need login/logout
    </td>
  </tr>
</tbody>
</table>

## Developer Experience

Several improvements make day-to-day development smoother:

- **Query complexity warnings** — build-time analysis warns about expensive queries (deep extraction paths or many fragments)
- **Build hash cache busting** — every deployment gets a unique hash to ensure cache invalidation
- **DevTools integration** — a WPNuxt-branded tab in Nuxt DevTools for inspecting GraphQL queries
- **Trailing slash handler** — automatic redirect from `/path` to `/path/` to match WordPress URI format
- **GraphQL error logging** — centralized error handler in development for easier debugging
- **Query override warnings** — notified when your custom queries override built-in ones

## What's Next

Planned improvements for upcoming releases:

- End-to-end tutorials for common workflows (blog, SEO, menus)
- Media and image handling deep dive
- Troubleshooting guide with common errors and fixes
- Authentication workflow examples (SSR login states, session persistence)
- WordPress 7.0 AI Client integration via GraphQL

Follow progress on [GitHub](https://github.com/wpnuxt/wpnuxt) and check the [changelog](https://github.com/wpnuxt/wpnuxt/releases) for the latest updates.


## Sitemap

See the full [sitemap](https://wpnuxt.com/sitemap.md) for all pages.
