affaan-m/ECC/skills/nuxt4-patterns/SKILL.md
nuxt4-patterns
Nuxt 4 app patterns for hydration safety, performance, route rules, lazy loading, and SSR-safe data fetching with useFetch and useAsyncData.
- Source repository stars
- 234,327
- Declared platforms
- 0
- Static risk flags
- 1
- Last source update
- 2026-07-27
- Source checked
- 2026-07-28
Decision brief
What it does—and where it fits
Use when building or debugging Nuxt 4 apps with SSR, hybrid rendering, route rules, or page-level data fetching.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/affaan-m/ECC --skill "skills/nuxt4-patterns"Inspect the Agent Skill "nuxt4-patterns" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/skills/nuxt4-patterns/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Review Checklist
First SSR render and hydrated client render produce the same markup
First SSR render and hydrated client render produce the same markupPage data uses useFetch or useAsyncData, not top-level $fetchNon-critical data is lazy and has explicit loading UI - 02
When to Activate
Hydration mismatches between server HTML and client state
Hydration mismatches between server HTML and client stateRoute-level rendering decisions such as prerender, SWR, ISR, or client-only sectionsPerformance work around lazy loading, lazy hydration, or payload size - 03
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.
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. - 04
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.
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. - 05
Route Rules
Prefer routeRules in nuxt.config.ts for rendering and caching strategy:
prerender: static HTML at build timeswr: serve cached content and revalidate in the backgroundisr: incremental static regeneration on supported platforms
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
() => $fetch(`/api/articles/${route.params.slug}`),Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 74/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 234,327 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- affaan-m/ECC
- Skill path
- skills/nuxt4-patterns/SKILL.md
- Commit
- 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
- License
- MIT
- Collected
- 2026-07-28
- Default branch
- main
View the original SKILL.md
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.vuecomponent when the server cannot produce the same markup. - Use Nuxt's
useRoute()composable, not the one fromvue-router. - Do not use
route.fullPathto drive SSR-rendered markup. URL fragments are client-only, which can create hydration mismatches. - Treat
ssr: falseas 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(), oruseLazyAsyncData()for non-critical data that should not block navigation. Handlestatus === 'pending'in the UI. - Use
server: falseonly for data that is not needed for SEO or the first paint. - Trim payload size with
pickand prefer shallower payloads when deep reactivity is unnecessary.
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:
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 timeswr: serve cached content and revalidate in the backgroundisr: incremental static regeneration on supported platformsssr: false: client-rendered routecacheorredirect: 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
Lazyprefix to dynamically import non-critical components. - Conditionally render lazy components with
v-ifso the chunk is not loaded until the UI actually needs it. - Use lazy hydration for below-the-fold or non-critical interactive UI.
<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
NuxtLinkfor 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
useFetchoruseAsyncData, 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
Alternatives