Programming·Updated May 10, 2026·17 min read·👁 14.0K views

Vue.js & Nuxt AI Prompts: Build Production Apps Faster in 2026

John Allick· AI Researcher
📖 2,657 words
Quick Summary

Complete AI prompt library for Vue 3 and Nuxt 4 developers. Covers Composition API, Pinia state management, Nuxt server routes, authentication, component design, testing with Vitest and Playwright, and Vercel/Netlify deployment.

#Vue.js#Nuxt#Vue 3#Composition API#Pinia#AI Coding Prompts

Vue 3 & Nuxt 4 in 2026: The Progressive Framework at Scale

Vue 3's Composition API and Nuxt 4's hybrid rendering make them a powerful pair for everything from marketing sites to complex dashboards. The key to getting great AI-generated Vue code is specifying the modern patterns: script setup, TypeScript, Pinia, and composables — not the Options API and Vuex patterns that dominate older tutorials.

AI + Vue 3: Breaking the Options API Default

The biggest quality gap in AI-generated Vue code is the Composition API vs Options API split. Most training data contains Options API code — it was the dominant Vue pattern for its first five years. Without explicit instruction, models default to it even in projects that have never used it. The practical fix is a standing session prompt: "Use <script setup> with TypeScript, defineProps<T> with generic types, Vue 3.4+ defineModel() for two-way binding, Pinia stores (not Vuex), and composables in composables/use*.ts — never Options API."

A subtler gap appears with Nuxt 4's server routes. Because Nuxt 4 is relatively new in most training datasets, models generate plausible-looking server route code using the wrong H3 event handler signatures, missing useRuntimeConfig() or incorrectly placing environment variable reads. The reliable fix: paste one working server/api/ route from your project as context before asking for a new one. The model then mirrors your established pattern instead of guessing from sparse training data.

For a cross-framework model comparison covering Vue alongside Django and GraphQL, see the Frontend & API Layer AI Prompts guide.

1. Nuxt 4 Project Architecture

⌥ PROMPT
You are a senior Nuxt 4 architect.

Design a production Nuxt 4 SaaS application structure:
- Authentication: nuxt-auth-utils with Google + GitHub providers
- Database: Drizzle ORM + PostgreSQL (Neon serverless)
- State: Pinia with pinia-plugin-persistedstate
- UI: Nuxt UI v3 (built on Tailwind CSS v4)
- Payments: Stripe with Nuxt server routes for webhooks

