Skip to content

wpnuxt/wpnuxt

Repository files navigation

WPNuxt

npm version npm downloads License Nuxt

A Nuxt module that seamlessly integrates WordPress with Nuxt via GraphQL (WPGraphQL), providing type-safe composables and utilities for fetching WordPress content.

Packages

This monorepo contains the following packages:

Package Description Version
@wpnuxt/core Core WordPress integration with GraphQL npm
@wpnuxt/blocks Gutenberg block rendering components npm
@wpnuxt/auth WordPress authentication (JWT) npm

Features

  • Auto-generated Composables - Generates type-safe composables from your GraphQL queries
  • Reactive Params - Pass ref, computed, or getter functions as query variables with automatic re-fetching
  • Connection Queries - Cursor-based pagination with pageInfo, loadMore() for infinite scroll, and page-based navigation
  • Type Safety - Full TypeScript support with generated types from your WordPress GraphQL schema
  • Type Guards - isPage(), isPost(), isContentType() for narrowing union types from useNodeByUri()
  • ACF Helpers - unwrapScalar() and unwrapConnection() for normalizing ACF field return types
  • Query Merging - Extend or override default queries with your custom GraphQL queries
  • Block Rendering - Render Gutenberg blocks as Vue components with @wpnuxt/blocks
  • Image Optimization - NuxtImg integration for optimized WordPress images
  • Sanitized Content - Integrated DOMPurify for safe HTML content rendering
  • Vercel Ready - Optimized settings for Vercel deployment with ISR support

Quick Setup

Option A: Create a new project

pnpm create wpnuxt@latest

Option B: Add to an existing Nuxt project

Install the package:

pnpm add @wpnuxt/core

Add to your Nuxt config:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@wpnuxt/core'],

  wpNuxt: {
    wordpressUrl: 'https://your-wordpress-site.com'
  }
})

3. Start using composables

<script setup lang="ts">
// Fetch posts
const { data: posts } = await usePosts()

// Fetch a single post by URI
const { data: post } = await usePostByUri({ uri: '/my-post' })

// Custom ordering (defaults: DATE / DESC)
const { data: sorted } = await usePosts({ orderField: 'TITLE', order: 'ASC' })

// Lazy loading (non-blocking) with reactive state
const { data: pages, pending, refresh } = usePages(undefined, { lazy: true })
</script>

<template>
  <article v-for="post in posts" :key="post.id">
    <h2>{{ post.title }}</h2>
    <div v-sanitize-html="post.content" />
  </article>
</template>

Reactive Params

Pass reactive variables to composables — they auto-refetch when values change:

const category = ref<string>()
const params = computed(() => ({
  first: 20,
  where: { categoryName: category.value }
}))

const { data: posts } = usePosts(params)
// Changes to category trigger automatic re-fetch

Connection Queries (Pagination)

Queries with pageInfo automatically get pagination support:

const { data, pageInfo, loadMore } = await useEvents({ first: 10 })
// data.value is EventFragment[]

await loadMore() // Fetches next page, appends to data

Configuration

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@wpnuxt/core'],

  wpNuxt: {
    // Required: Your WordPress site URL (no trailing slash)
    wordpressUrl: 'https://your-wordpress-site.com',

    // Optional settings
    graphqlEndpoint: '/graphql',  // Default: '/graphql'
    downloadSchema: true,          // Default: true
    debug: false,                  // Default: false

    // Query folders
    queries: {
      extendFolder: 'extend/queries/',      // Default
      mergedOutputFolder: '.queries/'       // Default
    },

    // Server-side caching
    cache: {
      enabled: true,   // Default: true
      maxAge: 300,     // Default: 300 (5 minutes)
      swr: true        // Default: true (stale-while-revalidate)
    }
  }
})

Environment Variables

WPNUXT_WORDPRESS_URL=https://your-wordpress-site.com
WPNUXT_GRAPHQL_ENDPOINT=/graphql
WPNUXT_DOWNLOAD_SCHEMA=true
WPNUXT_DEBUG=false

Custom Queries

Create custom queries by adding .gql files to extend/queries/:

# extend/queries/CustomPosts.gql
query CustomPosts($categoryId: Int!) {
  posts(first: 10, where: { categoryId: $categoryId }) {
    nodes {
      ...Post
      customField
    }
  }
}

This generates a useCustomPosts() composable.

Add pageInfo to get pagination support automatically:

# extend/queries/PaginatedEvents.gql
query PaginatedEvents($first: Int = 10, $after: String) {
  events(first: $first, after: $after) {
    pageInfo { hasNextPage endCursor }
    nodes { ...Event }
  }
}

This generates usePaginatedEvents() with data, pageInfo, and loadMore().

Using @wpnuxt/blocks

For rendering WordPress Gutenberg blocks as Vue components:

pnpm add @wpnuxt/blocks
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@wpnuxt/core', '@wpnuxt/blocks'],

  wpNuxtBlocks: {
    imageDomains: ['your-wordpress-site.com']
  }
})
<script setup lang="ts">
const { data: page } = await usePageByUri({ uri: route.path })
</script>

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

Override default block components by creating your own in components/blocks/:

components/
  blocks/
    CoreParagraph.vue    # Override default paragraph rendering
    CoreHeading.vue      # Override default heading rendering
    MyCustomBlock.vue    # Custom block component

Requirements

  • Nuxt 4.0+ (for Nuxt 3, use WPNuxt 1.x)
  • WordPress with WPGraphQL plugin installed
  • Node.js 20+

Development

# Install dependencies
pnpm install

# Prepare all packages
pnpm run dev:prepare

# Run playground (full features)
pnpm run dev

# Run core playground (core only)
pnpm run dev:core

# Run blocks playground
pnpm run dev:blocks

# Run tests
pnpm run test

# Type check
pnpm run typecheck

# Lint
pnpm run lint

Migration from 1.x

See the Migration Guide for detailed instructions on upgrading from WPNuxt 1.x.

Key changes:

  • Nuxt 4.0+ required (was Nuxt 3)
  • Composables renamed: useWPPostsusePosts
  • Single composable pattern: usePosts(undefined, { lazy: true }) for non-blocking
  • Directive changed: v-sanitizev-sanitize-html

License

MIT

About

WPNuxt core module: connect Nuxt with a headless WordPress using GraphQL

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors