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
This commit is contained in:
@@ -79,7 +79,7 @@ export default async function BlogPostPage({ params }: Props) {
|
||||
return (
|
||||
<>
|
||||
<ReadingProgress />
|
||||
<PostLayout hasToc={hasToc}>
|
||||
<PostLayout hasToc={hasToc} contentKey={slug}>
|
||||
<div className="space-y-8">
|
||||
{/* Main content area for Pagefind indexing */}
|
||||
<div data-pagefind-body>
|
||||
|
||||
@@ -42,7 +42,7 @@ export default async function StaticPage({ params }: Props) {
|
||||
return (
|
||||
<>
|
||||
<ReadingProgress />
|
||||
<PostLayout hasToc={hasToc}>
|
||||
<PostLayout hasToc={hasToc} contentKey={slug}>
|
||||
<div className="space-y-8">
|
||||
<SectionDivider>
|
||||
<ScrollReveal>
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<PostToc />
|
||||
<PostToc key={contentKey} />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
@@ -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"
|
||||
>
|
||||
<div className="max-h-[60vh] overflow-y-auto">
|
||||
<PostToc onLinkClick={() => setIsTocOpen(false)} />
|
||||
<PostToc key={contentKey} onLinkClick={() => setIsTocOpen(false)} />
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user