Cookies

Bind React state to cookies, with SSR support in Next.js app router.

useCookies binds state to a cookie. Cookies can be read by server, which makes them ideal for values that affect SSR: locale, theme, feature flags. Changes are picked up across tabs via the Cookie Store API where available.

import {  } from 'kvantjs/react'
import * as  from 'kvantjs/schema'

export function () {
  const [, ] = ('locale', .().('en'))

  return (
    < ={} ={ => (..)}>
      < ="en">English</>
      < ="de">Deutsch</>
    </>
  )
}

Setting a key to undefined removes its entry. Values equal to the schema default are never written. Defaults stay internal. Multiple hooks bound to the same key stay in sync automatically.

Key maps work too:

const [, ] = ({
  : .().('en'),
  : .(['light', 'dark']).('light'),
})

( => ({ ..., : 'dark' }))

Options

Options extend the standard Set-Cookie attributes:

Prop

Type

const [, ] = (
  'consent',
  .().(false),
  { : 60 * 60 * 24 * 365, : 'lax' },
)

Set options once for a component subtree using the options provider:

import {  } from 'kvantjs/react'

<
  ={{ : 60 * 60 * 24 * 365, : 'lax' }}
>
  {}
</>

SSR setup

On the server there is no document.cookie, so provide the request's cookies as a fallback via the options provider. In the app router, you can do it in a layout or page:

app/layout.tsx
import {  } from 'kvantjs/react'
import {  } from 'next/headers'

export default async function ({  }: { : . }) {
  const  = await ()

  return (
    <>
      <>
        <
          ={{ : .() }}
        >
          {}
        </>
      </>
    </>
  )
}

With the fallback in place, the first client render matches the server-rendered HTML, with no hydration mismatch.

On this page