Skip to main content

useCookie Deep Dive

The useCookie hook manages browser cookies reactively. It is particularly useful for data that needs to be sent to the server with every request, such as authentication tokens, language preferences, or currency settings.


Core Concepts

The hook provides a reactive interface for cookie management, returning a consistent tuple for accessing and modifying values.

import { useCookie } from '@archibald/server';

function CurrencySelector() {
const [currency, setCurrency, clearCurrency] = useCookie('app-currency');

return (
<select value={currency} onChange={(e) => setCurrency(e.target.value)}>
<option value="EUR">EUR</option>
<option value="USD">USD</option>
</select>
);
}

Reactivity & Synchronization

Unlike direct document.cookie access, useCookie is reactive across your entire application.

  • Internal Subscriber Map: Archibald uses a CookieHelper that maintains a registry of subscribers. When you call set or clear in one component, all other components using the same cookie name are notified and re-render automatically.
  • Focus Tracking: Cookies can sometimes be modified by external scripts or the browser's DevTools. To handle this, useCookie can optionally re-verify its value whenever the window regains focus (see updateOnRefocus option), ensuring the UI stays in sync with the actual storage.

SSR & Server-Side Access

One of the primary advantages of cookies over localStorage is their visibility to the server.

  • Isomorphic Access: During Server-Side Rendering (SSR), useCookie can retrieve values directly from the request headers. This allows you to personalize the initial HTML response based on the user's cookie-stored preferences.
  • Safe Hydration: The hook ensures that the value read on the server matches the value initialized on the client, avoiding common hydration flickering issues.

How it Works Step-by-Step

  1. Subscription: The hook registers a listener with the global CookieHelper for the specific cookie name.
  2. Initial Value: It reads the cookie value from the request headers (on server) or document.cookie (on client).
  3. State Synchronization: It uses useSyncExternalStore to ensure the component re-renders whenever the cookie value is changed by any part of the application.
  4. Modification:
    • Calling set(value, options) updates the browser cookie and notifies all other hook instances.
    • Calling clear(options) removes the cookie and triggers a reactive update.
  5. Focus Events: If enabled, the hook listens for window.focus to perform a "lazy synchronization" check, updating the state if an external source modified the cookie while the tab was blurred.

Best Practice: Use useCookie for small pieces of state that are required by the server or that influence the initial page load (e.g., region, theme, session identifiers).