fix(dashboard): single template-literal child for <title> to stop SVG hydration mismatch

React 19's HTML serializer drops mixed text/expression children inside
<title> elements when emitting SVG markup, so the server rendered
<title></title> while the client rendered <title>2026-05-24: 0 commits</title>.
That mismatch was one of the documented triggers of the
chunk.reason.enqueueModel flight-client crash in
vercel/next.js#92362.

Pre-formatting the tooltip into a single string before passing it as the
<title>'s only child keeps server and client output identical.
This commit is contained in:
Dave 2026-09-17 12:06:20 +02:00
parent 950c3fb8ee
commit a4774783a9

View file

@ -93,6 +93,12 @@ export function ActivityCalendar({
{grid.weeks.map((week, weekIndex) =>
week.map((day, dayIndex) => {
if (!day.inRange) return null;
// Single template-literal child: React 19's HTML serializer drops
// mixed text/expression children inside <title> elements when
// emitted as SSR markup, causing a hydration mismatch where the
// client re-adds the text. One pre-formatted string keeps the
// server and client output identical.
const tooltipText = `${day.date}: ${day.count} ${day.count === 1 ? "commit" : "commits"}`;
return (
<rect
key={day.date}
@ -103,10 +109,7 @@ export function ActivityCalendar({
rx={2}
fill={fill(day.level)}
>
<title>
{day.date}: {day.count}{" "}
{day.count === 1 ? "commit" : "commits"}
</title>
<title>{tooltipText}</title>
</rect>
);
})