Timezones

Leveraging client hints to render timezone-aware content.

Server rendering timezones has always been a pain. This is because the server doesn't know the user's timezone. It only knows the timezone of the server. So lots of people will take the easy way out and do one of the following workarounds:

  • Just render in UTC: Not great because it's not the user's timezone
  • Render in the server's timezone: Not great because it's not the user's timezone
  • Render in the server's timezone, and hydrate in the client's timezone: Not great because it causes a flash of incorrect content (and a hydration error unless you add suppressHydrationWarning={true} to the element)
  • Don't render the time on the server at all: Not great because it's a flash of incomplete content (and no, fading it in does not count).
  • Only render the time from user interaction: Sometimes this is fine, but often you're just compromising on UX and you know it.

Thanks to the Epic Stack's built-in support for client hints, we can do better! We have a client hint set up for the user's timezone. This means you can render the time on the server in the user's timezone, and hydrate it in the user's timezone, without any flash of incorrect content or hydration errors.

You can use this in a few ways. In server-side only code, getHints(request).timeZone will be what you're looking for. In UI code, you can use useHints().timeZone to get the user's timezone.

For the server-side code, we have a getDateTimeFormat utility uses to give you a DateTimeFormat object that is in the user's timezone (it also uses the standard accept-language header to determine the user's preferred locale).

If you'd prefer to use a library for formatting dates and times, feel free to simply access the timezone from the hints and use it with your library of choice.

Edit this page on

Copyright © 2023 Kent C Dodds