Go back

Proper SSR for time zones: solving the problem with @epic-web/client-hints 🌍⏰

How @epic-web/client-hints passes time zones through cookies for correct server-rendered dates without flashes or hydration errors.

Proper SSR for time zones: solving the problem with @epic-web/client-hints 🌍⏰

The perennial problem with server-rendering dates is that the server has no idea which time zone the user is in.

We usually end up with two less-than-ideal options:

  1. Render everything on the server in UTC, then β€œfix” it on the client with useEffect. The result is an unpleasant Flash of Incorrect Content (FOIC) or a hydration error.
  2. Don’t render dates on the server at all, and show a skeleton/loading state instead. Goodbye, fast First Contentful Paint.

The @epic-web/client-hints library (from Kent Dodds and the Epic Web team) helps solve this problem.

How does it work?

The library uses the Client Hints through Cookies pattern:

  1. First visit: Before hydration, a tiny script runs on the client. It detects the user’s time zone through Intl.DateTimeFormat().resolvedOptions().timeZone, writes it to a Cookie and reloads the page (this happens only once, on the very first visit).
  2. All subsequent requests: The server reads the cookie in a loader (for example, in React Router / Remix / Next) and immediately returns HTML with a date perfectly formatted for the user’s locale and time zone.

What are the benefits?

  • Formatting in the loader: You can format dates directly on the backend in a loader and send ready-made strings to the client. Less client-side JS, better performance.
  • No hydration errors: Server and client HTML match perfectly.
  • Not just time zones: With getHintUtils, you can similarly pass color theme preferences (prefers-color-scheme), accessibility settings (prefers-reduced-motion) and screen dimensions to the server.

Tutorial

Repository

How do you handle local dates with SSR? Are you willing to accept a one-time reload on the first visit for perfect HTML, or are you still fixing dates on the client through hydration? πŸ‘‡

Copied