From b77f49569b5800f081cc596273892797c693542e Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Fri, 20 Mar 2026 04:44:31 -0700 Subject: [PATCH] feat: add nuxt 4 patterns skill (#702) --- AGENTS.md | 4 +- README.md | 4 +- skills/nuxt4-patterns/SKILL.md | 100 +++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 skills/nuxt4-patterns/SKILL.md diff --git a/AGENTS.md b/AGENTS.md index 0039c62f..62fd86b1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Everything Claude Code (ECC) — Agent Instructions -This is a **production-ready AI coding plugin** providing 27 specialized agents, 114 skills, 59 commands, and automated hook workflows for software development. +This is a **production-ready AI coding plugin** providing 27 specialized agents, 115 skills, 59 commands, and automated hook workflows for software development. **Version:** 1.9.0 @@ -142,7 +142,7 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat ``` agents/ — 27 specialized subagents -skills/ — 114 workflow skills and domain knowledge +skills/ — 115 workflow skills and domain knowledge commands/ — 59 slash commands hooks/ — Trigger-based automations rules/ — Always-follow guidelines (common + per-language) diff --git a/README.md b/README.md index 14853eb3..736e1227 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ For manual install instructions see the README in the `rules/` folder. /plugin list everything-claude-code@everything-claude-code ``` -✨ **That's it!** You now have access to 27 agents, 114 skills, and 59 commands. +✨ **That's it!** You now have access to 27 agents, 115 skills, and 59 commands. --- @@ -1071,7 +1071,7 @@ The configuration is automatically detected from `.opencode/opencode.json`. |---------|-------------|----------|--------| | Agents | ✅ 27 agents | ✅ 12 agents | **Claude Code leads** | | Commands | ✅ 59 commands | ✅ 31 commands | **Claude Code leads** | -| Skills | ✅ 114 skills | ✅ 37 skills | **Claude Code leads** | +| Skills | ✅ 115 skills | ✅ 37 skills | **Claude Code leads** | | Hooks | ✅ 8 event types | ✅ 11 events | **OpenCode has more!** | | Rules | ✅ 29 rules | ✅ 13 instructions | **Claude Code leads** | | MCP Servers | ✅ 14 servers | ✅ Full | **Full parity** | diff --git a/skills/nuxt4-patterns/SKILL.md b/skills/nuxt4-patterns/SKILL.md new file mode 100644 index 00000000..3e7a0b8e --- /dev/null +++ b/skills/nuxt4-patterns/SKILL.md @@ -0,0 +1,100 @@ +--- +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. +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 + +``` + +- 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