All skills
onmax avatar

/nuxt-ui

@de09c7b official
by Maxonmax/nuxt-skills715 stars
38

Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with Tailwind CSS theming. Use when creating interfaces, customizing themes to match a brand, building forms, or composing layouts like dashboards, docs sites, and chat interfaces.

Use this Skill: https://skilld.dev/gh/onmax/nuxt-skills/nuxt-ui

This session only. Nothing lands on disk.

referencesguidelinesconventions.md

≈2.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Conventions

Coding patterns specific to Nuxt UI.

Auto-registered modules

Nuxt UI automatically registers @nuxt/icon, @nuxt/fonts, and @nuxtjs/color-mode. Do not add them to your modules array. Configure them via root-level keys in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui'],
  icon: { /* @nuxt/icon options */ },
  fonts: { /* @nuxt/fonts options */ },
  colorMode: { /* @nuxtjs/color-mode options */ }
})

Disable any of them: ui: { fonts: false }, ui: { colorMode: false }.

Content module integration

When using @nuxt/content, it must come after @nuxt/ui in the modules array — otherwise prose components won't be available:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui', '@nuxt/content']
})

Add @source in your CSS so Tailwind generates classes used in markdown/MDC:

/* app/assets/css/main.css */
@import "tailwindcss";
@import "@nuxt/ui";

@source "../../../content/**/*";

Use mapContentNavigation to transform content navigation for components like UBreadcrumb:

import { mapContentNavigation } from '@nuxt/ui/utils/content'
import { findPageBreadcrumb } from '@nuxt/content/utils'

const breadcrumb = computed(() =>
  mapContentNavigation(findPageBreadcrumb(navigation.value, page.value?.path))
)

IDE setup

Recommended .vscode/settings.json for Tailwind IntelliSense autocomplete with Nuxt UI:

{
  "files.associations": { "*.css": "tailwindcss" },
  "editor.quickSuggestions": { "strings": "on" },
  "tailwindCSS.classAttributes": ["class", "ui"],
  "tailwindCSS.classFunctions": ["defineAppConfig"]
}

UApp wrapper

Always wrap your app in UApp — it provides:

  • Toast container (useToast)
  • Tooltip provider
  • Programmatic overlay context (useOverlay)
  • i18n locale support
<UApp :locale="fr">
  <NuxtPage /> <!-- or <RouterView /> for Vue -->
</UApp>

Icons

Nuxt UI registers @nuxt/icon automatically. Format: i-{collection}-{name}. Prefer lucide collection.

<UIcon name="i-lucide-sun" class="size-5" />
<UButton icon="i-lucide-plus" label="Add" />
<UAlert icon="i-lucide-info" title="Heads up" />

Install collections locally for reliable SSR and best performance:

pnpm i @iconify-json/lucide
pnpm i @iconify-json/simple-icons

Custom local collections (Nuxt only):

// nuxt.config.ts
export default defineNuxtConfig({
  icon: {
    customCollections: [{
      prefix: 'custom',
      dir: './app/assets/icons'
    }]
  }
})

Default icon overrides

Components like Modal, Select, Accordion, etc. use default icons from appConfig.ui.icons. Override them globally:

// app.config.ts
export default defineAppConfig({
  ui: {
    icons: {
      loading: 'i-lucide-refresh-cw',
      close: 'i-lucide-x',
      check: 'i-lucide-check',
      chevronDown: 'i-lucide-chevron-down',
      chevronRight: 'i-lucide-chevron-right',
      arrowLeft: 'i-lucide-arrow-left',
      arrowRight: 'i-lucide-arrow-right'
    }
  }
})

Slot patterns

Most components follow consistent slot naming:

Slot Used by Purpose
#header Card, Modal, Slideover, DashboardPanel Top section
#body DashboardPanel Scrollable content area
#footer Card, Modal, Slideover, DashboardPanel Bottom section
#left Page, DashboardNavbar Left sidebar or content
#right Page, DashboardNavbar, Header Right sidebar or content
#leading Input, Button, Alert Before main content (icon area)
#trailing Input, Button After main content (icon area)
#content Modal, Slideover, Popover, Tooltip Full content override
#default Most components Main content area

Items arrays

Many components accept an items prop. Two patterns:

Flat array — plain list:

const items = [
  { label: 'Edit', icon: 'i-lucide-pencil' },
  { label: 'Delete', icon: 'i-lucide-trash', color: 'error' }
]

Nested array — groups with automatic separators between them:

const items = [
  [
    { label: 'Edit', icon: 'i-lucide-pencil' },
    { label: 'Duplicate', icon: 'i-lucide-copy' }
  ],
  [
    { label: 'Delete', icon: 'i-lucide-trash', color: 'error' }
  ]
]

Components supporting nested arrays: UDropdownMenu, UContextMenu, UNavigationMenu. UCommandPalette uses a groups prop instead, with an items array on each group.

Composables

useToast

const toast = useToast()

toast.add({
  title: 'Success',
  description: 'Item saved',
  color: 'success',
  icon: 'i-lucide-check-circle',
  duration: 5000,
  actions: [{ label: 'Undo', onClick: () => {} }]
})

toast.remove('toast-id')
toast.clear()

useOverlay

Programmatic modals, slideovers, drawers — no template v-model needed. See overlays recipe for full patterns.

const overlay = useOverlay()
const modal = overlay.create(MyComponent)
const instance = modal.open({ title: 'Confirm?' })
if (await instance.result) { /* confirmed */ }

defineShortcuts

defineShortcuts({
  meta_k: () => openSearch(),
  escape: () => close(),
  meta_enter: {
    handler: () => submit(),
    whenever: [isFormValid]
  }
})

