From 99ad4706603401bc25c10404e62241864db943a9 Mon Sep 17 00:00:00 2001 From: Charan Date: Wed, 22 Jul 2026 22:43:05 +0530 Subject: [PATCH] Deduplicate anchors and navbar links in secondary top nav. Sites like pokeapi-docs listed the same URLs in both config arrays; merging them into one row showed duplicates. Dedupe by href with anchors taking precedence, and drop redundant pokeapi navbarLinks. Co-authored-by: Cursor --- examples/pokeapi-docs/content/docs/docs.json | 5 +-- packages/framework/src/secondary-top-nav.tsx | 39 ++++++++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/examples/pokeapi-docs/content/docs/docs.json b/examples/pokeapi-docs/content/docs/docs.json index c4e1eae..8b5d157 100644 --- a/examples/pokeapi-docs/content/docs/docs.json +++ b/examples/pokeapi-docs/content/docs/docs.json @@ -4,10 +4,7 @@ "logo": "/logo.svg", "favicon": "/favicon.svg", "colors": { "primary": "#dc2626" }, - "navbarLinks": [ - { "name": "pokeapi.co", "href": "https://pokeapi.co" }, - { "name": "GitHub", "href": "https://github.com/PokeAPI/pokeapi" } - ], + "navbarLinks": [], "anchors": [ { "name": "PokéAPI", "href": "https://pokeapi.co", "icon": "globe" }, { "name": "GitHub", "href": "https://github.com/PokeAPI/pokeapi", "icon": "github" } diff --git a/packages/framework/src/secondary-top-nav.tsx b/packages/framework/src/secondary-top-nav.tsx index 0924fc2..9568f57 100644 --- a/packages/framework/src/secondary-top-nav.tsx +++ b/packages/framework/src/secondary-top-nav.tsx @@ -22,14 +22,30 @@ function tabClass(active: boolean) { return `fw-topnav-tab${active ? ' fw-topnav-tab--active' : ''}`; } +/** Anchors and navbarLinks can point at the same URL; render once (anchors win). */ +function mergeTopBarLinks( + anchors: NonNullable, + navlinks: NonNullable, +) { + const seen = new Set(); + const merged: Array<{ name: string; href: string }> = []; + + for (const link of [...anchors, ...navlinks]) { + if (seen.has(link.href)) continue; + seen.add(link.href); + merged.push(link); + } + + return merged; +} + /** * Unified secondary header row: doc tabs, anchors, and navbar links share the * same underline-tab styling and active state logic. */ export function SecondaryTopNav({ config, activeTab, pathname, apiBase }: SecondaryTopNavProps) { const tabs = docTabs(config); - const anchors = config.anchors ?? []; - const navlinks = config.navbarLinks ?? []; + const extraLinks = mergeTopBarLinks(config.anchors ?? [], config.navbarLinks ?? []); const onBlog = pathname.startsWith('/blog'); const onChangelog = pathname.startsWith('/changelog'); @@ -56,24 +72,7 @@ export function SecondaryTopNav({ config, activeTab, pathname, apiBase }: Second ); })} - {anchors.map((a) => { - const external = a.href.startsWith('http'); - const isActive = isInternalNavActive(pathname, a.href); - - return ( - - {a.name} - - ); - })} - - {navlinks.map((l) => { + {extraLinks.map((l) => { const external = l.href.startsWith('http'); const isActive = isInternalNavActive(pathname, l.href);