Deliver:
1. Full directory tree: pages/, components/, composables/, server/api/, stores/, types/
2. Which pages use SSR, SSG, or SPA mode (nuxtRouteRules per route)
3. Pinia store architecture: which stores, what they own, what they share
4. Server route security pattern: authentication middleware reused across all /api/* routes
5. nuxt.config.ts with runtime config strategy (public vs private env vars)

2. Vue 3 Components with script setup

⌥ PROMPT
You are a Vue 3 expert using the Composition API and script setup syntax.

Build a DataTable<T> generic Vue 3 component with TypeScript:

Features:
- Generic columns: ColumnDef<T> with key, label, sortable, width, renderCell slot
- Client-side sorting with visual direction indicators
- Row selection: checkbox per row, shift+click range, select-all header checkbox
- Pagination: configurable page sizes, emit page-change event for server-side support
- Slot: #actions(row) for per-row action buttons
- Loading state: skeleton rows (animated pulse)
- Empty state: default slot with override
- WCAG 2.1 AA: role="grid", aria-sort on sortable headers, keyboard navigation

Props interface with defineProps<Props>() TypeScript generic.
Emits: sort-change, page-change, selection-change.
CSS: scoped styles using Tailwind CSS utility classes.
No third-party table library dependencies.

3. Pinia Store with Optimistic Updates

⌥ PROMPT
You are a Pinia expert for Vue 3 TypeScript applications.

Build a useTaskStore (Setup store syntax) for a project management app:

State:
- tasks: Map<string, Task> (keyed by ID for O(1) lookup)
- tasksByProject: Map<string, string[]> (project ID → task IDs)
- loading: Record<string, boolean> (keyed by operation)
- error: string | null
- pagination: { page, pageSize, total, hasMore }
- filters: { status, priority, assignedTo, dueDateRange }

Actions:
- fetchTasks(projectId, filters): load paginated tasks into Map
- createTask(data): optimistic insert → API call → rollback on failure
- updateTask(id, patch): optimistic update → API call → rollback on failure
- deleteTask(id): optimistic remove → API call → restore on failure

Getters (computed):
- getTask(id): single task from Map
- projectTasks(projectId): ordered task array from tasksByProject Map
- overdueTasks: filtered derived list
- completionStats: { total, done, percentage } for current project

Persist: filters and pagination preferences only (not task data).
TypeScript throughout. Show usage in a Vue component.

4. Nuxt Server API Route with Validation

⌥ PROMPT
You are a Nuxt 4 server-side expert.

Build Nuxt server routes for the Task resource (server/api/tasks/):

Files: index.get.ts, index.post.ts, [id].get.ts, [id].patch.ts, [id].delete.ts

Every route must:
- Authenticate via requireUserSession() (nuxt-auth-utils)
- Validate input with Zod (body for POST/PATCH, query for GET, params always)
- Scope DB queries to session.user.organizationId (never trust client-sent org ID)
- Return consistent shape: { data, meta? } on success
- Use createError() for all errors: { statusCode, message, data?: { fieldErrors } }
- Log structured events: method, path, userId, tenantId, duration

index.get.ts: paginated list with filtering (status, priority, assignedTo)
index.post.ts: create task, run Drizzle insert, return created task
[id].patch.ts: partial update with optimistic concurrency (version field check)
[id].delete.ts: soft delete (set deletedAt), return 204

Show Drizzle ORM queries for each route.

5. Composables for Data Fetching

⌥ PROMPT
You are a Vue 3 composables expert.

Build a set of production composables for a Nuxt 4 app:

useApi<T>(endpoint, options):
- Wraps $fetch with: auth headers from session, base URL from runtime config
- Error normalisation: always return { data, error, loading } shape
- Retry: 3 times with exponential backoff on network errors only
- AbortController: cancel on component unmount or new call

usePaginatedTasks(projectId, filters):
- Calls useApi for paginated task list
- Cursor-based or offset pagination with has-more flag
- Auto-refetch when filters change (watchEffect)
- Merge: append new page results to existing list (infinite scroll support)
- Returns: { tasks, loading, error, hasMore, loadMore, refresh }

useOptimisticMutation<T>(mutationFn):
- Accepts: optimisticValue, onSuccess, onError callbacks
- Applies optimistic update to Pinia store immediately
- Calls mutationFn (API call)
- On success: confirm optimistic state
- On error: rollback optimistic state, show toast error

TypeScript strict. Show usage in 2 Vue components.

6. Vue Component Testing with Vitest

⌥ PROMPT
You are a Vue Testing Library + Vitest expert.

Write component tests for a TaskForm.vue component:

[PASTE COMPONENT CODE]

Requirements:
- renderWithProviders(): custom render wrapper with Pinia, Vue Router, i18n
- Test user behavior, not internals (no accessing component refs or internal state)
- Use userEvent for all interactions (typing, clicking, selecting)
- MSW (Mock Service Worker) for API calls

Test cases:
1. Renders all form fields with correct labels (accessibility query: getByLabelText)
2. Shows validation errors below each field on submit with empty form
3. Due date in past shows inline error without submit
4. Successful submit: calls API with correct payload, shows success toast, emits 'created' event
5. API error: shows error message, form remains submittable (not locked)
6. Loading state: submit button disabled and shows spinner during API call
7. Dirty form: navigate away → confirm dialog appears (useBeforeRouteLeave)
8. Keyboard: Tab through all fields in correct order, Enter submits form

vitest.config.ts setup with jsdom environment.

8. Nuxt Server Middleware for Auth

⌥ PROMPT
You are a Nuxt 4 full-stack engineer.

Implement server-side authentication middleware for a Nuxt 4 application:

Middleware: server/middleware/auth.ts (runs on every server request)
- Read JWT from Authorization header or __session cookie (cookie-first for SSR, header-first for API clients)
- Verify JWT using jose library (not jsonwebtoken — edge runtime compatible)
- On valid JWT: set event.context.user = { id, email, role, tenantId }
- On invalid/missing JWT for protected routes: throw createError({ statusCode: 401 })
- Public routes (no auth required): /api/auth/*, /api/public/*, all non-/api routes (handled by page-level auth)

Route protection in pages: definePageMeta({ middleware: 'auth' })
Nuxt route middleware: middleware/auth.ts (client-side guard that redirects to /login)
useAuth() composable:
  - user: readonly computed from useState('user')
  - isAuthenticated: computed boolean
  - login(credentials) → POST /api/auth/login, set cookie, update state
  - logout() → POST /api/auth/logout, clear cookie and state, redirect

Output: server middleware, route middleware, useAuth composable, and example protected page.

9. Nuxt Content with MDX for a Technical Blog

⌥ PROMPT
You are a Nuxt content engineer.

Set up Nuxt Content v3 for a technical blog with advanced features:

Content structure: content/blog/[slug].mdx — frontmatter: title, description, date, tags, author, draft

Features to implement:
1. Blog listing page: /blog — query all non-draft posts, sort by date, paginate 10/page with useAsyncData
2. Blog detail: /blog/[slug] — dynamic OG image generation with Satori, reading time calculation
3. MDX components: CodeBlock (syntax highlighting with Shiki, copy button, language badge), Callout (info/warning/danger variants), YouTubeEmbed
4. Search: full-text search across all blog posts using Nuxt Content's built-in search API
5. Related posts: query posts with matching tags, exclude current post, limit 3
6. RSS feed: /rss.xml server route that generates valid RSS 2.0 from all posts
7. Sitemap: auto-generate /sitemap.xml including all blog slugs

TypeScript: define CollectionSchema for blog posts with Zod validation of frontmatter

Output: nuxt.config.ts with content module setup, page components, MDX component examples, and the RSS route.

10. Vue 3 Animation with GSAP and Transitions

⌥ PROMPT
You are a Vue 3 animation engineer.

Implement smooth page transitions and component animations in a Nuxt 4 app:

Page transitions:
- Define pageTransition in nuxt.config.ts: name 'page', mode 'out-in'
- app.vue: <NuxtPage :transition="route.meta.pageTransition" />
- Fade transition: default (opacity 0 → 1, 200ms ease)
- Slide transition: dashboard pages (translateX -20px → 0, 300ms ease-out)
- Per-page override: definePageMeta({ pageTransition: { name: 'slide', mode: 'out-in' } })

GSAP animations with Vue 3 Composition API:
- useEntranceAnimation(el: Ref<HTMLElement | null>) composable: GSAP timeline that runs on onMounted, cleanup on onUnmounted
- Stagger animation for list items: gsap.from('.list-item', { opacity: 0, y: 20, stagger: 0.05 })
- ScrollTrigger for section reveals: fade-in when section enters viewport

<TransitionGroup> for dynamic lists:
- Task list reorder animation using FLIP technique (Vue's built-in move-class)
- Item add/remove with height animation (GSAP + Vue transition hooks: onEnter, onLeave)

Output: transition CSS classes, GSAP composable, and 3 example component implementations.

End-to-End Workflow: Full-Stack Nuxt Feature

Shipping a complete feature (team management with real-time presence) using chained Nuxt prompts:

  1. Server route (Prompt 4 variant): "Create GET /api/teams and POST /api/teams server routes in Nuxt 4. Validate POST body with Zod (name: string min 3, description: string optional). Use Drizzle ORM to query/insert. Scope to event.context.user.tenantId."
  2. Pinia store (Prompt 3 variant): "Create a useTeamsStore Pinia store: fetch teams from /api/teams with useAsyncData, optimistic create (push to local array before API response, rollback on failure), real-time sync via Nuxt's built-in WebSocket or useFetch polling."
  3. Component (Prompt 2 variant): "Create a TeamCard.vue component with script setup TypeScript. Props: team (typed from Drizzle schema). Display name, member avatars (max 5 with +N overflow), role badge, and a 'Manage' button. Emit 'select' with team ID."
  4. Page: "Create pages/teams/index.vue: use useTeamsStore, show skeleton while loading, empty state with create button, TeamCard grid with CSS Grid auto-fill."
  5. Tests (Prompt 6 variant): "Write Vitest component tests for TeamCard.vue: renders team name, shows correct member count overflow, emits 'select' on button click, renders empty avatar placeholder when team has no members."

Where AI Goes Wrong in Vue 3 + Nuxt

  • Options API instead of Composition API. The most common failure. AI trained on pre-2022 Vue data defaults to the Options API with data(), methods, and computed properties. Always start Vue prompts with: "Use Vue 3 script setup with TypeScript."
  • Vuex instead of Pinia. Specify Pinia explicitly — AI still reaches for Vuex for state management. They're structurally different enough that Vuex code won't migrate easily.
  • Nuxt 3 vs Nuxt 4 differences. Nuxt 4 moved to a new composable layer and changed several APIs. AI trained before Nuxt 4's release generates Nuxt 3 patterns in Nuxt 4 projects. Specify "Nuxt 4" explicitly and verify the composable signatures against the docs.
  • Missing h3 event handler syntax in server routes. Nuxt server routes use h3 under the hood. AI often generates incorrect event handler usage — wrong ways to read request body, wrong header access patterns. Always verify server route code against the h3 documentation.
  • defineModel() not used for v-model in Vue 3.4+. AI still generates the pre-3.4 emit pattern (emit 'update:modelValue'). Since Vue 3.4, defineModel() is the correct pattern. Specify "Vue 3.4+ defineModel for v-model props."

7. Good vs Bad Vue/Nuxt Prompts

Task❌ Bad Prompt✅ Good Prompt
Component"Build a task form in Vue""Build TaskForm.vue with script setup, TypeScript, Vue 3 Composition API. Use VeeValidate + Zod schema. Fields: title (required, min 3), description (optional, textarea), dueDate (future dates only), assignee (async search combobox with 300ms debounce). Emit 'submit' with typed payload. Show field-level errors."
State"Create a Pinia store""Create useTaskStore (Pinia Setup store) with TypeScript. State: Map<string,Task> for O(1) lookup. Actions: createTask with optimistic insert + rollback on API failure. Getter: overdueTasks computed from Map. Persist filter preferences only via pinia-plugin-persistedstate."
Server route"Add an API to my Nuxt app""Write server/api/tasks/index.post.ts for Nuxt 4: requireUserSession() auth, Zod body validation, Drizzle insert scoped to session.user.organizationId, createError() on validation failure, return { data: createdTask } with 201 status."

Before You Prompt: Vue 3 & Nuxt Context Setup

Vue 3's Composition API and Vue 2's Options API look completely different, and AI trained on Vue 2 tutorials produces code that compiles but misses all the ergonomic benefits of script setup. This block keeps everything in the modern Vue 3 paradigm:

⌥ PROMPT
Context for all Vue/Nuxt prompts in this session:
- Framework: Nuxt 4 (OR Vue 3 + Vite 6 SPA — specify which)
- Language: TypeScript, all components use <script setup lang="ts">
- State: Pinia 3 with setup stores (NOT Vuex, NOT Options stores)
- Nuxt: auto-imports enabled — do NOT manually import ref, computed, watch,
  or any useXxx composable from 'vue' or '#imports'
- Styling: Tailwind CSS v4

Never generate:
- Options API (no data(), methods:, computed:, mounted:)
- Vuex (store module, mapState, mapGetters)
- Vue 2 lifecycle hooks (beforeDestroy → onBeforeUnmount, destroyed → onUnmounted)
- defineComponent() wrapper (script setup is always preferred)

The auto-imports line prevents a subtle but frustrating issue: Nuxt auto-imports all Vue composables and your own composables in composables/ — if AI adds explicit imports, they're either redundant or wrong path. The "Never generate" list for Vue 2 lifecycle hook names matters because both names coexist in training data and some models use them interchangeably.

3 Common Mistakes When Prompting AI for Vue & Nuxt

Mistake 1: Getting Options API instead of Composition API

Asking for "a Vue component" produces Options API output roughly 40% of the time — data(), methods: {}, computed: {}. This code works but doesn't coexist cleanly with Composition API components and misses the type inference benefits of script setup. Always say: "<script setup lang='ts'> only — no Options API, no defineComponent wrapper." If you're seeing Options API output even with this instruction, add a short example of a <script setup> component to anchor the format.

Mistake 2: Vuex patterns in Pinia stores

AI frequently generates Pinia stores using the Options Store syntax (state: () => ({}), getters: {}, actions: {}) which looks like Vuex. The modern equivalent is the Setup Store: a function using ref(), computed(), and regular functions — exactly like script setup. Specify: "Pinia 3 Setup Store syntax — a function with ref/computed/return, not Options Store with state/getters/actions." The Setup Store has better TypeScript inference and feels more natural in a Composition API codebase.

Mistake 3: Missing Nuxt's rendering mode context

Nuxt 4 supports universal rendering (SSR + client hydration), SPA mode, and static generation. AI generates components without considering which rendering mode they run in — resulting in window/document access errors on the server, or fetch calls that run twice (once on server, once on client). For every component prompt, specify: "this runs in universal (SSR) mode — use useAsyncData or useFetch for data fetching, never fetch() directly in setup."

Further Reading

Resources for AI-assisted Vue and Nuxt development:

Generate a custom Vue/Nuxt prompt → Try PromptPrepare free

Help & Answers

Frequently Asked Questions

John AllickAI Researcher· Updated May 10, 2026

John Allick is an AI researcher specializing in prompt engineering and large language model evaluation. He benchmarks models across ChatGPT, Claude, Gemini, Grok, and DeepSeek, focusing on practical techniques that produce reliable, production-ready outputs. Every guide on PromptPrepare is tested live on current model versions before publication.

✓ Expert-tested on live models✓ Updated May 10, 2026✓ Model-verified examples

Found this helpful?

Save it to your library or share with your team.

Keep Reading

Related Guides

Apply this guide instantly

Free AI prompt generator