# Pathrule Pattern: Nuxt (1.0.0)
# ::pathrule:package:nuxt

### [RULE] Use useFetch and useAsyncData for render data, not raw $fetch  (path: /app)
<!-- scope: folder | priority: high | strict -->

Use `useFetch` and `useAsyncData` for any data that feeds the initial render. They transfer the server payload to the client and dedupe, while raw `$fetch` re-runs on hydration.

- Use `useFetch(url)` for plain endpoint calls. It keys on the URL automatically and infers types from `server/api`.
- Use `useAsyncData(key, fn)` when you wrap an SDK, combine endpoints, or shape the payload. Always pass an explicit unique `key`.
- Reserve bare `$fetch` for client-side event handlers (submit, click), never for initial data.
- Do not pass `$fetch` directly as the `useFetch` handler. It breaks caching and dedup.

---

### [RULE] Define Nitro routes with defineEventHandler, one handler per file  (path: /server)
<!-- scope: folder | priority: high | strict -->

Files in `server/api` are auto-prefixed with `/api`; files in `server/routes` map at the root. Export one `defineEventHandler` per file.

- Encode the method in the filename (`users.get.ts`, `users.post.ts`) instead of branching on `event.method`.
- Read inputs with `getQuery`, `getRouterParam`, and `await readBody(event)` from `h3`; never parse the raw request yourself.
- Throw `createError({ statusCode, statusMessage })` for failures so Nitro returns a proper error response.
- Access secrets via `useRuntimeConfig(event)`, passing `event` so env overrides apply at runtime.

---

### [MEMORY] Nuxt 4 SSR-safe and auto-import conventions  (path: /app)

Nuxt 4 renders universally by default, so component setup runs on both server and client. Guard browser-only access.

- Wrap `window`, `document`, `localStorage`, and similar in `if (import.meta.client)` or `onMounted`, which only runs on the client.
- Use `import.meta.server` / `import.meta.client` for branch logic; the legacy `process.server` / `process.client` flags are gone.
- Composables, components, and `utils`/`composables` exports are auto-imported. Do not add manual imports for them; `$fetch` is the global auto-imported alias for `ofetch`.
- In Nuxt 4 the `data` from `useFetch`/`useAsyncData` is a `shallowRef`. Replace the value to trigger reactivity rather than mutating nested fields in place.

---

### [MEMORY] Nuxt 4 directory layout and runtimeConfig  (path: /app)

Nuxt 4 moved app source under `app/` (`app/pages`, `app/components`, `app/composables`) while `server/`, `modules/`, `layers/`, and `shared/` stay at the project root.

- Put API handlers in `server/api`, shared cross-runtime helpers in `shared/`, and Vue UI under `app/`.
- Define secrets in `runtimeConfig` (server-only) and browser-safe values in `runtimeConfig.public`. Never put tokens in `public`.
- Override config at runtime with `NUXT_*` env vars (for example `NUXT_API_SECRET`, `NUXT_PUBLIC_SITE_URL`).
- Read config with `useRuntimeConfig()` in components and `useRuntimeConfig(event)` in server handlers.

---

### [SKILL] nuxt-review  (path: /)

---
name: nuxt-review
description: Review a Nuxt 4 change for correct data fetching, Nitro server routes, runtimeConfig secret handling, and SSR-safe code before merging.
---

# Nuxt 4 review

- [ ] Initial render data uses `useFetch` or `useAsyncData`, not raw `$fetch`.
- [ ] Every `useAsyncData` call passes an explicit, unique `key`.
- [ ] `$fetch` is only used in client event handlers, never for initial data.
- [ ] `lazy: true` / `server: false` choices match the data's SEO and blocking needs.
- [ ] Server handlers use `defineEventHandler` with method-suffixed filenames.
- [ ] Inputs read via `getQuery`, `getRouterParam`, `readBody`; errors via `createError`.
- [ ] Secrets live in `runtimeConfig` (server-only), never `runtimeConfig.public`.
- [ ] `useRuntimeConfig(event)` is used inside server handlers.
- [ ] Browser-only APIs are guarded with `import.meta.client` or `onMounted`.
- [ ] No manual imports added for auto-imported composables, components, or utils.
