@lars-plate/delta-client-nuxt

6,261
Install
npm install @lars-plate/delta-client-nuxt
Latest Version:1.1.15
Vue:3
Last Updated:Oct 1, 2026
Links: npm
Maintainer: lars-plate

@lars-plate/delta-client-nuxt

npm version npm downloads License Nuxt

Nuxt module that wires Plate CMS Delta into your Nuxt app: runtime configuration, Vue plugin setup, building-block auto-registration, and optional editor, preview, and component-dev routes.

Built on @lars-plate/delta-client and @lars-plate/delta-client-vue.

Features

  • Registers the Delta Vue plugin with TanStack Vue Query
  • Exposes environment, token, and version via Nuxt runtimeConfig.public.delta and Vue DELTA_CONFIG
  • Auto-imports Delta composables and registers Delta Vue components globally
  • Glob-registers Vue building blocks from app/blocks
  • Loads building-block JSON schemas from delta/building-blocks/ (blockLoader + #delta-building-blocks)
  • Catch-all route for live content; optional CMS editor, preview, and component showcase routes
  • Renders GraphQL trees for CDA v0 and accessible trees for CDA v1

Requirements

  • Nuxt ^3.10.0 or ^4.0.0
  • Vue ^3.5.13
  • Node 18+
  • A Plate CMS project with Delta CLI output (delta/, app/blocks/, delta-types.d.ts)

Installation

Install the module and its peer dependencies:

pnpm add @lars-plate/delta-client-nuxt @lars-plate/delta-client @lars-plate/delta-client-vue
npm install @lars-plate/delta-client-nuxt @lars-plate/delta-client @lars-plate/delta-client-vue
yarn add @lars-plate/delta-client-nuxt @lars-plate/delta-client @lars-plate/delta-client-vue

Or with the Nuxt module helper:

npx nuxt module add @lars-plate/delta-client-nuxt

Then add the module to nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@lars-plate/delta-client-nuxt'],

  delta: {
    environment: process.env.DELTA_ENVIRONMENT ?? 'dev',
    token: process.env.DELTA_TOKEN,
    version: process.env.DELTA_VERSION ?? 'v0',
  },
})

Configuration

The module is configured under the delta key in nuxt.config.ts (configKey: 'delta').

