useCookie
StorageRead and write a browser cookie as React state — SSR-aware, JSON-friendly, with full cookie attribute support
Install
$ npm install @usefy/use-cookieQuick start
import { useCookie } from "@usefy/use-cookie";
function ThemeToggle() {
const [theme, setTheme, removeTheme] = useCookie("theme", {
initialValue: "light",
});
return (
<div>
<p>Current theme: {theme}</p>
<button onClick={() => setTheme("dark")}>Dark</button>
<button onClick={removeTheme}>Reset</button>
</div>
);
}API reference
useCookie<T>(key, options?)
Reads and writes the cookie named key, returning a [value, setValue, remove] tuple.
Parameters
| Parameter | Type | Description |
|---|---|---|
key | string | The cookie name |
options | UseCookieOptions<T> | Configuration (see below) |
Options
| Option | Type | Default | Description |
|---|---|---|---|
initialValue | T | (() => T) | undefined | Value when the cookie is absent (and on the server); also the reset target for remove(). Supports a lazy initializer. |
serializer | (value: T) => string | JSON.stringify | Convert the value to the stored cookie string |
deserializer | (value: string) => T | JSON-or-raw* | Parse the stored cookie string back to a value |
onError | (error: Error) => void | — | Called on a serialization/deserialization error |
expires | Date | number | — | Absolute Date, or a number of days from now. Omit for a session cookie. |
maxAge | number | — | Max-Age in seconds. Use 0/negative to expire immediately. |
path | string | "/" | Path the cookie is scoped to |
domain | string | — | Domain the cookie is scoped to (e.g. .example.com) |
secure | boolean | — | Send the cookie over HTTPS only |
sameSite | 'strict' | 'lax' | 'none' | — | SameSite policy. 'none' requires secure: true. |
* Default deserialization: the value is written with JSON.stringify and read with JSON.parse. Because cookies are very often plain, non-JSON strings (set by a server or another library), the default deserializer falls back to the raw string when JSON.parse throws — so foo=bar reads back as "bar" and never crashes, while '{"a":1}' reads back as { a: 1 }.
Returns [T | undefined, SetValue, Remove]
| Index | Type | Description |
|---|---|---|
[0] | T | undefined | Current value (undefined when absent and no initialValue) |
[1] | Dispatch<SetStateAction<T | undefined>> | Set the cookie; accepts a value or (prev) => next |
[2] | () => void | Delete the cookie and reset state to initialValue |
SSR / hydration
On the server there is no document, so useCookie returns initialValue. Like @usefy/use-local-storage, it reads through useSyncExternalStore with a server snapshot, so the first client render is consistent and there is no hydration mismatch.
Cross-tab limitation
Cookies have no storage event, so writes made in other browser tabs cannot be observed without polling — useCookie does not fake this. It does keep every useCookie(key) instance within the same document in sync via an internal subscription (mirroring @usefy/use-local-storage's same-tab store). If you need cross-tab reactivity for a cookie, poll document.cookie yourself or store the value in localStorage instead.
Go deeper
This page is the quick reference. For every example, prop, and edge case, read the full README — or open Storybook to change props live.