useCookie & Cookies on the Server

Read/Write Cookies on Both Sides

useCookie & Cookies on the Server

useCookie gives you a typed, reactive cookie binding on the client; getCookie, setCookie, and deleteCookie handle cookies on the server side.

4 min read Level 2/5 #nuxt#cookies
What you'll learn
  • Read and write cookies on the client with useCookie
  • Read cookies on the server with getCookie
  • Set httpOnly and secure flags when storing sensitive data

Cookies are the universal currency of state on the web. Nuxt gives you matching tools on both sides of the wire — useCookie for components, h3 helpers for handlers.

Client: useCookie

useCookie returns a reactive ref bound to a cookie:

<script setup lang="ts">
const theme = useCookie<'light' | 'dark'>('theme', {
  default: () => 'light',
  sameSite: 'lax',
  maxAge: 60 * 60 * 24 * 365,
})

function toggle() {
  theme.value = theme.value === 'light' ? 'dark' : 'light'
}
</script>

<template>
  <button @click="toggle">Theme: {{ theme }}</button>
</template>

Setting theme.value writes the cookie. Reading it gets the parsed value. Works during SSR too — the server reads from request headers, the client reads from document.cookie.

Server: h3 Helpers

In server routes and middleware, use the explicit helpers:

// server/api/session.get.ts
export default defineEventHandler((event) => {
  const token = getCookie(event, 'token')
  if (!token) {
    throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })
  }
  return { token }
})
// server/api/logout.post.ts
export default defineEventHandler((event) => {
  deleteCookie(event, 'token')
  return { ok: true }
})

Sensitive Data: httpOnly + secure

For session tokens, never expose the cookie to JavaScript. Set httpOnly (so JS can’t read it) and secure (so it only travels over HTTPS):

setCookie(event, 'token', jwt, {
  httpOnly: true,
  secure: true,
  sameSite: 'lax',
  path: '/',
  maxAge: 60 * 60, // 1 hour
})

httpOnly cookies are still sent on requests, so the server can still verify them — they just can’t be read by document.cookie.

Pitfalls

  • useCookie can’t read httpOnly cookies — the browser hides them from JS by design.
  • Setting secure: true breaks cookies on localhost over HTTP. Either accept this or use a dev proxy with HTTPS.
  • Cookies have a 4KB total limit per domain. Don’t shove session blobs in them — store a key, look up the data server-side.
JWT Auth With Nitro →