@ardimo/cms

1
Install
npm install @ardimo/cms
Latest Version:1.0.2
Vue:3
License:MIT
Last Updated:Sep 14, 2026
Links: npm
Maintainer: ardimo

@ardimo/cms

npm version npm downloads License Nuxt

A Nuxt module that turns your .vue files into a CMS component registry. Declare components and layouts with defineCmsComponent / defineCmsLayout, and the module auto-registers them as global Vue components and syncs their schema to a remote CMS endpoint.

  • ✨  Release Notes

Features

  • 🔍  Scans your app's .vue files for defineCmsComponent / defineCmsLayout declarations
  • 🌍  Auto-registers matching components as global Vue components
  • 🔄  Syncs the resulting registry (props via FormKit schema, slots, icons) to a remote CMS endpoint
  • 🧩  Detects duplicate keys and other authoring mistakes at build/dev time with clear, file-and-line errors
  • ⚡  Runs on ready in dev and on build:before in production builds

Quick Setup

Install the module to your Nuxt application:

npx nuxt module add @ardimo/cms

Then configure it in nuxt.config.ts:

export default defineNuxtConfig({
  modules: ["@ardimo/cms"],
  cms: {
    apiKey: process.env.CMS_API_KEY,
    endpoint: process.env.CMS_ENDPOINT,
    timeout: 5000 // optional, defaults to 5000ms
  }
})

Usage

Declare a component by calling defineCmsComponent inside a <script setup> block. Only <script setup> files are scanned; plain <script> blocks are skipped with a warning if they look like they're trying to use the macro.

<!-- components/HeroBanner.vue -->
<script setup lang="ts">
defineCmsComponent({
  name: "Hero Banner",
  icon: "image",
  props: [
    { $formkit: "text", name: "title", label: "Title" },
    { $formkit: "textarea", name: "subtitle", label: "Subtitle" }
  ],
  slots: {
    default: { min: 0, max: 1 }
  }
})
</script>

<template>
  <section>
    <h1>{{ title }}</h1>
    <p>{{ subtitle }}</p>
    <slot />
  </section>
</template>

Layouts work the same way with defineCmsLayout:

<!-- layouts/TwoColumn.vue -->
<script setup lang="ts">
defineCmsLayout({
  name: "Two Column",
  icon: "columns"
})
</script>

If key/name are omitted, they are derived from the file name (e.g. HeroBanner.vue → hero-banner). A file must declare exactly one macro call, and a key must be unique across all components (and, separately, all layouts) in the app.

Module Options

Option Type Default Description
apiKey string - Sent as the api-key header when syncing the registry.
endpoint string - URL the registry is POSTed to. If unset, syncing is skipped.
timeout number 5000 Abort the sync request after this many milliseconds.

Contribution

Local development
# Install dependencies
npm install

# Generate type stubs
npm run dev:prepare

# Develop with the playground
npm run dev

# Build the playground
npm run dev:build

# Run ESLint
npm run lint

# Run Vitest
npm run test
npm run test:watch

# Release new version
npm run release

Version History

Version Released Vue License
1.0.2 ^3.0 MIT
1.0.1 ^3.0 MIT