How to Use Claude for Vue.js and Nuxt Development — Complete Guide 2026
Master Vue.js and Nuxt 4 development with Claude AI. Learn CLAUDE.md setup, Composition API prompting, SSR debugging, and workflows senior Vue devs use in 2026.
How to Use Claude for Vue.js and Nuxt Development — Complete Guide 2026
Most "Claude for frontend" tutorials assume you're writing React. If you're on Vue or Nuxt, the generic prompts you copy from those guides produce code with useEffect-shaped thinking bolted onto — technically valid, structurally wrong. Claude knows Vue's reactivity model well, but it needs to be told which Vue you're using, because the gap between Options API, Vue 2 Composition API, and Vue 3.5+ patterns is wide enough to break your build.
This guide covers the setup and prompting workflow that gets Claude producing idiomatic Composition API and Nuxt 4 code on the first try — not code you have to rewrite before it passes review.
Why Vue Developers Need a Different Claude Workflow Than React Devs
Vue's reactivity system, SFC (Single File Component) structure, and Nuxt's file-based conventions are different enough from React that generic prompting produces subtly wrong output:
- Reactivity primitives are ambiguous without context. Claude has to choose between
ref,reactive,computed, andshallowReffor any given piece of state. Without guidance, it defaults torefeverywhere, even whenreactiveor acomputedwould be more idiomatic. - Composition API vs Options API is a real fork. A huge share of Vue code online (including in Claude's training data) still uses Options API. Without an explicit instruction, you'll get inconsistent output — some components in
, others inexport default { data() {...} }. - Nuxt's auto-imports hide what Claude needs to know. Nuxt auto-imports composables, components, and utils — which means Claude can't infer your available helpers from file contents alone. It needs to be told what exists.
- SSR and hydration bugs need Vue-specific reasoning. Errors like hydration mismatches,
window is not definedduring SSR, anduseAsyncDatarace conditions require Nuxt-specific debugging patterns, not generic "fix this error" prompts.
The fix for all four is the same: give Claude explicit project context once, and it stops guessing.
Step 1 — Set Up CLAUDE.md for Your Nuxt Project
Create a CLAUDE.md file at your project root. Claude Code reads it automatically at the start of every session, so your conventions persist without you retyping them.
Here's a production-ready template for a Nuxt 4 + TypeScript project:
markdown# Project: [Your App Name]
## Stack
- Nuxt 4 (Vue 3.5+)
- TypeScript (strict mode)
- Composition API with `<script setup lang="ts">` — NEVER Options API
- Pinia for global state
- Tailwind CSS v4
- VueUse for common composables (check before writing custom ones)
- Zod for validation
## Component Conventions
- Always use `<script setup lang="ts">`, never `export default { ... }`
- Props: define with `defineProps<{ ... }>()` and TypeScript interfaces, not runtime validators
- Emits: define with `defineEmits<{ ... }>()` using the typed tuple syntax
- Reactivity: use `ref` for primitives, `reactive` only for grouped local state that's never destructured
- Computed values: always `computed()`, never derive in the template
- Component file order: script, template, style
## Nuxt-Specific Rules
- Data fetching: `useFetch` or `useAsyncData` in the component/page — NEVER `fetch()` in `onMounted`
- Server-only code goes in `server/api/`, never imported into client components
- Use auto-imports — do NOT manually import `ref`, `computed`, `useRoute`, etc.
- Environment variables: runtime config via `useRuntimeConfig()`, never `process.env` in components
- SEO: use `useSeoMeta()` on every page component
## File Conventions
- Pages: `app/pages/[route]/index.vue`
- Layouts: `app/layouts/[name].vue`
- Composables: `app/composables/use[Name].ts`
- Server routes: `server/api/[name].[method].ts`
- Pinia stores: `app/stores/[name].ts` using the setup-store syntax
## Code Standards
- TypeScript: explicit return types on all composables and functions
- No `any` — use `unknown` and narrow with type guards
- Prefer arrow functions in composables, named function declarations for components
- Loading/error states: destructure from `useAsyncData` (`pending`, `error`), don't manage manually
## CLI Commands
- Dev: `npm run dev`
- Build: `npm run build`
- Type check: `npx nuxi typecheck`
- Lint: `npm run lint`Once this file exists, Claude stops defaulting to Options API, stops manually importing auto-imported functions, and stops writing client-side fetch() calls that break SSR.
Step 2 — The Composition API Component Workflow
For new components, vague prompts ("build me a pricing card") produce generic markup. Specific prompts that name the reactive shape produce components you can merge without editing.
Weak prompt:Build a search input component for my Vue app.Build a SearchInput.vue component using our CLAUDE.md conventions.
Behavior:
- v-model support via defineModel<string>()
- Debounce input by 300ms before emitting a "search" event
- Show a loading spinner (via slot) while a `loading` prop is true
- Clear button appears when there's text, calls a `clear` event on click
- Accessible: proper aria-label, keyboard-dismissible with Escape
Use VueUse's useDebounceFn if it fits our pattern — check before
writing a custom debounce.The second prompt gives Claude everything it needs to choose the right primitives: defineModel for two-way binding, VueUse for debouncing instead of a hand-rolled setTimeout, and explicit accessibility requirements that generic prompts almost always skip.
Prompting for Pinia Stores
Pinia's setup-store syntax looks like a composable, which confuses generic AI output. Be explicit:
Create a Pinia store for cart state using the setup-store syntax
(not the options syntax). It needs:
- items: ref<CartItem[]>
- computed total (sum of price * quantity)
- addItem, removeItem, updateQuantity actions
- Persist to localStorage using VueUse's useStorage instead of
manual localStorage calls
Export as useCartStore, following our stores/ file convention.Step 3 — Debugging SSR and Hydration Issues
Nuxt's server-side rendering introduces a class of bugs that don't exist in client-only Vue apps. Generic "fix this error" prompts waste turns because Claude needs to know it's debugging an isomorphic app, not a browser-only one.
Hydration mismatch example:I'm getting a hydration mismatch warning on my Nuxt page:
"Hydration node mismatch: <div class="timestamp"> ...
Server rendered HTML: 2026-07-19T10:03:00
Client rendered HTML: 2026-07-19T10:03:04"
Here's the component: [paste component]
This is a Nuxt SSR hydration issue — explain why the server and
client are producing different output, and give me the fix using
ClientOnly or a hydration-safe pattern, not a workaround that
disables SSR for the whole page.This prompt does two things generic prompting misses: it names the bug class (hydration mismatch) so Claude reasons about server/client divergence specifically, and it constrains the fix to avoid the lazy "just wrap it in " answer when a narrower fix exists.
window is not defined during SSR:
This composable throws "window is not defined" during SSR:
[paste composable]
Fix it so it's SSR-safe — either guard with import.meta.client,
or move the browser-only logic into onMounted. Explain which
approach fits better here and why.Asking Claude to justify the choice (not just apply a fix) matters here — import.meta.client guards and onMounted deferrals solve different problems, and blindly applying one everywhere creates its own bugs (like SEO-critical content that never renders server-side).
Step 4 — Migrating Options API to Composition API
A common real-world task: modernizing a legacy Vue 2 or early Vue 3 codebase. Claude is strong at this, but only if you scope the migration carefully.
Convert this Options API component to Composition API with
<script setup lang="ts">, following our CLAUDE.md conventions.
Requirements:
- Preserve all existing behavior exactly — do not "improve" logic
beyond the syntax conversion
- Convert `data()` fields to ref/reactive as appropriate
- Convert `computed` properties to computed()
- Convert `methods` to plain functions
- Convert lifecycle hooks (mounted, beforeDestroy, etc.) to their
Composition API equivalents (onMounted, onBeforeUnmount)
- Flag any watchers that need `flush: 'post'` because they touch the DOM
Component: [paste component]Constraining Claude to "preserve behavior, don't improve" prevents scope creep — without it, Claude will often refactor logic you didn't ask it to touch, making the diff harder to review and increasing regression risk.
Common Mistakes to Avoid
Don't let Claude guess your Vue version. "Vue" spans Vue 2 Options API, Vue 2 Composition API (via@vue/composition-api), and Vue 3.5+ syntax with defineModel and reactive props destructuring. State your version explicitly in every unfamiliar-codebase session, not just in CLAUDE.md.
Don't paste template, script, and style blocks separately for small fixes. Vue's SFC structure means Claude reasons better with the whole .vue file in context — template bindings often reference script-side reactive state that's meaningless in isolation.
Don't accept auto-generated Pinia stores without checking the syntax matches your codebase. Claude sometimes defaults to the older options-style Pinia store (state, getters, actions object) even when your project uses setup stores. Call it out explicitly if it happens once, and it'll stick for the rest of the session.
Do run npx nuxi typecheck after any generated code. Nuxt's auto-imports mean type errors from missing or misnamed composables won't show up until you type-check — ESLint alone won't catch them.
Key Takeaways
- A CLAUDE.md that states Composition API, Nuxt auto-import behavior, and your file conventions eliminates most of the Options-API/manual-import noise in Claude's output
- Name the reactivity primitive you want (
ref,reactive,computed,defineModel) in prompts — Claude will otherwise default toreffor everything - SSR and hydration bugs need prompts that name the bug class explicitly, or Claude reaches for the blunt
fix instead of a targeted one - When migrating Options API to Composition API, constrain Claude to "convert syntax only" to avoid unwanted refactors bleeding into the diff
- Type-check with
nuxi typecheckafter generated code — Nuxt's auto-imports hide errors that ESLint won't catch
Next Steps — Go Deeper on Claude
Prompting Claude well for framework-specific work gets easier once you understand how it reasons about context, tool use, and code generation at a deeper level. The Claude Certified Architect (CCA) exam covers exactly this — context window management, prompt engineering patterns, and Claude's API design — the knowledge that separates developers who get generic output from those who get production-ready code every time.
AI for Anything offers the most comprehensive CCA practice test bank available, with 200+ questions covering prompt engineering, multi-agent systems, and Claude's tool use APIs.
Start practicing for the CCA exam → — Free sample questions, no account required.Want more Claude development guides? See our tutorials on Claude for React and Next.js, writing a CLAUDE.md file, and Claude Code custom slash commands.
Ready to Start Practicing?
300+ scenario-based practice questions covering all 5 CCA domains. Detailed explanations for every answer.
⚡ Get the hottest AI insights, daily
One short email a day — the AI news, tools, and how-tos that actually matter. Plus, be first to hear when the personalized 30-Day AI Mastery Challenge launches.