From 2b1060dd45d81eaed294536814cd77844aade467 Mon Sep 17 00:00:00 2001 From: gbanyan Date: Thu, 20 Nov 2025 15:57:47 +0800 Subject: [PATCH] Fix TOC showing wrong headings across navigation Problem: Table of Contents displayed headings from previously viewed articles when navigating between posts via client-side routing. Root cause: PostToc component's useEffect with empty dependency array only ran once on mount, so it retained stale heading data when React reused the component instance during navigation. Solution: Add contentKey prop flow: - Blog/page routes pass slug to PostLayout - PostLayout passes contentKey as key prop to PostToc instances - React remounts PostToc when key changes, rebuilding TOC correctly Files changed: - components/post-layout.tsx: Add contentKey prop and key forwarding - app/blog/[slug]/page.tsx: Pass slug as contentKey - app/pages/[slug]/page.tsx: Pass slug as contentKey --- app/blog/[slug]/page.tsx | 2 +- app/pages/[slug]/page.tsx | 2 +- components/post-layout.tsx | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx index 2c8a7ca..1f9aafe 100644 --- a/app/blog/[slug]/page.tsx +++ b/app/blog/[slug]/page.tsx @@ -79,7 +79,7 @@ export default async function BlogPostPage({ params }: Props) { return ( <> - +
{/* Main content area for Pagefind indexing */}
diff --git a/app/pages/[slug]/page.tsx b/app/pages/[slug]/page.tsx index 7871d88..343c517 100644 --- a/app/pages/[slug]/page.tsx +++ b/app/pages/[slug]/page.tsx @@ -42,7 +42,7 @@ export default async function StaticPage({ params }: Props) { return ( <> - +
diff --git a/components/post-layout.tsx b/components/post-layout.tsx index 19b49b0..0bbca19 100644 --- a/components/post-layout.tsx +++ b/components/post-layout.tsx @@ -12,7 +12,7 @@ function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } -export function PostLayout({ children, hasToc = true }: { children: React.ReactNode; hasToc?: boolean }) { +export function PostLayout({ children, hasToc = true, contentKey }: { children: React.ReactNode; hasToc?: boolean; contentKey?: string }) { const [isTocOpen, setIsTocOpen] = useState(hasToc); return ( @@ -43,7 +43,7 @@ export function PostLayout({ children, hasToc = true }: { children: React.ReactN transition={{ duration: 0.3 }} className="h-full overflow-y-auto pr-2" > - + )} @@ -62,7 +62,7 @@ export function PostLayout({ children, hasToc = true }: { children: React.ReactN className="fixed bottom-24 right-4 z-40 w-72 rounded-2xl border border-white/20 bg-white/90 p-6 shadow-2xl backdrop-blur-xl dark:border-white/10 dark:bg-slate-900/90 lg:hidden" >
- setIsTocOpen(false)} /> + setIsTocOpen(false)} />
)}