Skip to main content ホーム クリエイター secondsky claude-skills nuxt-data
nuxt-data | Nuxt 4 data management: composables, data fetching with useFetch/useAsyncData, and state management with useState and Pinia. Use when: creating custom composables, fetching data with useFetch or useAsyncData, managing global state with useState, integrating Pinia, debugging reactive data issues, or implementing SSR-safe state patterns.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/secondsky/claude-skills --skill nuxt-dataコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... name nuxt-data description | Nuxt 4 data management: composables, data fetching with useFetch/useAsyncData, and state management with useState and Pinia. Use when: creating custom composables, fetching data with useFetch or useAsyncData, managing global state with useState, integrating Pinia, debugging reactive data issues, or implementing SSR-safe state patterns. license MIT metadata {"version":"4.0.0","author":"Claude Skills Maintainers","category":"Framework","framework":"Nuxt","framework-version":"4.x","last-verified":"2025-12-28T00:00:00.000Z","keywords":["useFetch","useAsyncData","$fetch","useState","composables","Pinia","data fetching","state management","reactive","shallow reactivity","reactive keys","transform","pending","error","refresh","dedupe","caching"]}
Nuxt 4 Data Management
Composables, data fetching, and state management patterns for Nuxt 4 applications.
Quick Reference
Data Fetching Methods
Method Use Case SSR Caching Reactive useFetchSimple API calls Yes Yes Yes useAsyncDataCustom async logic Yes Yes Yes $fetchClient-side only, events
Composable Naming Prefix Purpose Example useState/logic composable useAuth, useCartfetchData fetching only fetchUsers (rare)
When to Load References Load references/composables.md when:
Writing custom composables with complex state
Debugging state management issues or memory leaks
Implementing SSR-safe patterns with browser APIs
Building authentication or complex state composables
Understanding singleton vs per-call composable patterns
Load references/data-fetching.md when:
Implementing API data fetching with reactive parameters
Troubleshooting shallow vs deep reactivity issues
Debugging data not refreshing when params change
Implementing pagination, infinite scroll, or search
Understanding transform functions, caching, or error handling
Load references/pinia-integration.md when:
Setting up Pinia for complex state management
Creating stores with getters and actions
Integrating Pinia with SSR
Persisting state across page reloads
Composables
useState - The Foundation useState creates SSR-safe, shared reactive state that persists across component instances.
export const useCounter = ( ) => {
const count = useState ('counter' , () => 0 )
const increment = ( ) => count.value ++
const decrement = ( ) => count.value --
const reset = ( ) => count.value = 0
return { count, increment, decrement, reset }
}
useState vs ref - Critical Distinction
export const useAuth = ( ) => {
const user = useState ('auth-user' , () => null )
return { user }
}
export const useAuth = ( ) => {
const user = ref (null )
return { user }
}
Rule : Use useState for shared/global state. Use ref for local component state only.
Complete Authentication Composable
export const useAuth = ( ) => {
const user = useState<User | null >('auth-user' , () => null )
const isAuthenticated = computed (() => !!user.value )
const isLoading = useState ('auth-loading' , () => false )
const login = async (email : string , password : string ) => {
isLoading.value = true
try {
const data = await $fetch('/api/auth/login' , {
method : 'POST' ,
body : { email, password }
})
user.value = data.user
return { success : true }
} catch (error) {
return { success : false , error : error.message }
} finally {
isLoading.value = false
}
}
const logout = async ( ) => {
await $fetch('/api/auth/logout' , { method : 'POST' })
user.value = null
navigateTo ('/login' )
}
const checkSession = async ( ) => {
if (import .meta .server ) return
try {
const data = await $fetch('/api/auth/session' )
user.value = data.user
} catch {
user.value = null
}
}
return { user, isAuthenticated, isLoading, login, logout, checkSession }
}
SSR-Safe Browser APIs
export const useLocalStorage = <T>(key : string , defaultValue : T ) => {
const data = useState<T>(key, () => defaultValue)
if (import .meta .client ) {
const stored = localStorage .getItem (key)
if (stored) {
data.value = JSON .parse (stored)
}
watch (data, (newValue ) => {
localStorage .setItem (key, JSON .stringify (newValue))
}, { deep : true })
}
return data
}
Data Fetching
useFetch - Basic Usage
const { data, error, pending, refresh } = await useFetch ('/api/users' )
const { data : users } = await useFetch ('/api/users' , {
method : 'GET' ,
query : { limit : 10 , offset : 0 },
headers : { 'X-Custom-Header' : 'value' }
})
Reactive Parameters <script setup lang="ts">
const page = ref(1)
const search = ref('')
// Auto-refetches when page or search changes
const { data: users, pending } = await useFetch('/api/users', {
query: {
page,
search,
limit: 10
}
})
// Or with computed
const query = computed(() => ({
page: page.value,
search: search.value,
limit: 10
}))
const { data } = await useFetch('/api/users', { query })
</script>
Transform Data const { data : userNames } = await useFetch ('/api/users' , {
transform : (users ) => users.map (u => u.name )
})
Pick Specific Fields const { data } = await useFetch ('/api/user' , {
pick : ['id' , 'name' , 'email' ]
})
useAsyncData - Custom Logic
const { data } = await useAsyncData ('dashboard' , async () => {
const [users, posts, stats] = await Promise .all ([
$fetch('/api/users' ),
$fetch('/api/posts' ),
$fetch('/api/stats' )
])
return { users, posts, stats }
})
Error Handling const { data, error, status } = await useFetch ('/api/users' )
if (error.value ) {
console .error ('Error:' , error.value .message )
console .error ('Status:' , error.value .statusCode )
}
if (status.value === 'error' ) {
showError (error.value )
}
Manual Refresh const { data, refresh, execute } = await useFetch ('/api/users' , {
immediate : false
})
await execute ()
await refresh ()
await refresh ({ dedupe : true })
Shallow vs Deep Reactivity (v4 Change)
const { data } = await useFetch ('/api/user' )
data.value .name = 'New Name'
const { data } = await useFetch ('/api/user' , {
deep : true
})
data.value .name = 'New Name'
const { data, refresh } = await useFetch ('/api/user' )
await $fetch('/api/user' , { method : 'PATCH' , body : { name : 'New Name' } })
await refresh ()
Caching and Deduplication const { data } = await useFetch ('/api/users' , {
key : 'users-list' ,
dedupe : 'cancel' ,
getCachedData : (key, nuxtApp ) => {
return nuxtApp.payload .data [key]
}
})
Lazy Loading Data
const { data, pending } = useLazyFetch ('/api/users' )
const { data, pending } = useLazyAsyncData ('users' , () => $fetch('/api/users' ))
$fetch - Client-Side Only
const submitForm = async ( ) => {
const result = await $fetch('/api/submit' , {
method : 'POST' ,
body : formData.value
})
}
export default defineEventHandler (async (event) => {
const externalData = await $fetch('https://api.example.com/data' )
return externalData
})
State Management
useState Patterns
const count = useState ('count' , () => 0 )
const settings = useState ('settings' , () => ({
theme : 'light' ,
notifications : true ,
language : 'en'
}))
interface User {
id : string
name : string
email : string
}
const user = useState<User | null >('user' , () => null )
Shared Cart Example
interface CartItem {
id : string
name : string
price : number
quantity : number
}
export const useCart = ( ) => {
const items = useState<CartItem []>('cart-items' , () => [])
const total = computed (() =>
items.value .reduce ((sum, item ) => sum + item.price * item.quantity , 0 )
)
const itemCount = computed (() =>
items.value .reduce ((sum, item ) => sum + item.quantity , 0 )
)
const addItem = (product : Omit <CartItem , 'quantity' > ) => {
const existing = items.value .find (i => i.id === product.id )
if (existing) {
existing.quantity ++
} else {
items.value .push ({ ...product, quantity : 1 })
}
}
const removeItem = (id : string ) => {
items.value = items.value .filter (i => i.id !== id)
}
const updateQuantity = (id : string , quantity : number ) => {
const item = items.value .find (i => i.id === id)
if (item) {
item.quantity = Math .max (0 , quantity)
if (item.quantity === 0 ) removeItem (id)
}
}
const clearCart = ( ) => {
items.value = []
}
return { items, total, itemCount, addItem, removeItem, updateQuantity, clearCart }
}
Pinia Integration bun add pinia @pinia/nuxt
export default defineNuxtConfig ({
modules : ['@pinia/nuxt' ]
})
import { defineStore } from 'pinia'
export const useAuthStore = defineStore ('auth' , {
state : () => ({
user : null as User | null ,
token : null as string | null
}),
getters : {
isAuthenticated : (state ) => !!state.user ,
userName : (state ) => state.user ?.name ?? 'Guest'
},
actions : {
async login (email : string , password : string ) {
const { user, token } = await $fetch('/api/auth/login' , {
method : 'POST' ,
body : { email, password }
})
this .user = user
this .token = token
},
logout ( ) {
this .user = null
this .token = null
}
}
})
const authStore = useAuthStore ()
await authStore.login ('user@example.com' , 'password' )
console .log (authStore.userName )
Common Anti-Patterns
Using ref Instead of useState
export const useAuth = ( ) => {
const user = ref (null )
return { user }
}
export const useAuth = ( ) => {
const user = useState ('auth-user' , () => null )
return { user }
}
Missing Error Handling
const { data } = await useFetch ('/api/users' )
console .log (data.value .length )
const { data, error } = await useFetch ('/api/users' )
if (error.value ) {
showToast ({ type : 'error' , message : error.value .message })
return
}
console .log (data.value .length )
Non-Deterministic Transform
const { data } = await useFetch ('/api/users' , {
transform : (users ) => users.sort (() => Math .random () - 0.5 )
})
const { data } = await useFetch ('/api/users' , {
transform : (users ) => users.sort ((a, b ) => a.name .localeCompare (b.name ))
})
Mutating Shallow Refs
const { data } = await useFetch ('/api/user' )
data.value .name = 'New Name'
const { data } = await useFetch ('/api/user' , { deep : true })
data.value .name = 'New Name'
data.value = { ...data.value , name : 'New Name' }
await $fetch('/api/user' , { method : 'PATCH' , body : { name : 'New Name' } })
await refresh ()
Troubleshooting Data Not Refreshing When Params Change:
Ensure params are reactive: { query: { page } } where page = ref(1)
Check you're using the ref itself, not .value
Hydration Mismatch with useState:
Ensure key is unique: useState('unique-key', () => value)
Avoid Math.random() or Date.now() in initial values
State Lost on Navigation:
Use useState instead of ref for persistent state
Check you're using the same key across components
Check for reactive dependencies in transform function
Use watch with { immediate: false } for side effects
Related Skills
nuxt-core : Project setup, routing, configuration
nuxt-server : Server routes, API patterns
nuxt-production : Performance, testing, deployment
Version : 4.0.0 | Last Updated : 2025-12-28 | License : MIT