PluginBench
Skill
Pass
Audit score 90

nuxt4-patterns

affaan-m/everything-claude-code

Nuxt 4 patterns for SSR, hydration safety, route rules, and data fetching.

What is nuxt4-patterns?

Reference patterns for building Nuxt 4 apps with server-side rendering, hybrid rendering strategies, and client-server data synchronization. Use when debugging hydration mismatches, configuring route-level rendering rules, optimizing performance, or implementing SSR-safe data fetching.

  • Prevent hydration mismatches by keeping first renders deterministic and moving browser-only logic behind lifecycle hooks or client-only components
  • Configure route-level rendering strategies (prerender, SWR, ISR, client-only) via routeRules in nuxt.config.ts
  • Implement SSR-safe data fetching with useFetch and useAsyncData that forward server data into the Nuxt payload
  • Lazy-load non-critical components and data with Lazy prefix, useLazyFetch, and useLazyAsyncData to avoid blocking navigation
  • Optimize payload size and performance through selective data picking, lazy hydration strategies, and meaningful route boundaries

How to install nuxt4-patterns

npx skills add https://github.com/affaan-m/everything-claude-code --skill nuxt4-patterns
Claude Code
Cursor
Windsurf
Cline

How to use nuxt4-patterns

  1. 1.Identify hydration issues by comparing server HTML and client state; move browser-only logic to onMounted(), import.meta.client, or ClientOnly components
  2. 2.Replace top-level $fetch calls in pages with await useFetch() or useAsyncData() to enable server-side fetching and payload hydration
  3. 3.Define routeRules in nuxt.config.ts to set rendering strategy (prerender, swr, isr, ssr: false) per route group based on SEO and freshness needs
  4. 4.Wrap non-critical components with Lazy prefix and conditionally render with v-if to defer chunk loading until needed
  5. 5.Use lazy: true or useLazyFetch() for non-blocking data, handle status === 'pending' in UI, and trim payload with pick option

Use cases

Good for
  • Fixing hydration mismatches caused by Date.now(), Math.random(), or browser APIs in SSR-rendered templates
  • Deciding rendering strategy for different route groups: marketing pages with prerender, product catalogs with SWR, admin dashboards with client-only rendering
  • Fetching page data on the server and hydrating it on the client without duplicate requests using useFetch or useAsyncData
  • Lazy-loading below-the-fold components or non-critical interactive UI to reduce initial payload and improve navigation speed
  • Configuring cache headers and revalidation behavior for API routes and dynamic content
Who it's for
  • Nuxt 4 developers building SSR or hybrid-rendered applications
  • Full-stack engineers optimizing performance and SEO in Nuxt apps
  • Teams managing multi-strategy rendering across marketing, product, and admin sections

nuxt4-patterns FAQ

What is the difference between useFetch and useAsyncData?

useFetch is for simple $fetch() calls and automatically forwards server-fetched data into the Nuxt payload. useAsyncData is for custom fetchers, composing multiple async sources, or when you need a stable cache key. Both are SSR-safe when awaited at the top level.

How do I fix hydration mismatches?

Keep the first render deterministic by avoiding Date.now(), Math.random(), and browser APIs in SSR templates. Move browser-only logic behind onMounted(), import.meta.client, ClientOnly components, or .client.vue files so the server and client produce identical markup.

When should I use ssr: false in route rules?

Use ssr: false for truly client-only routes like admin dashboards or user-specific pages that do not need SEO. Do not use it as a default fix for hydration mismatches; instead, make the first render deterministic.

How do lazy components and lazy hydration differ?

Lazy components (Lazy prefix) defer code-splitting and loading until the component is rendered. Lazy hydration defers interactive hydration until the component is visible or idle, reducing initial hydration work while keeping the HTML in the DOM.

What is the purpose of routeRules?

routeRules in nuxt.config.ts define rendering and caching strategy per route group: prerender for static HTML, swr for background revalidation, isr for incremental regeneration, ssr: false for client-only routes, and cache for API response headers.

Full instructions (SKILL.md)

Source of truth, from affaan-m/everything-claude-code.


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. 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.
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 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.
<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