What Causes This Warning?
This warning appears when you try to use server-side response utilities (like setResponseHeaders, setHeader, or setCookie) in client-side code. These functions only work during server-side rendering.
The Problem
<script setup>
// ❌ Wrong - these don't work on client
setResponseHeader('X-Custom-Header', 'value')
setResponseStatus(404)
setCookie(event, 'name', 'value') // Wrong context
</script>
The Fix
Check for Server Context
<script setup>
// ✅ Correct - only run on server
if (process.server) {
const event = useRequestEvent()
if (event) {
setResponseHeader(event, 'X-Custom-Header', 'value')
}
}
</script>
Use Server Middleware
// server/middleware/headers.ts
export default defineEventHandler((event) => {
// ✅ Always server-side
setResponseHeader(event, 'X-Custom-Header', 'value')
setResponseHeader(event, 'X-Frame-Options', 'DENY')
})
Common Scenarios
Setting Cache Headers
<script setup>
// ❌ Wrong - won't work on client navigation
setResponseHeader('Cache-Control', 'max-age=3600')
</script>
Solution - Use Route Rules:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/products/**': {
headers: {
'Cache-Control': 'max-age=3600'
}
}
}
})
Custom Response Status
<script setup>
// ❌ Wrong - status codes don't apply on client
const { data, error } = await useFetch('/api/data')
if (error.value) {
setResponseStatus(404) // Warning on client!
}
</script>
Solution:
<script setup>
const { data, error } = await useFetch('/api/data')
// ✅ Set status only on server
if (process.server && error.value) {
const event = useRequestEvent()
if (event) {
setResponseStatus(event, 404)
}
}
// Handle client-side differently
if (process.client && error.value) {
// Redirect or show error UI
navigateTo('/404')
}
</script>
Setting Cookies
<script setup>
// ❌ Wrong - using H3 cookie function on client
setCookie(event, 'theme', 'dark')
</script>
Solution:
<script setup>
// ✅ Use useCookie which works on both server and client
const theme = useCookie('theme')
theme.value = 'dark'
</script>
Security Headers
<script setup>
// ❌ Wrong - security headers must be set server-side
setResponseHeaders({
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY'
})
</script>
Solution - Server Middleware:
// server/middleware/security.ts
export default defineEventHandler((event) => {
// ✅ Security headers set on every request
setResponseHeaders(event, {
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block',
'Referrer-Policy': 'strict-origin-when-cross-origin'
})
})
Or in Nitro Config:
// nuxt.config.ts
export default defineNuxtConfig({
nitro: {
routeRules: {
'/**': {
headers: {
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY'
}
}
}
}
})
Understanding SSR Context
Server-Only Functions
These only work during SSR:
// Only work on server
setResponseHeader(event, 'name', 'value')
setResponseHeaders(event, { ... })
setResponseStatus(event, 200)
appendResponseHeader(event, 'name', 'value')
removeResponseHeader(event, 'name')
// Getting request info (server-only)
getRequestHeaders(event)
getRequestHeader(event, 'name')
getCookie(event, 'name')
Universal Functions
These work on both server and client:
// useCookie works everywhere
const cookie = useCookie('name')
cookie.value = 'value'
// useRequestHeaders gets headers on server, empty on client
const headers = useRequestHeaders()
// useRequestURL works everywhere
const url = useRequestURL()
Proper Patterns
Conditional Server Code
<script setup>
// ✅ Check environment before using server functions
if (process.server) {
const event = useRequestEvent()
if (event) {
// Safe to use server functions
setResponseHeader(event, 'X-Custom', 'value')
}
}
</script>
Server Composable
// composables/useServerHeaders.ts
export function useServerHeaders(headers: Record<string, string>) {
if (process.server) {
const event = useRequestEvent()
if (event) {
setResponseHeaders(event, headers)
}
}
}
<script setup>
// ✅ Clean usage
useServerHeaders({
'Cache-Control': 'max-age=3600',
'X-Custom': 'value'
})
</script>
Route-Specific Headers
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// Static assets
'/assets/**': {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable'
}
},
// API routes
'/api/**': {
headers: {
'Cache-Control': 'no-store'
}
},
// HTML pages
'/**': {
headers: {
'Cache-Control': 's-maxage=3600, stale-while-revalidate'
}
}
}
})
Quick Checklist
- Response header functions are only called on server
- Use
process.serverguard before server-only code - Use
useCookie()instead ofsetCookie()in components - Use route rules for static header configuration
- Use server middleware for dynamic headers
- Check
useRequestEvent()returns a value before using