Server rendering
Fetch on the server and keep the current time identical on the server and the client.
Hydration
Today's highlight and the now indicator depend on the current time. If the server and the client use different times, for example across midnight, the markup doesn't match. Give both sides the same instant:
- Pick an instant once per request, on the server.
- Send it to the client as a string, with the page's data.
- Pass it as
initialNowon both sides.
initialNow is read once, when the calendar is created. After mounting, the client reads its clock and catches up to
the real time. On the server the clock never starts.
// the same instant on the server and the client: pick it once per request and send it as a string
export const createForRequest = (now: string, date: string) =>
createCalendar({
timeZone,
views,
features,
view: 'week',
date: Temporal.PlainDate.from(date),
events: bookings,
onNavigate: () => {},
initialNow: Temporal.Instant.from(now),
});Fetching on the server
getCalendarNavigation gives the visible range for any view and date without creating a calendar, so the server can
fetch the events to render:
// the visible range for any view and date, without a calendar: for example, to fetch on the server
export const range = getCalendarNavigation(views, 'month', Temporal.PlainDate.from('2026-03-11'), {
firstDayOfWeek: 1,
}).range;