Skip to content

@tank/vue-nuxt

1.0.0

Description

Vue 3 and Nuxt 3 production patterns covering script setup, composables, reactive primitives, TypeScript integration, Pinia, data fetching, middleware, plugins, rendering modes, Nitro deployment, and testing.

Triggered by

vue 3nuxt 3composablepiniauseFetchuseAsyncData
Download
Review Recommended
tank install @tank/vue-nuxt

Vue & Nuxt

Core Philosophy

  1. Composition over options -- <script setup> with Composition API is the standard for Vue 3. Prefer composables for reusable logic extraction over mixins, renderless components, or Options API.
  2. Server-first in Nuxt -- Nuxt renders on the server by default. Use useFetch/useAsyncData for data that needs SSR hydration. Reserve $fetch for client-only actions (form submissions, mutations).
  3. Type everything -- Use type-based defineProps<T>() and defineEmits<T>(). Type composable return values explicitly. Use InjectionKey<T> for provide/inject.
  4. Auto-import with intention -- Nuxt auto-imports composables, utils, and Vue APIs. Rely on it for framework APIs but use explicit imports for third-party code to keep dependency graphs visible.
  5. Reactivity is the API -- ref() for primitives, reactive() for objects you never reassign, computed() for derived state, watch() for side effects. Match the primitive to the use case.

Quick-Start: Common Problems

"How do I structure a Vue 3 component?"

  1. Use <script setup lang="ts"> -- no export default, no setup() return
  2. Define props with defineProps<{ title: string }>() (type-based)
  3. Define emits with defineEmits<{ (e: 'update', value: string): void }>()
  4. Extract reusable logic into composables/use*.ts files -> See references/composition-api.md

"useFetch vs useAsyncData vs $fetch?"

SituationUse
Page/component data with SSRuseFetch('/api/data')
Complex fetch logic with SSRuseAsyncData('key', () => $fetch(...))
Client-only mutations$fetch('/api/submit', { method: 'POST' })
Non-component context$fetch() directly

-> See references/data-fetching.md

"Setup store or option store in Pinia?"

  1. Default to setup stores -- they compose with other composables naturally
  2. Use option stores only for simple CRUD state or when migrating from Vuex
  3. Never access stores outside <script setup> or composables without useNuxtApp() -> See references/state-management.md

"Which rendering mode for each route?"

Use routeRules in nuxt.config.ts for per-route rendering:

Route PatternRuleEffect
/prerender: trueStatic at build time
/blog/**isr: 3600Regenerate every hour
/products/**swr: trueStale-while-revalidate
/admin/**ssr: falseClient-side only
/api/**cors: trueCORS headers

-> See references/rendering-deployment.md

"How do I test Vue/Nuxt components?"

  1. Use Vitest + @vue/test-utils for unit/component tests
  2. Use @nuxt/test-utils for Nuxt-aware integration tests
  3. Test composables by calling them inside a wrapper component or withSetup -> See references/testing.md

Decision Trees

Reactive Primitive Selection

Data ShapePrimitiveReason
String, number, booleanref()Simple .value access, template auto-unwraps
Object you never reassignreactive()No .value, direct property access
Derived from other statecomputed()Cached, auto-tracks dependencies
Side effect on changewatch()Explicit source, access old/new values
Side effect, auto-track depswatchEffect()No explicit source, runs immediately

Component Communication

ScenarioPattern
Parent to child dataProps (defineProps)
Child to parent eventsEmits (defineEmits)
Two-way bindingdefineModel() (Vue 3.4+)
Deep ancestor to descendantprovide() / inject() with InjectionKey
Cross-component shared statePinia store
Cross-composable coordinationComposable importing composable

Reference Index

FileContents
references/composition-api.md<script setup>, ref/reactive/computed/watch, lifecycle hooks, composable design patterns, Vue 3.4+ and 3.5+ features
references/typescript-patterns.mdType-based defineProps/Emits/Model, typed composables, InjectionKey, template ref typing, vue-tsc, generic components
references/nuxt-fundamentals.mdDirectory structure, auto-imports, plugins, layouts, middleware, runtime config, nuxt.config.ts, error handling
references/data-fetching.mduseFetch, useAsyncData, $fetch, server routes, API patterns, caching, error handling, serialization
references/state-management.mdPinia setup/option stores, store composition, persistence plugins, VueUse composables, SSR state hydration
references/rendering-deployment.mdSSR/SSG/ISR/SWR, routeRules, Nitro presets, edge rendering, SEO (useHead, useSeoMeta), performance optimization
references/testing.mdVitest setup, @vue/test-utils patterns, @nuxt/test-utils, testing composables, testing Pinia stores, MSW mocking

Command Palette

Search skills, docs, and navigate Tank