plugins/smedjen/skills/nuxt-patterns/SKILL.md
Nuxt 3/4 patterns — auto-imports, useFetch, server routes, layers, and module development
npx skillsauth add hjemmesidekongen/ai nuxt-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Nuxt 3 is a full-stack Vue framework built on Nitro (server engine) and Vite (dev server). It unifies SSR, SSG, and SPA in one model. The key mental shift from Nuxt 2: everything is composable-first, auto-imported, and TypeScript-native by default.
Directory roles: pages/ → file-based routing, components/ → auto-imported Vue components, composables/ → auto-imported composables, server/api/ → Nitro API routes, server/middleware/ → server-side middleware, layers/ → composable feature layers.
Nuxt auto-imports from components/, composables/, utils/, and Nuxt's own API surface. No import statements needed for ref, computed, useState, useFetch, useRoute, defineEventHandler, etc.
Rule: if you're writing import { useFetch } from '#app' or import { ref } from 'vue', you're doing it wrong. Remove the import — it just works.
Custom composables in composables/ are auto-imported by filename. useMyThing.ts → useMyThing() available everywhere.
Three primitives, each with a specific role:
| Scenario | Use |
|----------|-----|
| Page-level data, SSR + client hydration | useFetch |
| Same data across multiple components | useAsyncData with a shared key |
| Client-only fetch (post-mount, no SSR) | $fetch in onMounted or event handler |
| Form submissions, mutations | $fetch directly |
useFetch is shorthand for useAsyncData(url, () => $fetch(url)). Use useFetch for the simple case; reach for useAsyncData when you need a custom fetcher, shared deduplication key, or lazy loading.
Caching: both useFetch and useAsyncData deduplicate by key — same key across components shares one request. Pass { key: 'my-key' } explicitly when the URL isn't unique enough.
Defined in server/api/ and server/routes/. server/api/ routes are auto-prefixed with /api/.
Each file exports a default defineEventHandler. Method routing via filename: users.get.ts, users.post.ts. Dynamic params: users/[id].get.ts.
Input validation belongs in the handler — use readBody, getQuery, getRouterParam, then validate before touching the DB.
Full patterns, layers, module development, runtime config, state management, Nuxt 2→3 migration, and anti-patterns: references/process.md
development
Creates a brand from scratch through market research and interactive sparring. Runs competitive research via Perplexity, then guides the user through positioning, audience, voice, values, and content pillars. Produces the full brand guideline set at .ai/brand/{name}/. Use when building a new brand, defining brand strategy for a product, or when /våbenskjold:create is invoked.
testing
Loads brand guidelines from .ai/brand/{name}/ and makes them available to the current context. Progressive disclosure: L1 confirms brand exists, L2 loads summary, L3 loads specific files on demand. Use when a downstream skill or user needs brand context, or when /våbenskjold:apply is invoked.
documentation
Guided reinvention of an existing brand guideline. Loads current brand from .ai/brand/{name}/, identifies what to keep vs change, and walks the user through targeted evolution. Preserves brand equity while updating positioning, voice, or values. Use when refreshing a brand or when /våbenskjold:evolve is invoked.
development
Codifies an existing brand from materials, samples, and references. Analyzes provided content to extract voice patterns, values, and positioning. Produces the same guideline format as brand-strategy. Use when a brand already exists but isn't documented, or when /våbenskjold:audit is invoked.