Option Type Default Description
environment string 'dev' Delta stack: acc, dev, local, or prod
token string undefined Bearer token for CDA fetches (prefer env vars)
version string 'v0' CDA URL version (v0 or v1)
editor boolean false Enable /editor/* CMS iframe routes
preview boolean false Enable /preview/* CMS preview iframe route
components boolean false Enable /components local block showcase

Full example

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@lars-plate/delta-client-nuxt'],

  delta: {
    environment: process.env.DELTA_ENVIRONMENT,
    token: process.env.DELTA_TOKEN,
    version: process.env.DELTA_VERSION ?? 'v0',

    // Development helpers (disable in production unless needed)
    editor: true,
    preview: true,
    components: true,
  },
})

Environment variables

# .env
DELTA_ENVIRONMENT=dev
DELTA_TOKEN=your-api-token
DELTA_VERSION=v0

Values are merged into useRuntimeConfig().public.delta. The runtime plugin also provides them as DELTA_CONFIG for Vue composables.

Project layout

After running the Delta CLI in your Nuxt app, you typically have:

my-nuxt-app/
├── app/
│   └── blocks/                    # Vue building-block components
│       ├── RootBuildingBlock.vue
│       ├── HeroBuildingBlock.vue
│       └── index.ts               # Generated slug → component map
├── delta/
│   ├── building-blocks/           # JSON schemas (synced from CMS)
│   │   └── root.json
│   └── content-types/             # Content type definitions
│       └── page.json
├── delta.config.ts                # Delta CLI config (theme, paths, token)
├── delta-types.d.ts               # Generated TypeScript for Content.* types
└── nuxt.config.ts

If app/blocks is missing, the module logs a warning and skips glob-registering block components. If delta/building-blocks is missing, blockLoader has an empty map.

delta.config.ts

Used by the Delta CLI (not read directly by this Nuxt module). Example:

export type DeltaConfig = {
  directories: {
    components: string
    content: string
  }
  theme: {
    name: string
    prn: string
  }
  token?: string
}

const config: DeltaConfig = {
  directories: {
    components: 'app/blocks',
    content: 'delta',
  },
  theme: {
    name: 'My Theme',
    prn: 'prn:plate-dev:…:cms:theme:…',
  },
  token: process.env.DELTA_TOKEN,
}

export default config

Building-block registry (app/blocks/index.ts)

Generated by the Delta CLI. Maps CMS slugs to Vue component names:

// Autogenerated by the Delta CLI. DO NOT MODIFY OR REMOVE.

export const components = {
  root: 'RootBuildingBlock',
  'smart-text': 'SmartTextBuildingBlock',
  hero: 'HeroBuildingBlock',
}

The module registers all *.vue files under app/blocks as global components. Module pages import this map as ~/blocks and pass it to useDeltaComponents().

JSON definitions in delta/building-blocks/<slug>.json are bundled into the #delta-building-blocks alias and used as blockLoader for the Delta Vue plugin.

Building blocks

Each building block is a Vue SFC. Use generated types from delta-types.d.ts for typed data props.

<!-- app/blocks/HeroBuildingBlock.vue -->
<template>
  <section data-building-block-slug="hero">
    <h1>{{ data.title }}</h1>
  </section>
</template>

<script setup lang="ts">
import type { BuildingBlock } from '@lars-plate/delta-client'
import type { Content } from '@platecms/delta-client' // generated by Delta CLI

defineProps<{
  buildingBlock: BuildingBlock
  data: Content.HeroBuildingBlock
}>()
</script>
  • data-building-block-slug should match the block slug in the CMS.
  • buildingBlock is the block schema (from props or blockLoader).
  • data is the resolved field content, typed per block in Content.*.

Routes

The module extends Nuxt pages automatically:

Route Enabled when Purpose
/:pathMatch(.*)* Always Fetches and renders a content experience for the current URL path
/editor/content-experiences/:pathMatch(.*)* delta.editor: true CMS editor iframe for a content experience
/editor/global-components/:pathMatch(.*)* delta.editor: true CMS editor iframe for a global component
/editor/blueprints/:pathMatch(.*)* delta.editor: true CMS editor iframe for a blueprint
/preview/:pathMatch(.*)* delta.preview: true CMS preview iframe
/components delta.components: true Lists all building blocks with placeholders
/components/:slug delta.components: true Renders a single building block in isolation

The catch-all content route is registered last so more specific app routes (e.g. /about) can take precedence if you define them in your own pages/ directory.

Content experience (production)

The catch-all page loads CMS content for the current path. v0 uses the GraphQL component tree; v1 uses the accessible / CDA tree:

<script setup lang="ts">
const { data, error } = useDeltaFetchContentExperienceByPath(useRoute().path)
</script>

<template>
  <DeltaContentExperienceComponent
    v-if="version === 'v0' && data"
    :content-experience="data"
    :root-experience-component="data.experienceComponent"
  />
  <DeltaAccessibleContentExperienceComponent
    v-else-if="version === 'v1' && data"
    :content-experience="data"
    :root-experience-component="data.experienceComponent"
  />
  <p v-if="error">Error: {{ error.message }}</p>
</template>

Visit /, /blog/my-post, or any path that exists in your CMS.

Editor & preview (CMS iframe)

When editor or preview is enabled, those pages listen for messages from the parent CMS window via useDeltaClientConnector() and render incoming ContentExperience / ExperienceComponent payloads (GraphQL tree).

Point your Plate CMS theme settings at:

CMS target App URL
Content experience editor https://your-app.example/editor/content-experiences
Global component editor https://your-app.example/editor/global-components
Blueprint editor https://your-app.example/editor/blueprints
Preview https://your-app.example/preview

Component showcase (local dev)

With components: true:

  • Open /components to see every registered block with placeholder data.
  • Open /components/hero (or any slug) to work on one block without CMS content.

Auto-imports

The module registers these composables (from @lars-plate/delta-client-vue):

Composable Description
useDeltaClientConnector Window messaging between Nuxt app and CMS parent frame
useDeltaComponents Resolves slug → Vue component map from app/blocks/index.ts
useDeltaFetchContentExperienceByPath Fetches content experience by URL path (Vue Query)

The runtime plugin also registers Delta Vue components globally, including:

Component Description
DeltaContentExperienceComponent GraphQL content experience tree (v0 / editor)
DeltaExperienceComponentComponent Single GraphQL experience component
DeltaBuildingBlockComponent One building block (used in /components)
DeltaGridPlacementComponent Grid placement / layout regions
DeltaAccessibleContentExperienceComponent CDA accessible experience tree (v1)
DeltaAccessibleExperienceComponentComponent Single accessible experience component
DeltaAccessibleBuildingBlockComponent Accessible building block

Use them in any page or component without manual imports.

Custom pages

You can build your own routes and still use Delta primitives. Provide the block map with the DELTA_COMPONENTS symbol (not the string 'components'):

<!-- pages/custom.vue -->
<script setup lang="ts">
import { DELTA_COMPONENTS, useDeltaComponents } from '@lars-plate/delta-client-vue'
import { components as blocks } from '~/blocks'

const { components } = useDeltaComponents(blocks)
provide(DELTA_COMPONENTS, components)

const { data } = useDeltaFetchContentExperienceByPath('/my-custom-path')
</script>

<template>
  <DeltaAccessibleContentExperienceComponent
    v-if="data"
    :content-experience="data"
    :root-experience-component="data.experienceComponent"
  />
</template>

provide(DELTA_COMPONENTS, components) is required so nested Delta components can resolve building-block Vue components.

Runtime config

Access Delta settings anywhere in the app:

const { environment, token, version } = useRuntimeConfig().public.delta

The Nuxt plugin also provides DELTA_CONFIG on the Vue app for @lars-plate/delta-client-vue composables.

TypeScript

Commit the generated delta-types.d.ts from the Delta CLI. It currently augments @platecms/delta-client with project-specific Content.* interfaces (runtime packages in this repo are @lars-plate/*):

// delta-types.d.ts (excerpt — generated, do not edit by hand)
declare module '@platecms/delta-client' {
  namespace Content {
    export interface HeroBuildingBlock {
      title: string
    }
  }
}

Run vue-tsc --noEmit in your app to verify block props against generated types.

Development workflow

  1. Configure delta.config.ts and authenticate the Delta CLI.
  2. Pull or sync schemas: building blocks and content types under delta/.
  3. Generate or update app/blocks/*.vue, app/blocks/index.ts, and delta-types.d.ts.
  4. Run nuxt dev with DELTA_TOKEN set.
  5. Use /components (if enabled) to iterate on blocks; use /editor/... and /preview when testing inside the CMS.

Module development

This package lives in the delta-packages Nx workspace. A consumer app is app/nuxt-playground.

# Install dependencies (monorepo root)
pnpm install

# Build the module
pnpm nx build delta-client-nuxt

# Typecheck
pnpm nx typecheck delta-client-nuxt

Related packages

Package Role
@lars-plate/delta-client Core client, GraphQL types, CDA, window connector
@lars-plate/delta-client-vue Vue components, views, and composables
@lars-plate/delta-client-nuxt This module — Nuxt integration layer

License

MIT © Lars Baalmans

Version History

Version Released License
1.1.15
1.1.14
1.1.12
1.1.11
1.1.10