nuxt4-patterns — Claude skill: Nuxt 4 app patterns
A skill for Nuxt 4 work: hydration safety, route rules, lazy loading and SSR-safe data fetching with useFetch and useAsyncData.
npx skills add affaan-m/ECC --skill nuxt4-patterns -a claude-codeWhat nuxt4-patterns does
The skill lays out how to build and review Nuxt 4 apps. It covers hydration safety, data fetching, route rules, lazy loading and a review checklist. Your agent pulls these rules in when you build or audit a Nuxt 4 project, chase a mismatch between server HTML and client state, or pick a rendering strategy per route.
On hydration it asks for a deterministic first render. Date.now(), Math.random(), browser APIs and storage reads stay out of SSR-rendered template state; browser-only logic moves behind onMounted(), import.meta.client, ClientOnly or a .client.vue component. For data, pages and components use await useFetch(), and useAsyncData() with a stable key when the fetcher is more than a plain $fetch() call. Non-critical data goes lazy via lazy: true, useLazyFetch() or useLazyAsyncData(), with status === 'pending' handled in the UI.
Route rules live in nuxt.config.ts and are set per route group: prerender, swr, isr, ssr: false, cache or redirect. The skill is explicit that one strategy for the whole site is the wrong move. Worth installing if you run Nuxt 4 with SSR or hybrid rendering. On another version, or a purely client-rendered app, skip it.
What it helps with
- fix mismatches between server HTML and client state
- pick a rendering strategy for a route group
- move page data off top-level $fetch onto useFetch
- defer non-critical data and show a pending state
- shrink the payload and split heavy interactive islands
Example prompts for the agent
- Check my Nuxt 4 page for hydration mismatches
- Set up routeRules for /products/** and /blog/**
- Rewrite this data fetch with useAsyncData and a stable key
How to install nuxt4-patterns
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill nuxt4-patterns -a claude-code2Manually: put the files in place
~/.claude/skills/nuxt4-patterns/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/nuxt4-patterns/
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill nuxt4-patterns -a codex2Manually: put the files in place
.agents/skills/nuxt4-patterns/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill nuxt4-patterns -a cursor2Manually: put the files in place
.cursor/skills/nuxt4-patterns/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install affaan-m/ECC nuxt4-patterns2Manually: put the files in place
.github/skills/nuxt4-patterns/SKILL.md1Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill nuxt4-patterns -a gemini-cli2Platform CLI
gemini skills install https://github.com/affaan-m/ECC --path skills/nuxt4-patternsManually: put the files in place
.devin/skills/nuxt4-patterns/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add affaan-m/ECC --skill nuxt4-patterns -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
From the same set146
The whole set →Similar
Questions about nuxt4-patterns
How do I install nuxt4-patterns in Claude?
Run npx skills add affaan-m/ECC --skill nuxt4-patterns -a claude-code. The skill file lands at ~/.claude/skills/nuxt4-patterns/SKILL.md.
What does nuxt4-patterns do?
It gives your agent rules for hydration, data fetching, route rules and lazy loading in Nuxt 4, applied while writing or reviewing pages.
When does the skill activate?
On hydration mismatch debugging, useFetch and useAsyncData work, route rule setup, and lazy loading or payload size tasks.
Source text
SKILL.md · MIT
---
name: nuxt4-patterns
description: Nuxt 4 app patterns for hydration safety, performance, route rules, lazy loading, and SSR-safe data fetching with useFetch and useAsyncData. Use when building or reviewing a Nuxt 4 app, or debugging hydration mismatches and SSR-safe data fetching.
metadata:
origin: ECC
---
# Nuxt 4 Patterns
Use when building or debugging Nuxt 4 apps with SSR, hybrid rendering, route rules, or page-level data fetching.
## When to Activate
- Hydration mismatches between server HTML and client state
- Route-level rendering decisions such as prerender, SWR, ISR, or client-only sections
- Performance work around lazy loading, lazy hydration, or payload size
- Page or component data fetching with `useFetch`, `useAsyncData`, or `$fetch`
- Nuxt routing issues tied to route params, middleware, or SSR/client differences
## Hydration Safety
- Keep the first render deterministic. Do not put `Date.now()`, `Math.random()`, browser-only APIs, or storage reads directly into SSR-rendered template state.
- Move browser-only logic behind `onMounted()`, `import.meta.client`, `ClientOnly`, or a `.client.vue` component when the server cannot produce the same markup.
- Use Nuxt's `useRoute()` composable, not the one from `vue-router`.
- Do not use `route.fullPath` to drive SSR-rendered markup. URL fragments are client-only, which can create hydration mismatches.
- Treat `ssr: false` as an escape hatch for truly browser-only areas, not a default fix for mismatches.
## Data Fetching
- Prefer `await useFetch()` for SSR-safe API reads in pages and components. It forwards server-fetched data into the Nuxt payload and avoids a second fetch on hydration.
- Use `useAsyncData()` when the fetcher is not a simple `$fetch()` call, when you need a custom key, or when you are composing multiple async sources.
- Give `useAsyncData()` a stable key for cache reuse and predictable refresh behavior.
- Keep `useAsyncData()` handlers side-effect free. They can run during SSR and hydration.
- Use `$fetch()` for user-triggered writes or client-only actions, not top-level page data that should be hydrated from SSR.
- Use `lazy: true`, `useLazyFetch()`, or `useLazyAsyncData()` for non-critical data that should not block navigation. Handle `status === 'pending'` in the UI.
- Use `server: false` only for data that is not needed for SEO or the first paint.
- Trim payload size with `pick` and prefer shallower payloads when deep reactivity is unnecessary.
```ts
const route = useRoute()
const { data: article, status, error, refresh } = await useAsyncData(
() => `article:${route.params.slug}`,
() => $fetch(`/api/articles/${route.params.slug}`),
)
const { data: comments } = await useFetch(`/api/articles/${route.params.slug}/comments`, {
lazy: true,
server: false,
})
```
## Route Rules
Prefer `routeRules` in `nuxt.config.ts` for rendering and caching strategy:
```ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/products/**': { swr: 3600 },
'/blog/**': { isr: true },
'/admin/**': { ssr: false },
'/api/**': { cache: { maxAge: 60 * 60 } },
},
})
```
- `prerender`: static HTML at build time
- `swr`: serve cached content and revalidate in the background
- `isr`: incremental static regeneration on supported platforms
- `ssr: false`: client-rendered route
- `cache` or `redirect`: Nitro-level response behavior
Pick route rules per route group, not globally. Marketing pages, catalogs, dashboards, and APIs usually need different strategies.
## Lazy Loading and Performance
- Nuxt already code-splits pages by route. Keep route boundaries meaningful before micro-optimizing component splits.
- Use the `Lazy` prefix to dynamically import non-critical components.
- Conditionally render lazy components with `v-if` so the chunk is not loaded until the UI actually needs it.
- Use lazy hydration for below-the-fold or non-critical interactive UI.
```vue
<template>
<LazyRecommendations v-if="showRecommendations" />
<LazyProductGallery hydrate-on-visible />
</template>
```
- For custom strategies, use `defineLazyHydrationComponent()` with a visibility or idle strategy.
- Nuxt lazy hydration works on single-file components. Passing new props to a lazily hydrated component will trigger hydration immediately.
- Use `NuxtLink` for internal navigation so Nuxt can prefetch route components and generated payloads.
## Review Checklist
- First SSR render and hydrated client render produce the same markup
- Page data uses `useFetch` or `useAsyncData`, not top-level `$fetch`
- Non-critical data is lazy and has explicit loading UI
- Route rules match the page's SEO and freshness requirements
- Heavy interactive islands are lazy-loaded or lazily hydrated
© affaan-m · MIT · affaan-m/ECC