Bug Fix·Pushed May 9, 2026·S
PR side panel deep link crash fixed
The PR side panel no longer crashes when opened via deep link — hook order has been stabilized so the component renders reliably from all entry points.
React's rules around hooks require that they be called in the same order every time a component renders. When the [[code ref=1]]PanelContent[[/code]] component was closed, an early return happened before one of the useEffect calls — but when opened via a deep link like ?story=…, the panel would render first in a closed state, then immediately re-render open, changing the hook count between renders. React responded with error 310.
The fix moves the focus-trap useEffect above the early return so it runs consistently regardless of panel state. The effect itself checks whether the panel is open before doing any work.
The PR side panel now opens reliably from all entry points — direct navigation, deep links, and UI interactions alike.
Technical description
The [[code ref=1]]PanelContent[[/code]] component in [[code]]site/src/components/PRSidePanel.tsx[[/code]] was violating React's rules of hooks. In the original code, several useRef calls were followed by an early return when [[code]]!isOpen[[/code]], and the focus-trap useEffect was placed after that return. This meant the hook count varied depending on whether the panel was open or closed — a problem when deep linking caused the component to render initially closed and then immediately open.
The fix moves the useEffect above the early return, ensuring it executes on every render. The effect's internal logic still returns early if the panel isn't open, so behavior is unchanged — only the hook order is now stable.
````diff
file=site/src/components/PRSidePanel.tsx
- if (!isOpen) return null;
-
- const onBackdropClick = (e: React.MouseEvent) => {
- if (e.target === e.currentTarget) closePanel();
- };
-
// Focus trap and restoration
useEffect(() => {
if (!isOpen || isClosing) return;
@@ -92,6 +86,12 @@ function PanelContent() {
};
}, [isOpen, isClosing]);
+ if (!isOpen) return null;
+
+ const onBackdropClick = (e: React.MouseEvent) => {
+ if (e.target === e.currentTarget) closePanel();
+ };
````
Files at a Glance:
- [[code]]site/src/components/PRSidePanel.tsx[[/code]] — stability fix for hook order in panel component