The current implementation of the dashboard frequently uses router.push() within onClick handlers for navigation (e.g., in the sidebar, table cells, and badges). While this works, it bypasses several key optimizations provided by Next.js, especially when the dashboard is deployed in SSG (next export) mode.
Using router.push instead of the <Link> component leads to:
- Lack of Prefetching: Next.js cannot prefetch the resources for the target page, resulting in a perceived delay when the user clicks.
- Full Page Refreshes: In many cases, especially in SSG, this triggers a full browser navigation or a heavy re-render that feels like a page refresh (white flash, scroll position reset).
- SEO & Accessibility Issues: Interactive elements that should be links are rendered as
button elements, which is not ideal for screen readers or standard browser behavior (like "Open in new tab").
Impacted Areas
Based on a codebase search, over 50 instances of router.push are used for standard navigation, including:
- Sidebar:
src/components/SidebarItem.tsx (Recently identified as a major source of navigation lag)
- Table Cells:
PeerNameCell.tsx, NetworkNameCell.tsx, UsersTable.tsx, GroupsNameCell.tsx
- Badges:
PeerCountBadge.tsx, ResourceCountBadge.tsx
- Global UI:
src/layouts/Header.tsx, UserDropdown.tsx
Proposed Changes
We should refactor these components to use the next/link component.
For complex components like SidebarItem that handle both navigation and UI state (like collapsibles), we can implement a conditional approach:
- Use
<Link> for items with a valid href and no sub-menu.
- Keep
<button> only for items that solely toggle UI state.
Example (SidebarItem.tsx refactoring)
// From:
<button onClick={() => router.push(href)}>...</button>
// To:
<Link href={href} prefetch={true}>...</Link>
Expected Outcome
- Instantaneous page transitions due to prefetching.
- Smoother "SPA-like" experience without white flashes.
- Better alignment with Next.js best practices and improved accessibility.
Additional Context
This pattern seems to be a legacy from the early Dashboard V2 implementation. Since we are moving towards a more robust and interactive UI, optimizing the navigation foundation is crucial for the overall user experience.
The current implementation of the dashboard frequently uses
router.push()withinonClickhandlers for navigation (e.g., in the sidebar, table cells, and badges). While this works, it bypasses several key optimizations provided by Next.js, especially when the dashboard is deployed in SSG (next export) mode.Using
router.pushinstead of the<Link>component leads to:buttonelements, which is not ideal for screen readers or standard browser behavior (like "Open in new tab").Impacted Areas
Based on a codebase search, over 50 instances of
router.pushare used for standard navigation, including:src/components/SidebarItem.tsx(Recently identified as a major source of navigation lag)PeerNameCell.tsx,NetworkNameCell.tsx,UsersTable.tsx,GroupsNameCell.tsxPeerCountBadge.tsx,ResourceCountBadge.tsxsrc/layouts/Header.tsx,UserDropdown.tsxProposed Changes
We should refactor these components to use the
next/linkcomponent.For complex components like
SidebarItemthat handle both navigation and UI state (like collapsibles), we can implement a conditional approach:<Link>for items with a validhrefand no sub-menu.<button>only for items that solely toggle UI state.Example (SidebarItem.tsx refactoring)
Expected Outcome
Additional Context
This pattern seems to be a legacy from the early Dashboard V2 implementation. Since we are moving towards a more robust and interactive UI, optimizing the navigation foundation is crucial for the overall user experience.