100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
| Nuxt 4 production optimization: hydration, performance, testing with Vitest, deployment to Cloudflare/Vercel/Netlify, and v4 migration. Use when: debugging hydration mismatches, optimizing performance and Core Web Vitals, writing tests with Vitest, deploying to Cloudflare Pages/Workers/Vercel/Netlify, or migrating from Nuxt 3 to Nuxt 4.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Hydration, performance, testing, deployment, and migration patterns.
1. Abort Control for Data Fetching
const controller = ref<AbortController>()
const { data } = await useAsyncData(
'users',
() => $fetch('/api/users', { signal: controller.value?.signal })
)
const abortRequest = () => {
controller.value?.abort()
controller.value = new AbortController()
}
2. Async Data Handler Extraction
3. Enhanced Error Handling
1. Enhanced Chunk Stability
2. Lazy Hydration
<script setup>
const LazyComponent = defineLazyHydrationComponent(() =>
import('./HeavyComponent.vue')
)
</script>
| Change | v3 | v4 |
|---|---|---|
| Source directory | Root | app/ |
| Data reactivity | Deep | Shallow (default) |
| Default values | null | undefined |
| Route middleware | Client | Server |
| App manifest | Opt-in | Default |
Load references/hydration.md when:
Load references/performance.md when:
Load references/testing-vitest.md when:
Load references/deployment-cloudflare.md when:
| Cause | Example | Fix |
|---|---|---|
| Non-deterministic values | Math.random() | Use useState |
| Browser APIs on server | window.innerWidth | Use onMounted |
| Date/time on server | new Date() | Use useState or ClientOnly |
| Third-party scripts | Analytics | Use ClientOnly |
Non-deterministic Values:
<!-- WRONG -->
<script setup>
const id = Math.random()
</script>
<!-- CORRECT -->
<script setup>
const id = useState('random-id', () => Math.random())
</script>
Browser APIs:
<!-- WRONG -->
<script setup>
const width = window.innerWidth // Crashes on server!
</script>
<!-- CORRECT -->
<script setup>
const width = ref(0)
onMounted(() => {
width.value = window.innerWidth
})
</script>
ClientOnly Component:
<template>
<!-- Wrap client-only content -->
<ClientOnly>
<MyMapComponent />
<template #fallback>
<div class="skeleton">Loading map...</div>
</template>
</ClientOnly>
</template>
Conditional Rendering:
<script setup>
const showWidget = ref(false)
onMounted(() => {
// Only show after hydration
showWidget.value = true
})
</script>
<template>
<AnalyticsWidget v-if="showWidget" />
</template>
<script setup>
// Lazy load heavy components
const HeavyChart = defineAsyncComponent(() =>
import('~/components/HeavyChart.vue')
)
// With loading/error states
const HeavyChart = defineAsyncComponent({
loader: () => import('~/components/HeavyChart.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorFallback,
delay: 200,
timeout: 10000
})
</script>
<template>
<Suspense>
<HeavyChart :data="chartData" />
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
<script setup>
// Hydrate when visible in viewport
const LazyComponent = defineLazyHydrationComponent(
() => import('./HeavyComponent.vue'),
{ hydrate: 'visible' }
)
// Hydrate on user interaction
const InteractiveComponent = defineLazyHydrationComponent(
() => import('./InteractiveComponent.vue'),
{ hydrate: 'interaction' }
)
// Hydrate when browser is idle
const IdleComponent = defineLazyHydrationComponent(
() => import('./IdleComponent.vue'),
{ hydrate: 'idle' }
)
</script>
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// Static pages (prerendered at build)
'/': { prerender: true },
'/about': { prerender: true },
// SWR caching (1 hour)
'/blog/**': { swr: 3600 },
// ISR (regenerate every hour)
'/products/**': { isr: 3600 },
// SPA mode (no SSR)
'/dashboard/**': { ssr: false },
// Static with CDN caching
'/static/**': {
headers: { 'Cache-Control': 'public, max-age=31536000' }
}
}
})
<template>
<!-- Automatic optimization with NuxtImg -->
<NuxtImg
src="/images/hero.jpg"
alt="Hero image"
width="800"
height="400"
loading="lazy"
placeholder
format="webp"
/>
<!-- Responsive images -->
<NuxtPicture
src="/images/product.jpg"
alt="Product"
sizes="sm:100vw md:50vw lg:400px"
:modifiers="{ quality: 80 }"
/>
</template>
bun add -d @nuxt/test-utils vitest @vue/test-utils happy-dom
// vitest.config.ts
import { defineVitestConfig } from '@nuxt/test-utils/config'
export default defineVitestConfig({
test: {
environment: 'nuxt',
environmentOptions: {
nuxt: {
domEnvironment: 'happy-dom'
}
}
}
})
// tests/components/UserCard.test.ts
import { describe, it, expect } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
import UserCard from '~/components/UserCard.vue'
describe('UserCard', () => {
it('renders user name', async () => {
const wrapper = await mountSuspended(UserCard, {
props: {
user: { id: 1, name: 'John Doe', email: 'john@example.com' }
}
})
expect(wrapper.text()).toContain('John Doe')
expect(wrapper.text()).toContain('john@example.com')
})
it('emits delete event', async () => {
const wrapper = await mountSuspended(UserCard, {
props: { user: { id: 1, name: 'John' } }
})
await wrapper.find('[data-test="delete-btn"]').trigger('click')
expect(wrapper.emitted('delete')).toHaveLength(1)
expect(wrapper.emitted('delete')[0]).toEqual([1])
})
})
// tests/components/Dashboard.test.ts
import { describe, it, expect, vi } from 'vitest'
import { mountSuspended, mockNuxtImport } from '@nuxt/test-utils/runtime'
import Dashboard from '~/pages/dashboard.vue'
// Mock useFetch
mockNuxtImport('useFetch', () => {
return () => ({
data: ref({ users: [{ id: 1, name: 'John' }] }),
pending: ref(false),
error: ref(null)
})
})
describe('Dashboard', () => {
it('displays users from API', async () => {
const wrapper = await mountSuspended(Dashboard)
expect(wrapper.text()).toContain('John')
})
})
// tests/api/users.test.ts
import { describe, it, expect } from 'vitest'
import { $fetch, setup } from '@nuxt/test-utils/e2e'
describe('API: /api/users', async () => {
await setup({ server: true })
it('returns users list', async () => {
const users = await $fetch('/api/users')
expect(users).toHaveProperty('users')
expect(Array.isArray(users.users)).toBe(true)
})
it('creates a new user', async () => {
const result = await $fetch('/api/users', {
method: 'POST',
body: { name: 'Jane', email: 'jane@example.com' }
})
expect(result.user.name).toBe('Jane')
})
})
# Build and deploy
bun run build
bunx wrangler pages deploy .output/public
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-pages'
}
})
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'cloudflare-module'
}
})
# wrangler.toml
name = "my-nuxt-app"
compatibility_date = "2025-01-01"
compatibility_flags = ["nodejs_compat"]
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxx-xxx-xxx"
[[kv_namespaces]]
binding = "KV"
id = "xxx-xxx-xxx"
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'vercel'
}
})
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
preset: 'netlify'
}
})
bun add @nuxthub/core
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxthub/core'],
hub: {
database: true, // D1
kv: true, // KV
blob: true, // R2
cache: true // Cache API
}
})
// Usage in server routes
export default defineEventHandler(async (event) => {
const db = hubDatabase()
const kv = hubKV()
const blob = hubBlob()
// Use like regular Cloudflare bindings
const users = await db.prepare('SELECT * FROM users').all()
})
# .env (development)
API_SECRET=dev-secret
DATABASE_URL=http://localhost:8787
# Production (Cloudflare)
wrangler secret put API_SECRET
wrangler secret put DATABASE_URL
# Production (Vercel/Netlify)
# Set in dashboard or CLI
{
"devDependencies": {
"nuxt": "^4.0.0"
}
}
// nuxt.config.ts
export default defineNuxtConfig({
future: {
compatibilityVersion: 4
}
})
# Create app directory
mkdir app
# Move files
mv components app/
mv composables app/
mv pages app/
mv layouts app/
mv middleware app/
mv plugins app/
mv assets app/
mv app.vue app/
mv error.vue app/
// If mutating data.value properties:
const { data } = await useFetch('/api/user', {
deep: true // Enable deep reactivity
})
// Or replace entire value
data.value = { ...data.value, name: 'New Name' }
// v3: data.value is null
// v4: data.value is undefined
// Update null checks
if (data.value === null) // v3
if (!data.value) // v4 (works for both)
// WRONG
const width = window.innerWidth
// CORRECT
if (import.meta.client) {
const width = window.innerWidth
}
// Or use onMounted
onMounted(() => {
const width = window.innerWidth
})
// WRONG - Different on server vs client
const id = Math.random()
const time = Date.now()
// CORRECT - Use useState for consistency
const id = useState('id', () => Math.random())
const time = useState('time', () => Date.now())
<!-- WRONG -->
<AsyncComponent />
<!-- CORRECT -->
<Suspense>
<AsyncComponent />
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
Hydration Mismatch:
window, document, localStorage usageClientOnly or use onMountedMath.random(), Date.now(), crypto.randomUUID()Build Errors:
rm -rf .nuxt .output node_modules/.vite && bun install
Deployment Fails:
nitro.preset matches targetTests Failing:
@nuxt/test-utils is installedenvironment: 'nuxt'mountSuspended for async componentsVersion: 4.0.0 | Last Updated: 2025-12-28 | License: MIT
아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Implements standardized API error responses with proper status codes, logging, and user-friendly messages. Use when building production APIs, implementing error recovery patterns, or integrating error monitoring services.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.