Skip to content

/web-meta-framework-nuxt

Nuxt patterns - file-based routing, data fetching (useFetch/useAsyncData), useState, server routes, middleware, auto-imports, layouts, SEO

shell
$ npx -y skills add agents-inc/skills --skill web-meta-framework-nuxt --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-meta-framework-nuxt
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Nuxt patterns - file-based routing, data fetching (useFetch/useAsyncData), useState, server routes, middleware, auto-imports, layouts, SEO

SKILL.md

web-meta-framework-nuxt.SKILL.md
name: web-meta-framework-nuxt
description: Nuxt patterns - file-based routing, data fetching (useFetch/useAsyncData), useState, server routes, middleware, auto-imports, layouts, SEO

Nuxt Framework Patterns

> **Quick Guide:** Use `useFetch` for API calls in components (SSR-safe), `useAsyncData` for custom data sources or parallel fetches. Create server routes in `server/api/`. Auto-imports handle composables and components automatically. Use `useState` for SSR-friendly shared state. Data is a `shallowRef` by default -- use `deep: true` if you need deep reactivity.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST use `useFetch` or `useAsyncData` for data fetching in components -- NEVER raw `$fetch` in setup which causes double-fetching)**

**(You MUST use `server/api/` for API routes -- handlers export default with `defineEventHandler()`)**

**(You MUST use `definePageMeta` to attach middleware and configure page behavior -- it is a macro, values must be statically analyzable)**

**(You MUST use `useHead` or `useSeoMeta` for SEO metadata -- never manual `<head>` tags)**

**(You MUST ensure `useState` values are JSON-serializable for SSR hydration -- no functions, classes, or Symbols)**

</critical_requirements>

---

**Auto-detection:** Nuxt, nuxt.config.ts, useFetch, useAsyncData, useState, defineEventHandler, definePageMeta, defineNuxtRouteMiddleware, NuxtLayout, NuxtPage, NuxtLink, navigateTo, server/api, pages/, layouts/, middleware/, composables/, useHead, useSeoMeta, app/ directory

**When to use:**

  • Building Vue 3 applications with file-based routing and SSR/SSG
  • Creating full-stack applications with server routes in the same project
  • Implementing data fetching that works seamlessly across server and client
  • Building SEO-optimized pages with automatic metadata handling
  • Leveraging auto-imports for composables and components

**Key patterns covered:**

  • File-based routing (pages/, dynamic routes, catch-all routes)
  • Data fetching (useFetch, useAsyncData, $fetch)
  • Server routes (server/api/, defineEventHandler)
  • Shared state (useState composable)
  • Route middleware (defineNuxtRouteMiddleware, navigateTo)
  • Layouts (layouts/, NuxtLayout, setPageLayout)
  • SEO (useHead, useSeoMeta)
  • Plugins (plugins/, defineNuxtPlugin)
  • Error handling (NuxtErrorBoundary, createError, showError)
  • Auto-imports (composables, components, utils)

**When NOT to use:**

  • Simple SPAs without SSR needs (consider Vue + Vite directly)
  • Static documentation sites without server logic (consider a static-site generator)

---

<philosophy>

Philosophy

Nuxt is a **meta-framework for Vue 3** that provides file-based routing, automatic code splitting, server-side rendering, and a powerful data-fetching system. Built on Nitro server engine, it enables full-stack development with API routes colocated with your frontend.

**Core Principles:**

1. **Universal rendering by default** -- Pages render on server first, then hydrate on client 2. **Auto-imports everywhere** -- Composables, components, and utilities are automatically available 3. **File-based conventions** -- Directories define behavior (pages/, server/, layouts/, middleware/) 4. **SSR-safe data fetching** -- Composables prevent double-fetching between server and client 5. **Zero-config TypeScript** -- Full type safety with automatic type generation 6. **Shallow reactivity for performance** -- `data` from `useFetch`/`useAsyncData` is a `shallowRef` by default

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: File-Based Routing

File names in `pages/` become URL paths. Dynamic segments use bracket syntax.

| File | URL | Description | | --------------------------- | ------------------------ | ------------------ | | `pages/index.vue` | `/` | Home page | | `pages/about.vue` | `/about` | Static route | | `pages/blog/[slug].vue` | `/blog/:slug` | Dynamic parameter | | `pages/users/[...slug].vue` | `/users/*` | Catch-all route | | `pages/posts/[[id]].vue` | `/posts` or `/posts/:id` | Optional parameter |

<!-- pages/blog/[slug].vue -->
<script setup lang="ts">
const route = useRoute();
const slug = route.params.slug as string;
const { data: post, error } = await useFetch(`/api/posts/${slug}`);

if (error.value) {
  throw createError({ statusCode: 404, statusMessage: "Post not found" });
}
</script>

**Why good:** File names map to URLs, bracket syntax for dynamic params, createError triggers error page

See [examples/core.md](examples/core.md) for complete page examples with layouts and middleware.

---

Pattern 2: Data Fetching (useFetch / useAsyncData)

`useFetch` wraps `useAsyncData` + `$fetch`. It prevents double-fetching by transferring server data to client during hydration. Data is a `shallowRef` -- replace the whole object to trigger reactivity, or use `deep: true`.

// Simple fetch -- URL is cache key
const { data, error, status, refresh, clear } = await useFetch("/api/users");

// With reactive query params and auto-refetch
const page = ref(1);
const { data: users } = await useFetch("/api/users", {
  query: { page, limit: 20 },
  watch: [page],
});

// POST with immediate: false for user-triggered actions
const { execute, status } = useFetch("/api/users", {
  method: "POST",
  body: form,
  immediate: false,
  watch: false,
});

Use `useAsyncData` when combining multiple fetches or using non-HTTP sources:

const { data } = await useAsyncData("dashboard", async () => {
  const [users, stats] = await Promise.all([
    $fetch("/api/users"),
    $fetch("/api/stats"),
  ]);
  return { users, stats };
});

**Critical:** `$fetch` in `<script setup>` (o

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked