home / skills / oro-ad / nuxt-claude-devtools / nuxt-patterns

This skill helps you apply Nuxt 3/4 best practices for auto-imports, composables, server routes, and data fetching across pages.

npx playbooks add skill oro-ad/nuxt-claude-devtools --skill nuxt-patterns

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.9 KB
---
name: nuxt-patterns
description: Nuxt 3/4 best practices. Use when working with Nuxt features like pages, composables, layouts, or server routes.
---

You are a Nuxt expert. Follow these patterns:

## Auto-imports

Don't import Vue or Nuxt APIs manually — they're auto-imported:

```typescript
// ❌ Don't do this
import { ref, computed } from 'vue'
import { useFetch } from '#app'

// ✅ Just use them
const count = ref(0)
const { data } = await useFetch('/api/users')
```

## Composables

Place in `composables/` directory with `use` prefix:

```typescript
// composables/useCounter.ts
export function useCounter(initial = 0) {
  const count = ref(initial)
  const increment = () => count.value++
  return { count, increment }
}
```

## Server Routes

Use `server/api/` for API endpoints:

```typescript
// server/api/users.get.ts
export default defineEventHandler(async (event) => {
  return await fetchUsers()
})

// server/api/users.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  return await createUser(body)
})
```

## Data Fetching

Prefer `useFetch()` or `useAsyncData()`:

```typescript
// Simple fetch
const { data, pending, error } = await useFetch('/api/users')

// With transform
const { data } = await useFetch('/api/users', {
  transform: (users) => users.map(u => u.name)
})
```

## State Management

Use `useState()` for SSR-safe shared state:

```typescript
// Shared across components, SSR-safe
const user = useState('user', () => null)
```

## Runtime Config

Use `useRuntimeConfig()` for environment variables:

```typescript
const config = useRuntimeConfig()
const apiBase = config.public.apiBase
```

## Pages & Routing

File-based routing in `pages/`:

```
pages/
├── index.vue          # /
├── about.vue          # /about
├── users/
│   ├── index.vue      # /users
│   └── [id].vue       # /users/:id
```

Overview

This skill captures Nuxt 3/4 best practices for building reliable, maintainable Nuxt apps. It focuses on idiomatic patterns for auto-imports, composables, server routes, data fetching, state, runtime config, and file-based routing. Use it to standardize structure and avoid common pitfalls when working with Nuxt features like pages, composables, layouts, and server routes.

How this skill works

The guidance inspects common Nuxt usage and recommends patterns that align with framework conventions and SSR behavior. It explains when to rely on auto-imported APIs, how to organize composables and server routes, and which helpers to use for data fetching and SSR-safe state. It also highlights runtime config usage and file-based routing conventions to keep code predictable and portable.

When to use it

  • Starting a new Nuxt 3/4 project and deciding on project structure and conventions
  • Refactoring an app to align with SSR-safe state and composable patterns
  • Adding server-side API endpoints under server/api for consistent routing
  • Implementing data fetching with useFetch or useAsyncData to handle SSR/CSR seamlessly
  • Reading or writing runtime configuration and public environment values

Best practices

  • Rely on Nuxt/Vue auto-imports instead of manual imports for built-in APIs
  • Place composables in composables/ with a use prefix (e.g., useCounter) and return minimal reactive state
  • Create server endpoints under server/api and use defineEventHandler + readBody for request handling
  • Prefer useFetch/useAsyncData for HTTP requests so SSR hydration and caching behave correctly
  • Use useState for shared, SSR-safe state and useRuntimeConfig for environment-dependent values

Example use cases

  • Build a counter composable: composables/useCounter.ts that exposes reactive count and increment
  • Create REST-style server routes: server/api/users.get.ts and server/api/users.post.ts for user CRUD
  • Fetch users on a page with useFetch and transform results for display without manual lifecycle code
  • Store current user in useState('user') to share across components and avoid client-only globals
  • Read public API base from useRuntimeConfig().public.apiBase for consistent runtime URLs

FAQ

Do I need to import ref, computed, or useFetch manually?

No. Nuxt auto-imports common Vue and Nuxt APIs, so use ref, computed, useFetch, etc., directly without manual imports.

Where should I put server-side API handlers?

Place them in server/api using file-based names like users.get.ts or users.post.ts and export a default defineEventHandler.