A simple, yet flexible React hook for managing persistent state through browser cookies.
By leveraging browser cookies, use-cookie-state ensures that your component states remain consistent and available even after a page reload. It gracefully handles both client and server-side rendering (SSR) scenarios.
- π Persistent state: Store your React state in browser cookies.
- π Similar to
useState: Familiar API and usage, making it intuitive for React developers. - βοΈ Flexible options: Customizable cookie settings, including
maxAge,expires,domain,path,secure,httpOnly,sameSite,priority, andpartitioned. - π SSR-friendly: Falls back to
useStatebehavior whendocument.cookieis not accessible.
- πͺ use-cookie-state
Using npm:
npm install --save use-cookie-state cookieUsing pnpm:
pnpm add use-cookie-state cookieUsing yarn:
yarn add use-cookie-state cookieπ Note: The
cookiepackage is a peer dependency and must be installed alongsideuse-cookie-state.
useCookieState<T = string>(
key: string,
initialValue: T,
options?: {
decode?: (value: string) => any;
encode?: CookieSerializeOptions;
}
): [T, (value: T, encode?: CookieSerializeOptions) => void];π Parameters:
- key (string, required): Cookie name.
- initialValue (T, required): Initial state value. Can be a primitive, object, or a function returning the initial value.
- options (optional):
- decode: A function to decode the cookie value when reading it from
document.cookie. - encode: An object specifying default cookie attributes used when writing the cookie.
- decode: A function to decode the cookie value when reading it from
cookie package implementation, the decode function will be applied for each cookie value during the cookies parsing process. Be sure to use a try/catch block to avoid errors.
π Return Value:
- An array
[value, setValue]similar touseState:- value: The current state derived from the cookie.
- setValue(value: T, encode?: CookieSerializeOptions): Updates the cookie (and the state). Accepts optional runtime
encodeoptions to override defaults.
When setting or updating cookies, you can specify cookie-related attributes as encode options. These options influence how the cookie is stored and retrieved by the browser. All cookie attributes are optional.
If no encode options are provided, use-cookie-state defaults to:
{ path: "/", expires: new Date("9999") }You can override these defaults by specifying your own
encodeoptions.
- maxAge (number): Maximum age of the cookie in seconds. If both
expiresandmaxAgeare set,maxAgetakes precedence. - expires (Date): Specific date and time when the cookie should expire.
- domain (string): The domain for which the cookie is valid. Defaults to the current domain if not set.
- path (string): The path for which the cookie is valid. Defaults to
"/". - httpOnly (boolean): If
true, the cookie is not accessible to client-side JavaScript. - secure (boolean): If
true, the cookie is only sent over HTTPS connections. - sameSite (
true | "strict" | "lax" | "none"): Controls cross-site request behavior.trueor"strict": Strict same-site enforcement."lax": Lax same-site enforcement."none": No same-site restrictions.
- priority (
"low" | "medium" | "high"): Sets the cookieβs priority. - partitioned (boolean): Enables the
Partitionedattribute for the cookie (experimental).
π You can find more details about these options in the cookie package documentation: CookieSerializeOptions.
import React from "react";
import { useCookieState } from "use-cookie-state";
function MyComponent() {
const [value, setValue] = useCookieState("username", "JohnDoe");
return (
<div>
<div>Username: {value}</div>
<button onClick={() => setValue("JaneDoe")}>Change Username</button>
</div>
);
}
export default MyComponent;For objects/arrays, store as JSON and provide a decode function:
import React from "react";
import { useCookieState } from "use-cookie-state";
function jsonDecode(value) {
try {
return JSON.parse(value);
} catch {
return value;
}
}
function MyComponent() {
const [data, setData] = useCookieState("myData", { foo: "bar" }, { decode: jsonDecode });
const updateData = () => {
setData({ foo: "baz", count: 1 });
};
return (
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
<button onClick={updateData}>Update Data</button>
</div>
);
}
export default MyComponent;cookie package implementation, the decode function will be applied for each cookie value during the cookies parsing process. Be sure to use a try/catch block to avoid errors.
import React from "react";
import { useCookieState } from "use-cookie-state";
function MyComponent() {
const [value] = useCookieState("myKey", "initialVal", {
encode: {
maxAge: 60 * 60 * 24 * 7, // 1 week
secure: true,
sameSite: "strict",
httpOnly: true
}
});
return <div>Value: {value}</div>;
}
export default MyComponent;import React from "react";
import { useCookieState } from "use-cookie-state";
function MyComponent() {
const [state, setState] = useCookieState("userToken", "abc123", {
encode: { secure: true, path: "/" }
});
const updateToken = () => {
// Add domain at runtime, merging it with the default secure and path options
setState("newTokenValue", { domain: "example.com" });
};
return (
<div>
<div>Current Token: {state}</div>
<button onClick={updateToken}>Update Token</button>
</div>
);
}
export default MyComponent;On the server, document.cookie is not available. During SSR:
useCookieStateuses the providedinitialValuedirectly, just likeuseState.- No cookie operations occur until the browser environment is available.
Once hydrated, it will sync the component state with any browser cookies.
- π Keep cookie size small: Most cookies have size limits (~4KB).
- π§© Use JSON for complex data: Consider
JSON.stringifyon write and a customdecodefunction on read. - π Security considerations: Use
secure: trueif your site uses HTTPS. - π Domain and path: Control where cookies are valid with
domainandpath. - π‘οΈ SameSite attribute: Consider
sameSiteto protect against CSRF attacks or to allow cross-site requests depending on your needs.
MIT Β© dqunbp