Server rendering
Render with renderToString, hydrate with hydrate, and keep the current time identical on both sides.
The package renders with solid-js/web's renderToString and hydrates with hydrate. There is no separate server
entry: the parts render every element through <Dynamic>, so one build serves both sides, and solid-js/web's export
conditions pick the server or client runtime.
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.
Example
Pass the instant into the calendar as a string:
// the server picks `now` once per request and passes it, with `date`, as strings
export const Schedule = (props: { now: string; date: string; children: JSX.Element }) => {
const calendar = useCalendar(() => ({
timeZone,
views,
features,
view: 'week',
date: Temporal.PlainDate.from(props.date),
events: bookings,
onNavigate: () => {},
initialNow: Temporal.Instant.from(props.now),
}));
return <CalendarProvider value={calendar}>{props.children}</CalendarProvider>;
};Render it on the server, and hydrate with the same instant:
// server: render with the request's instant, and send the same instant to the client
export const render = (date: string) => {
const now = Temporal.Now.instant().toString();
const html = renderToString(() => (
<Schedule now={now} date={date}>
{null}
</Schedule>
));
return { html, head: generateHydrationScript(), data: { now, date } };
};// client: hydrate with the instant the server used
export const start = (root: HTMLElement, data: { now: string; date: string }) =>
hydrate(
() => (
<Schedule now={data.now} date={data.date}>
{null}
</Schedule>
),
root,
);Without initialNow, hydrate throws a hydration mismatch when the now indicator lands in a different column.
Solid has no Server Components, so the entry carries no 'use client' directive.