fix(nav): avoid Kanban flyout state update racing with RSC navigation

A click outside the Kanban sidebar flyout called setOpen(false) even when
the click was on a Link, so the deferred state update landed during the
Link navigation's RSC stream and corrupted Turbopack's flight client
(vercel/next.js#92362).

Skip the close when the click target is inside an <a> and flush the close
synchronously from the Link's own onClick so the state update completes
before navigation, not during RSC processing.
This commit is contained in:
Dave 2026-09-17 11:15:32 +02:00
parent dc45063508
commit 5c26f39f2c

View file

@ -1,6 +1,7 @@
"use client";
import { useEffect, useRef, useState } from "react";
import { flushSync } from "react-dom";
import Link from "next/link";
import { Kanban } from "lucide-react";
@ -36,6 +37,11 @@ export function KanbanNav({
containerRef.current &&
!containerRef.current.contains(event.target as Node)
) {
// Skip closing when the click is on an anchor. The Link's own
// onClick closes the flyout via flushSync below, and racing a
// deferred state update with the navigation's RSC stream
// corrupts Turbopack's flight client (vercel/next.js#92362).
if ((event.target as HTMLElement).closest("a")) return;
setOpen(false);
}
}
@ -80,7 +86,11 @@ export function KanbanNav({
<Link
key={project.id}
href={`/p/${group.client.slug}/${project.slug}`}
onClick={() => setOpen(false)}
onClick={() => {
// Force the close to land before navigation, not
// during RSC stream processing — see #92362 above.
flushSync(() => setOpen(false));
}}
className="flex items-center justify-between gap-2 rounded-lg px-2 py-1.5 text-xs text-text-secondary transition-colors hover:bg-surface-raised hover:text-text-primary"
>
<span className="truncate">{project.name}</span>