feat(skills): add Nuxt 4 frontend patterns (rebased #643)#683
feat(skills): add Nuxt 4 frontend patterns (rebased #643)#683
Conversation
|
📝 WalkthroughWalkthroughAdded a new comprehensive Nuxt 4 frontend patterns skill (documentation-only) and updated project documentation counts: skills 109 → 114, commands 57 → 58. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Analysis CompleteGenerated ECC bundle from 500 commits | Confidence: 100% View Pull Request #685Repository Profile
Detected Workflows (9)
Generated Instincts (17)
After merging, import with: Files
|
Greptile SummaryThis PR adds a new Key observations:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Page Request] --> B{Route Rule?}
B -->|prerender: true| C[Static HTML\nServed from CDN]
B -->|swr: N seconds| D[SSR + Cache\nStale-While-Revalidate]
B -->|isr: N seconds| E[SSR + Cache\nIncremental Static Regen]
B -->|ssr: false| F[SPA / Client-Only\nNo SSR]
B -->|No rule| G[Full SSR\nEvery Request]
C --> H[Hydration]
D --> H
E --> H
G --> H
H --> I{Hydration Safe?}
I -->|useState / useCookie| J[✅ Same value\nServer & Client]
I -->|Math.random / Date.now\nin template| K[❌ Mismatch\nDifferent values]
I -->|Browser API in setup| L[❌ Error on Server]
J --> M[Interactive App]
K --> N[Fix: Wrap in useState]
L --> O[Fix: onMounted or\nimport.meta.client guard]
N --> M
O --> M
F --> P[Client Render Only\nNo hydration step]
P --> M
Last reviewed commit: "fix: update catalog ..." |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@README.md`:
- Around line 1073-1074: The README has inconsistent counts: update the later
"Cross-Tool Feature Parity" table so its "Commands" and "Skills" rows match the
earlier values shown (Commands: 58 and 31; Skills: 114 and 37) — locate the
pipe-table under the "Cross-Tool Feature Parity" heading and replace the
outdated numbers with 58/31 for Commands and 114/37 for Skills so both tables
are consistent.
In `@skills/nuxt-4-frontend-patterns/SKILL.md`:
- Around line 11-21: Rename the existing "## When to Activate" section to the
required "## When to Use" and move its bullet list under that heading; then add
a new "## How It Works" section summarizing the core concepts (SSR vs CSR,
hydration handling, fetch/state patterns, hybrid rendering and route rules, and
integration points like VueUse) and a new "## Examples" section containing at
least two short example use-cases (one showing handling of useFetch/useAsyncData
in SSR and one showing a route-level hybrid rendering or plugin script handling)
so the SKILL.md matches the repo convention; update headings exactly to "## When
to Use", "## How It Works", and "## Examples" in
skills/nuxt-4-frontend-patterns/SKILL.md and keep the existing "Project
Structure" section below.
- Around line 1-5: The new skill "nuxt-4-frontend-patterns" is not registered in
the install modules manifest, so add the skill folder name to the
framework-language paths list in manifests/install-modules.json; specifically,
update the array that lists skills (the same list referenced by
selective/module-based installs) to include "skills/nuxt-4-frontend-patterns" so
installers can discover it, ensuring the entry matches the existing path format
used by other skills.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3150a4c2-bc54-411e-b22a-ebe19b17a21c
📒 Files selected for processing (3)
AGENTS.mdREADME.mdskills/nuxt-4-frontend-patterns/SKILL.md
| --- | ||
| name: nuxt-4-frontend-patterns | ||
| description: Nuxt 4 frontend patterns — hydration safety, performance optimization, route rules, lazy loading, plugin best practices, data fetching, and VueUse integration for production Vue 3/Nuxt apps. | ||
| origin: ECC | ||
| --- |
There was a problem hiding this comment.
Skill is added but appears unregistered in install modules.
skills/nuxt-4-frontend-patterns is not present in manifests/install-modules.json (framework-language paths list in the provided snippet), so selective/module-based installs may never include this skill.
Suggested manifest update
--- a/manifests/install-modules.json
+++ b/manifests/install-modules.json
@@
"skills/frontend-patterns",
+ "skills/nuxt-4-frontend-patterns",
"skills/frontend-slides",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/nuxt-4-frontend-patterns/SKILL.md` around lines 1 - 5, The new skill
"nuxt-4-frontend-patterns" is not registered in the install modules manifest, so
add the skill folder name to the framework-language paths list in
manifests/install-modules.json; specifically, update the array that lists skills
(the same list referenced by selective/module-based installs) to include
"skills/nuxt-4-frontend-patterns" so installers can discover it, ensuring the
entry matches the existing path format used by other skills.
| ## When to Activate | ||
|
|
||
| - Building Nuxt 4 / Vue 3 applications | ||
| - Fixing hydration mismatch warnings | ||
| - Optimizing Core Web Vitals (LCP, CLS, INP) | ||
| - Configuring hybrid rendering or route rules | ||
| - Working with `useFetch`, `useAsyncData`, or `useState` | ||
| - Integrating VueUse composables in an SSR context | ||
| - Managing third-party scripts or plugins | ||
|
|
||
| ## Project Structure |
There was a problem hiding this comment.
Add canonical skill sections required by repo conventions.
Please include explicit ## When to Use, ## How It Works, and ## Examples headings. Current structure is close, but the required section names/shape are not fully present, which can break consistency across skills.
As per coding guidelines, “Skills should be formatted as Markdown with clear sections for When to Use, How It Works, and Examples”.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@skills/nuxt-4-frontend-patterns/SKILL.md` around lines 11 - 21, Rename the
existing "## When to Activate" section to the required "## When to Use" and move
its bullet list under that heading; then add a new "## How It Works" section
summarizing the core concepts (SSR vs CSR, hydration handling, fetch/state
patterns, hybrid rendering and route rules, and integration points like VueUse)
and a new "## Examples" section containing at least two short example use-cases
(one showing handling of useFetch/useAsyncData in SSR and one showing a
route-level hybrid rendering or plugin script handling) so the SKILL.md matches
the repo convention; update headings exactly to "## When to Use", "## How It
Works", and "## Examples" in skills/nuxt-4-frontend-patterns/SKILL.md and keep
the existing "Project Structure" section below.
There was a problem hiding this comment.
2 issues found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="skills/nuxt-4-frontend-patterns/SKILL.md">
<violation number="1" location="skills/nuxt-4-frontend-patterns/SKILL.md:365">
P2: The claim that all VueUse composables are auto-imported is incorrect; @vueuse/nuxt has documented exclusions, so this guidance can cause missing-import/runtime confusion.</violation>
<violation number="2" location="skills/nuxt-4-frontend-patterns/SKILL.md:372">
P2: The storage example is labeled SSR-safe, but it reads browser storage without `initOnMounted`, which can produce server/client state divergence during hydration.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| }) | ||
| ``` | ||
|
|
||
| All VueUse composables are auto-imported — no manual imports needed. |
There was a problem hiding this comment.
P2: The claim that all VueUse composables are auto-imported is incorrect; @vueuse/nuxt has documented exclusions, so this guidance can cause missing-import/runtime confusion.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At skills/nuxt-4-frontend-patterns/SKILL.md, line 365:
<comment>The claim that all VueUse composables are auto-imported is incorrect; @vueuse/nuxt has documented exclusions, so this guidance can cause missing-import/runtime confusion.</comment>
<file context>
@@ -0,0 +1,500 @@
+})
+```
+
+All VueUse composables are auto-imported — no manual imports needed.
+
+### SSR-Safe Storage
</file context>
| All VueUse composables are auto-imported — no manual imports needed. | |
| Most VueUse composables are auto-imported, but conflicted names (for example `useStorage`, `useFetch`, `useCookie`, and `useHead`) should be imported explicitly from `@vueuse/core` when needed. |
| const theme = useLocalStorage('theme', 'light') | ||
| const session = useSessionStorage('session-data', { loggedIn: false }) |
There was a problem hiding this comment.
P2: The storage example is labeled SSR-safe, but it reads browser storage without initOnMounted, which can produce server/client state divergence during hydration.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At skills/nuxt-4-frontend-patterns/SKILL.md, line 372:
<comment>The storage example is labeled SSR-safe, but it reads browser storage without `initOnMounted`, which can produce server/client state divergence during hydration.</comment>
<file context>
@@ -0,0 +1,500 @@
+```vue
+<script setup lang="ts">
+// Good: useLocalStorage is SSR-safe via @vueuse/nuxt
+const theme = useLocalStorage('theme', 'light')
+const session = useSessionStorage('session-data', { loggedIn: false })
+</script>
</file context>
| const theme = useLocalStorage('theme', 'light') | |
| const session = useSessionStorage('session-data', { loggedIn: false }) | |
| const theme = useLocalStorage('theme', 'light', { initOnMounted: true }) | |
| const session = useSessionStorage('session-data', { loggedIn: false }, { initOnMounted: true }) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9e01b8282f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const { load, proxy } = useScriptGoogleAnalytics({ | ||
| id: 'G-XXXXXXX', | ||
| scriptOptions: { trigger: 'manual' }, | ||
| }) |
There was a problem hiding this comment.
Document the
@nuxt/scripts prerequisite
useScriptGoogleAnalytics() is not part of Nuxt 4 core; it is provided by the separate @nuxt/scripts module. In a plain Nuxt app, copying this section verbatim will fail because the composable is undefined unless the reader has already run the Scripts module install and added it to modules. Please add that prerequisite here or switch this example to a core Nuxt API so the skill stays copy-paste safe.
Useful? React with 👍 / 👎.
| }) | ||
| ``` | ||
|
|
||
| All VueUse composables are auto-imported — no manual imports needed. |
There was a problem hiding this comment.
Narrow the VueUse auto-import claim
This sentence is broader than what @vueuse/nuxt actually does. VueUse explicitly disables auto-imports for conflict-prone utilities like useFetch, useCookie, useHead, useStorage, and useImage; telling readers that all composables are auto-imported will lead to unresolved imports or accidental use of Nuxt's similarly named composables when they expand beyond the examples in this skill.
Useful? React with 👍 / 👎.
9e01b82 to
9f86e55
Compare
Remove markdown heading prefix (##) from name field and add missing closing --- delimiter so the skill catalog parses the description correctly.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…proach for layout switching
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
9f86e55 to
50b11a0
Compare
| const { data: user } = await useAsyncData('user', () => { | ||
| return $fetch('/api/user', { | ||
| headers: useRequestHeaders(['cookie']), | ||
| }) | ||
| }) | ||
| </script> |
There was a problem hiding this comment.
useRequestHeaders called inside async callback
useRequestHeaders is a Nuxt composable and must be called synchronously in the setup scope (or in a context where the Nuxt instance is available synchronously). Calling it inside the callback passed to useAsyncData is non-standard — the official Nuxt docs consistently show it captured before the useAsyncData call. Inside the async callback, Nuxt's composable context may not be guaranteed, especially on client-side re-fetches triggered by refreshNuxtData or navigation.
Capture the headers outside the handler to match the documented pattern:
| const { data: user } = await useAsyncData('user', () => { | |
| return $fetch('/api/user', { | |
| headers: useRequestHeaders(['cookie']), | |
| }) | |
| }) | |
| </script> | |
| const headers = useRequestHeaders(['cookie']) | |
| const { data: user } = await useAsyncData('user', () => { | |
| return $fetch('/api/user', { | |
| headers, | |
| }) | |
| }) |
| ### Image Optimization with NuxtImg | ||
|
|
||
| ```vue | ||
| <template> | ||
| <!-- High priority: hero/LCP image --> | ||
| <NuxtImg | ||
| src="/hero.jpg" | ||
| format="webp" | ||
| :preload="{ fetchPriority: 'high' }" | ||
| loading="eager" | ||
| width="1200" | ||
| height="600" | ||
| /> | ||
|
|
||
| <!-- Low priority: below the fold --> | ||
| <NuxtImg | ||
| src="/thumbnail.jpg" | ||
| format="webp" | ||
| loading="lazy" | ||
| fetchpriority="low" | ||
| width="300" | ||
| height="200" | ||
| /> | ||
| </template> | ||
| ``` |
There was a problem hiding this comment.
NuxtImg requires unlisted @nuxt/image module
<NuxtImg> is not part of Nuxt core — it is provided by the @nuxt/image module. A developer copying these examples without that module installed will get a "Unknown custom element: <NuxtImg>" warning and the images will not render correctly. This is the same class of issue as the already-noted useScriptGoogleAnalytics / @nuxtjs/scripts dependency.
Consider adding a setup note before this section:
> Requires `@nuxt/image`: `npx nuxt@latest module add image`|
Will re-apply on fresh branch |
Summary
nuxt-4-frontend-patternsskill with comprehensive Nuxt 4 development patternsOriginal PR
Closes #643
Test plan
Summary by cubic
Adds the
nuxt-4-frontend-patternsskill with production Nuxt 4 patterns for SSR safety, performance, and data fetching. Also fixes SKILL parsing and example issues, and syncs catalog counts.New Features
useState,useCookie), browser-only guards,ClientOnly.prerender,swr,isr,ssr: false), lazy components/hydration,NuxtLinkprefetch,NuxtImgoptimization.useFetch/useAsyncDatawith header forwarding and error states; plugin best practices with parallel loading;@vueuse/nuxtpatterns (storage, breakpoints withssrWidth, dark mode, intersection observer, debounced search, shortcuts).Bug Fixes
name, add closing---) so catalog parses; convert pitfalls to bullet points.useFetchplacement, completeuseScriptmanual trigger, fix keyboard shortcuts runtime error and item types; update responsive guidance to prefer CSS-first.AGENTS.mdandREADME.md(27 agents, 114 skills, 58 commands).Written for commit 50b11a0. Summary will update on new commits.
Summary by CodeRabbit