Skip to content

Commit e33e4b3

Browse files
chore(skills): rewrite agent skill with opinionated guidelines and recipes (#6347)
1 parent 0fc05b7 commit e33e4b3

21 files changed

Lines changed: 2171 additions & 1431 deletions

File tree

docs/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Used when pre-rendering the docs for dynamic OG images
22
NUXT_PUBLIC_SITE_URL=
3-
# Used to fetch `nuxt/ui-pro` docs content
3+
# Used to fetch GitHub data (commits, releases, pull requests)
44
NUXT_GITHUB_TOKEN=
55
# Vercel AI gateway key
66
AI_GATEWAY_API_KEY=

docs/content/docs/1.getting-started/7.ai/3.skills.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ Or install globally so the skill is available across all your projects:
4949
npx skills add nuxt/ui --global
5050
```
5151

52+
If cloning from GitHub is slow on your network, you can install directly from the website instead:
53+
54+
```bash
55+
npx skills add https://ui.nuxt.com
56+
```
57+
5258
::tip
5359
Visit [skills.sh](https://skills.sh) to learn more about the skills ecosystem and browse available skills.
5460
::

docs/nuxt.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ export default defineNuxtConfig({
168168
compatibilityDate: '2026-01-14',
169169

170170
nitro: {
171+
publicAssets: [{
172+
dir: resolve('../skills'),
173+
baseURL: '/.well-known/skills',
174+
maxAge: 60 * 60 * 24
175+
}],
171176
prerender: {
172177
routes: [
173178
'/docs/getting-started',

skills/index.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"skills": [
3+
{
4+
"name": "nuxt-ui",
5+
"description": "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.",
6+
"files": [
7+
"SKILL.md",
8+
"references/components.md",
9+
"references/guidelines/component-selection.md",
10+
"references/guidelines/conventions.md",
11+
"references/guidelines/design-system.md",
12+
"references/guidelines/forms.md",
13+
"references/layouts/chat.md",
14+
"references/layouts/dashboard.md",
15+
"references/layouts/docs.md",
16+
"references/layouts/editor.md",
17+
"references/layouts/landing.md",
18+
"references/recipes/auth.md",
19+
"references/recipes/data-tables.md",
20+
"references/recipes/navigation.md",
21+
"references/recipes/overlays.md"
22+
]
23+
}
24+
]
25+
}

skills/nuxt-ui/SKILL.md

Lines changed: 82 additions & 241 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,86 @@ description: Build UIs with @nuxt/ui v4 — 125+ accessible Vue components with
55

66
# Nuxt UI
77

8-
Vue component library built on [Reka UI](https://reka-ui.com/) + [Tailwind CSS](https://tailwindcss.com/) + [Tailwind Variants](https://www.tailwind-variants.org/). Works with Nuxt, Vue (Vite), Laravel (Inertia), and AdonisJS (Inertia).
8+
Vue component library built on [Reka UI](https://reka-ui.com/) + [Tailwind CSS](https://tailwindcss.com/) + [Tailwind Variants](https://www.tailwind-variants.org/). Works with Nuxt, Vue (Vite), Laravel (Vite + Inertia), and AdonisJS (Vite + Inertia).
9+
10+
## MCP Server
11+
12+
For component API details (props, slots, events, full documentation, examples), use the [Nuxt UI MCP server](https://ui.nuxt.com/docs/getting-started/ai/mcp). If not already configured, add it:
13+
14+
**Cursor**`.cursor/mcp.json`:
15+
16+
```json
17+
{ "mcpServers": { "nuxt-ui": { "type": "http", "url": "https://ui.nuxt.com/mcp" } } }
18+
```
19+
20+
**Claude Code**:
21+
22+
```bash
23+
claude mcp add --transport http nuxt-ui https://ui.nuxt.com/mcp
24+
```
25+
26+
Key MCP tools:
27+
- `search_components` — find components by name, description, or category (no params = list all)
28+
- `search_composables` — find composables by name or description (no params = list all)
29+
- `search_icons` — search Iconify icons (defaults to `lucide`), returns `i-{prefix}-{name}` names
30+
- `get_component` — full component documentation with usage examples
31+
- `get_component_metadata` — props, slots, events (lightweight, no docs content)
32+
- `get_example` — real-world code examples
33+
34+
When you need to know **what a component accepts** or **how its API works**, use the MCP. This skill teaches you **when to use which component** and **how to build well**.
35+
36+
## Core rules (always apply)
37+
38+
1. **Always wrap the app in `UApp`** — required for toasts, tooltips, and programmatic overlays. Accepts a `locale` prop for i18n.
39+
2. **Always use semantic colors**`text-default`, `bg-elevated`, `border-muted`, etc. Never use raw Tailwind palette colors like `text-gray-500`.
40+
3. **Read generated theme files for slot names** — Nuxt: `.nuxt/ui/<component>.ts`, Vue: `node_modules/.nuxt-ui/ui/<component>.ts`. These show every slot, variant, and default class for any component.
41+
4. **Override priority** (highest wins): `ui` prop / `class` prop → global config → theme defaults.
42+
5. **Icons use `i-{collection}-{name}` format**`lucide` is the default collection. Use the MCP `search_icons` tool to find icons, or browse at [icones.js.org](https://icones.js.org).
43+
44+
## How to use this skill
45+
46+
Based on the task, load the relevant reference files **before writing any code**. Don't load everything — only what's needed.
47+
48+
### Reference files
49+
50+
**Guidelines** — design decisions and conventions:
51+
- [design-system](references/guidelines/design-system.md) — semantic colors, theming, brand customization, variants, the `ui` prop
52+
- [component-selection](references/guidelines/component-selection.md) — decision matrices: when to use Modal vs Slideover, Select vs SelectMenu, Toast vs Alert, etc.
53+
- [conventions](references/guidelines/conventions.md) — coding patterns, slot naming, items arrays, composables, keyboard shortcuts
54+
- [forms](references/guidelines/forms.md) — form validation, field layout, error handling, Standard Schema
55+
56+
**Layouts** — full page structure patterns:
57+
- [landing](references/layouts/landing.md) — landing pages, blog, changelog, pricing
58+
- [dashboard](references/layouts/dashboard.md) — admin UI with sidebar and panels
59+
- [docs](references/layouts/docs.md) — documentation sites with navigation and TOC
60+
- [chat](references/layouts/chat.md) — AI chat with Vercel AI SDK
61+
- [editor](references/layouts/editor.md) — rich text editor with toolbars
62+
63+
**Recipes** — complete patterns for common tasks:
64+
- [data-tables](references/recipes/data-tables.md) — tables with filters, pagination, sorting, selection
65+
- [auth](references/recipes/auth.md) — login, signup, forgot password forms
66+
- [overlays](references/recipes/overlays.md) — modals, slideovers, drawers, command palette
67+
- [navigation](references/recipes/navigation.md) — headers, sidebars, breadcrumbs, tabs
68+
69+
**Quick reference:**
70+
- [components](references/components.md) — categorized component index for finding the right component name
71+
72+
### Routing table
73+
74+
| Task | Load these references |
75+
|---|---|
76+
| Build a landing page | design-system, conventions, landing |
77+
| Build a dashboard / admin UI | conventions, component-selection, dashboard |
78+
| Add a settings page | conventions, forms |
79+
| Create a login / signup form | conventions, forms, auth |
80+
| Display data in a table | conventions, component-selection, data-tables |
81+
| Customize theme / brand colors | design-system |
82+
| Add a chat interface | conventions, chat |
83+
| Add a modal, slideover, or drawer | conventions, component-selection, overlays |
84+
| Build site navigation | conventions, component-selection, navigation |
85+
| Build a documentation site | conventions, docs |
86+
| Add a rich text editor | conventions, editor |
87+
| General UI work | conventions, component-selection |
988

1089
## Installation
1190

@@ -67,7 +146,6 @@ import ui from '@nuxt/ui/vue-plugin'
67146
import App from './App.vue'
68147

69148
const app = createApp(App)
70-
71149
const router = createRouter({
72150
routes: [],
73151
history: createWebHistory()
@@ -93,242 +171,5 @@ app.mount('#app')
93171
</template>
94172
```
95173

96-
> **Vue**: Add `class="isolate"` to your root `<div id="app">` in `index.html`.
97-
98-
> **Vue + Inertia**: Use `ui({ router: 'inertia' })` in `vite.config.ts`.
99-
100-
### UApp
101-
102-
Wrapping your app in `UApp` is **required** — it provides global config for toasts, tooltips, and programmatic overlays. It also accepts a `locale` prop for i18n (see [composables reference](references/composables.md)).
103-
104-
## Icons
105-
106-
Nuxt UI uses [Iconify](https://iconify.design/) for 200,000+ icons. In Nuxt, `@nuxt/icon` is auto-registered. In Vue, icons work out of the box via the Vite plugin.
107-
108-
### Naming convention
109-
110-
Icons use the format `i-{collection}-{name}`:
111-
112-
```vue
113-
<UIcon name="i-lucide-sun" class="size-5" />
114-
<UButton icon="i-lucide-plus" label="Add" />
115-
<UAlert icon="i-lucide-info" title="Heads up" />
116-
```
117-
118-
> Browse all icons at [icones.js.org](https://icones.js.org). The `lucide` collection is used throughout Nuxt UI defaults.
119-
120-
### Install icon collections locally
121-
122-
```bash
123-
pnpm i @iconify-json/lucide
124-
pnpm i @iconify-json/simple-icons
125-
```
126-
127-
### Custom local collections (Nuxt)
128-
129-
```ts
130-
// nuxt.config.ts
131-
export default defineNuxtConfig({
132-
icon: {
133-
customCollections: [{
134-
prefix: 'custom',
135-
dir: './app/assets/icons'
136-
}]
137-
}
138-
})
139-
```
140-
141-
```vue
142-
<UIcon name="i-custom-my-icon" />
143-
```
144-
145-
## Theming & Branding
146-
147-
Nuxt UI ships with a default look. The goal is to adapt it to your brand so every app looks unique.
148-
149-
**Always use semantic utilities** (`text-default`, `bg-elevated`, `border-muted`), never raw Tailwind palette colors. See [references/theming.md](references/theming.md) for the full list.
150-
151-
### Colors
152-
153-
7 semantic colors (`primary`, `secondary`, `success`, `info`, `warning`, `error`, `neutral`) configurable at runtime:
154-
155-
```ts
156-
// Nuxt — app.config.ts
157-
export default defineAppConfig({
158-
ui: { colors: { primary: 'indigo', neutral: 'zinc' } }
159-
})
160-
```
161-
162-
```ts
163-
// Vue — vite.config.ts
164-
import { defineConfig } from 'vite'
165-
import vue from '@vitejs/plugin-vue'
166-
import ui from '@nuxt/ui/vite'
167-
168-
export default defineConfig({
169-
plugins: [
170-
vue(),
171-
ui({
172-
ui: { colors: { primary: 'indigo', neutral: 'zinc' } }
173-
})
174-
]
175-
})
176-
```
177-
178-
### Customizing components
179-
180-
**Override priority** (highest wins): `ui` prop / `class` prop > global config > theme defaults.
181-
182-
The `ui` prop overrides a component's **slots** after variants are computed — it wins over everything:
183-
184-
```vue
185-
<UButton :ui="{ base: 'rounded-none', trailingIcon: 'size-3 rotate-90' }" />
186-
<UCard :ui="{ header: 'bg-muted', body: 'p-8' }" />
187-
```
188-
189-
**Read the generated theme file** to find slot names for any component:
190-
191-
- **Nuxt**: `.nuxt/ui/<component>.ts`
192-
- **Vue**: `node_modules/.nuxt-ui/ui/<component>.ts`
193-
194-
> For CSS variables, custom colors, global config, compound variants, and a **full brand customization playbook**, see [references/theming.md](references/theming.md)
195-
196-
## Composables
197-
198-
```ts
199-
// Notifications
200-
const toast = useToast()
201-
toast.add({ title: 'Saved', color: 'success', icon: 'i-lucide-check' })
202-
203-
// Programmatic overlays
204-
const overlay = useOverlay()
205-
const modal = overlay.create(MyModal)
206-
const { result } = modal.open({ title: 'Confirm' })
207-
await result
208-
209-
// Keyboard shortcuts
210-
defineShortcuts({
211-
meta_k: () => openSearch(),
212-
escape: () => close()
213-
})
214-
```
215-
216-
> For full composable reference, see [references/composables.md](references/composables.md)
217-
218-
## Form validation
219-
220-
Uses Standard Schema — works with Zod, Valibot, Yup, or Joi.
221-
222-
```vue
223-
<script setup lang="ts">
224-
import { z } from 'zod'
225-
226-
const schema = z.object({
227-
email: z.string().email('Invalid email'),
228-
password: z.string().min(8, 'Min 8 characters')
229-
})
230-
231-
type Schema = z.output<typeof schema>
232-
const state = reactive<Partial<Schema>>({ email: '', password: '' })
233-
234-
function onSubmit() {
235-
// UForm validates before emitting @submit — state is valid here
236-
}
237-
</script>
238-
239-
<template>
240-
<UForm :schema="schema" :state="state" @submit="onSubmit">
241-
<UFormField name="email" label="Email" required>
242-
<UInput v-model="state.email" type="email" />
243-
</UFormField>
244-
245-
<UFormField name="password" label="Password" required>
246-
<UInput v-model="state.password" type="password" />
247-
</UFormField>
248-
249-
<UButton type="submit">Sign in</UButton>
250-
</UForm>
251-
</template>
252-
```
253-
254-
> For all form components and validation patterns, see [references/components.md](references/components.md#form)
255-
256-
## Overlays
257-
258-
```vue
259-
<!-- Modal -->
260-
<UModal v-model:open="isOpen" title="Edit" description="Edit your profile">
261-
<template #body>Content</template>
262-
<template #footer>
263-
<UButton variant="ghost" @click="isOpen = false">Cancel</UButton>
264-
<UButton @click="save">Save</UButton>
265-
</template>
266-
</UModal>
267-
268-
<!-- Slideover (side panel) -->
269-
<USlideover v-model:open="isOpen" title="Settings" side="right">
270-
<template #body>Content</template>
271-
</USlideover>
272-
273-
<!-- Dropdown menu (flat array) -->
274-
<UDropdownMenu :items="[
275-
{ label: 'Edit', icon: 'i-lucide-pencil' },
276-
{ type: 'separator' },
277-
{ label: 'Delete', icon: 'i-lucide-trash', color: 'error' }
278-
]">
279-
<UButton icon="i-lucide-ellipsis-vertical" variant="ghost" />
280-
</UDropdownMenu>
281-
282-
<!-- Dropdown menu (nested array — groups with automatic separators) -->
283-
<UDropdownMenu :items="[
284-
[{ label: 'Edit', icon: 'i-lucide-pencil' }, { label: 'Duplicate', icon: 'i-lucide-copy' }],
285-
[{ label: 'Delete', icon: 'i-lucide-trash', color: 'error' }]
286-
]">
287-
<UButton icon="i-lucide-ellipsis-vertical" variant="ghost" />
288-
</UDropdownMenu>
289-
```
290-
291-
> For all overlay components, see [references/components.md](references/components.md#overlay)
292-
293-
## Layouts
294-
295-
Nuxt UI provides components to compose full page layouts. Load the reference matching your use case:
296-
297-
| Layout | Description | Reference |
298-
|---|---|---|
299-
| Page | Landing, blog, changelog, pricing — public-facing pages | [layouts/page.md](references/layouts/page.md) |
300-
| Dashboard | Admin UI with resizable sidebar and panels | [layouts/dashboard.md](references/layouts/dashboard.md) |
301-
| Docs | Documentation with sidebar nav and TOC | [layouts/docs.md](references/layouts/docs.md) |
302-
| Chat | AI chat with messages and prompt | [layouts/chat.md](references/layouts/chat.md) |
303-
| Editor | Rich text editor with toolbars | [layouts/editor.md](references/layouts/editor.md) |
304-
305-
## Templates
306-
307-
Official starter templates at [github.com/nuxt-ui-templates](https://github.com/nuxt-ui-templates):
308-
309-
| Template | Framework | GitHub |
310-
|---|---|---|
311-
| Starter | Nuxt | [nuxt-ui-templates/starter](https://github.com/nuxt-ui-templates/starter) |
312-
| Starter | Vue | [nuxt-ui-templates/starter-vue](https://github.com/nuxt-ui-templates/starter-vue) |
313-
| Dashboard | Nuxt | [nuxt-ui-templates/dashboard](https://github.com/nuxt-ui-templates/dashboard) |
314-
| Dashboard | Vue | [nuxt-ui-templates/dashboard-vue](https://github.com/nuxt-ui-templates/dashboard-vue) |
315-
| SaaS | Nuxt | [nuxt-ui-templates/saas](https://github.com/nuxt-ui-templates/saas) |
316-
| Landing | Nuxt | [nuxt-ui-templates/landing](https://github.com/nuxt-ui-templates/landing) |
317-
| Docs | Nuxt | [nuxt-ui-templates/docs](https://github.com/nuxt-ui-templates/docs) |
318-
| Portfolio | Nuxt | [nuxt-ui-templates/portfolio](https://github.com/nuxt-ui-templates/portfolio) |
319-
| Chat | Nuxt | [nuxt-ui-templates/chat](https://github.com/nuxt-ui-templates/chat) |
320-
| Editor | Nuxt | [nuxt-ui-templates/editor](https://github.com/nuxt-ui-templates/editor) |
321-
| Changelog | Nuxt | [nuxt-ui-templates/changelog](https://github.com/nuxt-ui-templates/changelog) |
322-
| Starter | Laravel | [nuxt-ui-templates/starter-laravel](https://github.com/nuxt-ui-templates/starter-laravel) |
323-
| Starter | AdonisJS | [nuxt-ui-templates/starter-adonis](https://github.com/nuxt-ui-templates/starter-adonis) |
324-
325-
> When starting a new project, clone the matching template instead of setting up from scratch.
326-
327-
## Additional references
328-
329-
Load based on your task — **do not load all at once**:
330-
331-
- [references/theming.md](references/theming.md) — CSS variables, custom colors, component theme overrides
332-
- [references/components.md](references/components.md) — all 125+ components by category with props and usage
333-
- [references/composables.md](references/composables.md) — useToast, useOverlay, defineShortcuts
334-
- Generated theme files — all slots, variants, and default classes for any component (Nuxt: `.nuxt/ui/<component>.ts`, Vue: `node_modules/.nuxt-ui/ui/<component>.ts`)
174+
> Add `class="isolate"` to your root `<div id="app">` in `index.html`.
175+
> For Inertia: use `ui({ router: 'inertia' })` in `vite.config.ts`.

0 commit comments

Comments
 (0)