---
name: ssr-best-practices
description: Avoiding SSR context leaks, hydration mismatches, and proper composable usage
---
# SSR Best Practices
Patterns for avoiding common SSR pitfalls: context leaks, hydration mismatches, and composable errors.
## The "Nuxt Instance Unavailable" Error
This error occurs when calling Nuxt composables outside the proper context.
### ❌ Wrong: Composable Outside Setup
```ts
// composables/bad.ts
// Called at module level - no Nuxt context!
const config = useRuntimeConfig()
export function useMyComposable() {
return config.public.apiBase
}
```
### ✅ Correct: Composable Inside Function
```ts
// composables/good.ts
export function useMyComposable() {
// Called inside the composable - has context
const config = useRuntimeConfig()
return config.public.apiBase
}
```
### Valid Contexts for Composables
Nuxt composables work in:
- `
```
### ✅ Correct: Use SSR-safe Alternatives
```vue
```
### ❌ Wrong: Random/Time-based Values
```vue
{{ Math.random() }}
{{ new Date().toLocaleTimeString() }}
```
### ✅ Correct: Use useState for Consistency
```vue
{{ randomValue }}
```
### ❌ Wrong: Conditional Rendering on Client State
```vue
Desktop
```
### ✅ Correct: Use CSS or ClientOnly
```vue
Desktop
Mobile
Loading...
```
## Browser-only Code
### Use `import.meta.client`
```vue
```
### Use `onMounted` for DOM Access
```vue
```
### Dynamic Imports for Browser Libraries
```vue
```
## Server-only Code
### Use `import.meta.server`
```vue
```
### Server Components
```vue
{{ data }}
```
## Async Composable Patterns
### ❌ Wrong: Await Before Composable
```vue
```
### ✅ Correct: Get Context First
```vue
```
## Plugin Best Practices
### Client-only Plugins
```ts
// plugins/analytics.client.ts
export default defineNuxtPlugin(() => {
// Only runs on client
initAnalytics()
})
```
### Server-only Plugins
```ts
// plugins/server-init.server.ts
export default defineNuxtPlugin(() => {
// Only runs on server
initServerConnections()
})
```
### Provide/Inject Pattern
```ts
// plugins/api.ts
export default defineNuxtPlugin(() => {
const api = createApiClient()
return {
provide: {
api,
},
}
})
```
```vue
```
## Third-party Library Integration
### ❌ Wrong: Import at Top Level
```vue
```
### ✅ Correct: Dynamic Import
```vue
```
### Use ClientOnly Component
```vue
Loading...
```
## Debugging SSR Issues
### Check Rendering Context
```vue
```
### Use Nuxt DevTools
DevTools shows payload data and hydration state.
### Common Error Messages
| Error | Cause |
|-------|-------|
| "Nuxt instance unavailable" | Composable called outside setup context |
| "Hydration mismatch" | Server/client HTML differs |
| "window is not defined" | Browser API used during SSR |
| "document is not defined" | DOM access during SSR |