Keys: meta (Cmd/Ctrl), ctrl, alt, shift. Separator: _.

extractShortcuts

Wire up keyboard shortcuts from menu items:

const items = [
  { label: 'New file', kbds: ['meta', 'n'], onSelect: () => newFile() },
  { label: 'Save', kbds: ['meta', 's'], onSelect: () => save() }
]

defineShortcuts(extractShortcuts(items))

Internationalization (i18n)

Nuxt UI supports 50+ locales. Set the locale on UApp — all components inherit it.

Static locale
<script setup lang="ts">
import { fr } from '@nuxt/ui/locale'
</script>

<template>
  <UApp :locale="fr">
    <NuxtPage />
  </UApp>
</template>
Extend a built-in locale

extendLocale is auto-imported. Override specific messages or the code (affects date/time formatting in Calendar, InputDate, InputTime):

import { en } from '@nuxt/ui/locale'

const locale = extendLocale(en, {
  code: 'en-AU',
  messages: {
    commandPalette: { placeholder: 'Search a component...' }
  }
})
Custom locale from scratch
import type { Messages } from '@nuxt/ui'

const locale = defineLocale<Messages>({
  name: 'My locale',
  code: 'en',
  dir: 'ltr',
  messages: {
    // all component message keys
  }
})
Dynamic locale with @nuxtjs/i18n
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui', '@nuxtjs/i18n'],
  i18n: {
    locales: [
      { code: 'en', name: 'English' },
      { code: 'fr', name: 'Français' },
      { code: 'ar', name: 'العربية' }
    ]
  }
})
<script setup lang="ts">
import * as locales from '@nuxt/ui/locale'

const { locale } = useI18n()

const lang = computed(() => locales[locale.value]?.code)
const dir = computed(() => locales[locale.value]?.dir)

useHead({
  htmlAttrs: { lang, dir }
})
</script>

<template>
  <UApp :locale="locales[locale]">
    <NuxtPage />
  </UApp>
</template>

Each locale has a dir property ('ltr' or 'rtl'). UApp uses it to set directionality on all components. Use useHead to propagate lang and dir to the <html> element.

Color mode

Nuxt UI registers @nuxtjs/color-mode automatically. Built-in components for switching:

  • UColorModeButton — single button toggle (light/dark)
  • UColorModeSwitch — toggle switch
  • UColorModeSelect — dropdown with system/light/dark options
  • UColorModeAvatar — displays different avatar per mode
  • UColorModeImage — displays different image per mode

For custom color mode UI, use useColorMode with ClientOnly to avoid hydration mismatch:

<script setup lang="ts">
const colorMode = useColorMode()

const isDark = computed({
  get: () => colorMode.value === 'dark',
  set: (v) => { colorMode.preference = v ? 'dark' : 'light' }
})
</script>

<template>
  <ClientOnly>
    <USwitch v-model="isDark" />
    <template #fallback>
      <div class="size-8" />
    </template>
  </ClientOnly>
</template>

Official templates

Bootstrap a project from a template instead of starting from scratch:

npx nuxi@latest init -t ui              # Starter
npx nuxi@latest init -t ui/dashboard    # Dashboard
npx nuxi@latest init -t ui/docs         # Docs (Nuxt Content)
npx nuxi@latest init -t ui/landing      # Landing page
npx nuxi@latest init -t ui/saas         # SaaS (landing + pricing + docs + blog)
npx nuxi@latest init -t ui/chat         # AI chat (Vercel AI SDK)
npx nuxi@latest init -t ui/editor       # Rich text editor
npx nuxi@latest init -t ui/portfolio    # Portfolio
npx nuxi@latest init -t ui/changelog    # Changelog
npx nuxi@latest init -t ui/calendar     # Calendar

Responsive patterns

  • Dashboard sidebar hides on mobile, shows a slideover/drawer via UDashboardSidebar mode prop
  • UHeader body slot is the mobile menu content (shown when hamburger is tapped)
  • Most components handle responsiveness automatically — avoid manual breakpoint classes unless needed
  • Use UPageAside for sidebars that should hide below lg breakpoint

Source: SKILL.md on GitHub

No alerts12d5 checks · Risk SAFE
  • Gen Agent Trust Hub12d

    The skill provides comprehensive documentation and implementation guidance for the Nuxt UI v4 component library. It includes a maintenance script for synchronizing documentation with the official repository. No malicious patterns or security risks were identified.

  • Socket12d

    No alerts

  • Snyk12d

    Risk: LOW · No issues

  • Runlayer7mo

    129 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at de09c7b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last week

README badge

README badge for onmax/nuxt-skills/nuxt-ui

Builds styled UI for Nuxt 4+ using @nuxt/ui v4 components with Tailwind CSS and Tailwind Variants. Covers forms with validation, data tables, modals, and theme customization through semantic colors and CSS variables.

Generated from the current SKILL.md.

Does this skill cover Reka UI headless primitives?
No. This skill focuses on @nuxt/ui v4 components (styled, opinionated). For Reka UI primitives, accessibility patterns, and asChild behavior, use the reka-ui skill instead.
What form validation libraries does this support?
Zod and Valibot. The skill includes guidance on useFormField and form component integration with both libraries.
Do I need UApp wrapper?
Yes, UApp is required to use Toast, Tooltip, and overlay components like Modal and Slideover.
Can I customize colors and theme?
Yes. The skill covers semantic colors, CSS variables, app.config.ts setup, and Tailwind Variants for type-safe styling.
What Nuxt and Vue versions does this require?
Vue 3 and Nuxt 4+. The current stable version is v4.4.0 (January 2026).

Generated from the current SKILL.md. These answers refresh after source changes.