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