Ensure Vue composables, reactive state, and side effects are properly scoped within Vue's execution context to prevent SSR failures, memory leaks, and shared state across requests.
Ensure Vue composables, reactive state, and side effects are properly scoped within Vue’s execution context to prevent SSR failures, memory leaks, and shared state across requests.
Key Rules:
<script setup>
, setup()
functions, or Vue lifecycle hooks where Nuxt context is availableonMounted
since unmount hooks don’t run during SSRExamples:
❌ Incorrect - Top-level composable usage:
// utils/api.ts
const { session } = useUserSession() // Fails on server - no Nuxt context
export default defineNuxtPlugin((nuxtApp) => {
// composable called outside proper context
})
❌ Incorrect - Root scope side effects:
<script setup>
// Timer in root scope - never cleaned up during SSR
const timer = setInterval(() => {}, 1000)
// Shared state across requests
export const myState = ref({})
</script>
✅ Correct - Proper context usage:
// utils/api.ts
export default defineNuxtPlugin((nuxtApp) => {
const { session } = useUserSession() // Called within plugin context
})
✅ Correct - Side effects in lifecycle hooks:
<script setup>
// Move side effects to mounted hook
onMounted(() => {
const timer = setInterval(() => {}, 1000)
onBeforeUnmount(() => {
clearInterval(timer)
})
})
// Use useState for proper SSR-safe state
const myState = useState('key', () => ({}))
</script>
This prevents SSR hydration mismatches, memory leaks, and ensures proper cleanup of resources across the Vue component lifecycle.
Enter the URL of a public GitHub repository