Назад

Правильный SSR для таймзон: решаем проблему с помощью @epic-web/client-hints 🌍⏰

Как @epic-web/client-hints передаёт таймзону через cookies для корректного SSR дат без мерцания и ошибок гидратации.

Правильный SSR для таймзон: решаем проблему с помощью @epic-web/client-hints 🌍⏰

Вечная проблема при SSR-рендеринге дат — сервер понятия не имеет, в какой часовой зоне находится пользователь.

В итоге у нас обычно два так себе варианта:

  1. Рендерить всё на сервере в UTC, а на клиенте «чинить» через useEffect. Получаем неприятный Flash of Incorrect Content (FOIC) или hydration error.
  2. Не рендерить даты на сервере вообще и показывать skeleton/loading. Прощай, быстрый First Contentful Paint.

Решить эту проблему помогает библиотека @epic-web/client-hints (от Кента Доддса и команды Epic Web).

Как это работает?

Библиотека использует паттерн Client Hints через Cookies:

  1. Первый заход: До гидратации на клиенте выполняется крошечный скрипт. Он определяет таймзону пользователя через Intl.DateTimeFormat().resolvedOptions().timeZone, записывает её в Cookie и перезагружает страницу (это происходит единоразово при самом первом посещении).
  2. Все последующие запросы: Сервер читает куку в loader (например, в React Router / Remix / Next) и сразу отдаёт HTML с идеально отформатированной датой под локаль и часовой пояс юзера.

В чём профит?

  • Форматирование в loader: Можно форматировать даты прямо на бэкенде в loader и слать на клиент уже готовые строки. Меньше JS на клиенте, выше производительность.
  • Без гидро-ошибок: Идеальное совпадение HTML сервера и клиента.
  • Не только таймзоны: Через getHintUtils точно так же можно пробрасывать на сервер предпочтения по цветовой теме (prefers-color-scheme), настройки accessibility (prefers-reduced-motion) и размеры экрана.

Туториал

Репозиторий

А как вы решаете задачу с локальными датами при SSR? Согласны на однократный релоад при первом визите ради идеального HTML, или до сих пор правм даты на клиенте через hydration? 👇

Скопировано