From 1b6fc1bd5163599e7d09e3d70f02e4ffbf8d0fb4 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Wed, 15 Apr 2026 11:21:49 -0700 Subject: [PATCH] Use local Link wrapper with cloud-mode prefetch default --- src/app/(main)/MobileNav.tsx | 2 +- src/app/(main)/SideNav.tsx | 2 +- src/app/(main)/admin/AdminNav.tsx | 2 +- src/app/(main)/admin/teams/AdminTeamsTable.tsx | 2 +- src/app/(main)/admin/users/UsersTable.tsx | 2 +- src/app/(main)/admin/websites/AdminWebsitesTable.tsx | 2 +- src/app/(main)/boards/BoardsTable.tsx | 2 +- .../(main)/boards/[boardId]/edit/BoardEditPage.tsx | 2 +- .../(main)/console/[websiteId]/TestConsolePage.tsx | 2 +- src/app/(main)/links/LinksTable.tsx | 2 +- src/app/(main)/links/[linkId]/edit/LinkEditPage.tsx | 2 +- src/app/(main)/pixels/PixelsTable.tsx | 2 +- .../(main)/pixels/[pixelId]/edit/PixelEditPage.tsx | 2 +- src/app/(main)/settings/SettingsNav.tsx | 2 +- src/app/(main)/teams/TeamsDataTable.tsx | 2 +- src/app/(main)/teams/[teamId]/TeamWebsitesTable.tsx | 2 +- src/app/(main)/websites/WebsitesDataTable.tsx | 2 +- src/app/(main)/websites/[websiteId]/WebsiteNav.tsx | 2 +- .../websites/[websiteId]/cohorts/CohortsTable.tsx | 2 +- .../websites/[websiteId]/events/EventsTable.tsx | 2 +- .../websites/[websiteId]/realtime/RealtimeLog.tsx | 2 +- .../websites/[websiteId]/replays/ReplaysTable.tsx | 2 +- .../websites/[websiteId]/segments/SegmentsTable.tsx | 2 +- .../websites/[websiteId]/sessions/SessionsTable.tsx | 2 +- .../[websiteId]/settings/WebsiteSettingsHeader.tsx | 2 +- src/app/share/[slug]/[[...path]]/ShareNav.tsx | 2 +- src/components/common/ExternalLink.tsx | 5 +++-- src/components/common/FilterLink.tsx | 2 +- src/components/common/Link.tsx | 11 +++++++++++ src/components/common/LinkButton.tsx | 2 +- src/components/common/NavMenu.tsx | 2 +- 31 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 src/components/common/Link.tsx diff --git a/src/app/(main)/MobileNav.tsx b/src/app/(main)/MobileNav.tsx index f731cb08a..ff54eb75f 100644 --- a/src/app/(main)/MobileNav.tsx +++ b/src/app/(main)/MobileNav.tsx @@ -1,5 +1,5 @@ import { Column, Grid, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { WebsiteNav } from '@/app/(main)/websites/[websiteId]/WebsiteNav'; import { IconLabel } from '@/components/common/IconLabel'; import { useMessages, useNavigation } from '@/components/hooks'; diff --git a/src/app/(main)/SideNav.tsx b/src/app/(main)/SideNav.tsx index d66c1cc84..2f2c27ec4 100644 --- a/src/app/(main)/SideNav.tsx +++ b/src/app/(main)/SideNav.tsx @@ -24,7 +24,7 @@ import { Tooltip, TooltipTrigger, } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; export function SideNav(props: any) { const { t, labels } = useMessages(); diff --git a/src/app/(main)/admin/AdminNav.tsx b/src/app/(main)/admin/AdminNav.tsx index 064305cfa..7df3ff546 100644 --- a/src/app/(main)/admin/AdminNav.tsx +++ b/src/app/(main)/admin/AdminNav.tsx @@ -3,7 +3,7 @@ import { NavMenu } from '@/components/common/NavMenu'; import { useMessages, useNavigation } from '@/components/hooks'; import { ArrowLeft, Globe, User, Users } from '@/components/icons'; import { Column, Focusable, Row, Tooltip, TooltipTrigger } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; export function AdminNav({ onItemClick }: { onItemClick?: () => void }) { const { t, labels } = useMessages(); diff --git a/src/app/(main)/admin/teams/AdminTeamsTable.tsx b/src/app/(main)/admin/teams/AdminTeamsTable.tsx index f948aba96..8213b6d04 100644 --- a/src/app/(main)/admin/teams/AdminTeamsTable.tsx +++ b/src/app/(main)/admin/teams/AdminTeamsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, Dialog, Icon, MenuItem, Modal, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { useState } from 'react'; import { DateDistance } from '@/components/common/DateDistance'; import { useMessages } from '@/components/hooks'; diff --git a/src/app/(main)/admin/users/UsersTable.tsx b/src/app/(main)/admin/users/UsersTable.tsx index f337cc85f..fafe0e139 100644 --- a/src/app/(main)/admin/users/UsersTable.tsx +++ b/src/app/(main)/admin/users/UsersTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, Icon, MenuItem, Modal, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { useState } from 'react'; import { DateDistance } from '@/components/common/DateDistance'; import { useMessages } from '@/components/hooks'; diff --git a/src/app/(main)/admin/websites/AdminWebsitesTable.tsx b/src/app/(main)/admin/websites/AdminWebsitesTable.tsx index 062fe2774..751dc7583 100644 --- a/src/app/(main)/admin/websites/AdminWebsitesTable.tsx +++ b/src/app/(main)/admin/websites/AdminWebsitesTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, Dialog, Icon, MenuItem, Modal, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { useState } from 'react'; import { WebsiteDeleteForm } from '@/app/(main)/websites/[websiteId]/settings/WebsiteDeleteForm'; import { DateDistance } from '@/components/common/DateDistance'; diff --git a/src/app/(main)/boards/BoardsTable.tsx b/src/app/(main)/boards/BoardsTable.tsx index 25a10cdee..104a58fc8 100644 --- a/src/app/(main)/boards/BoardsTable.tsx +++ b/src/app/(main)/boards/BoardsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { DateDistance } from '@/components/common/DateDistance'; import { useMessages, useNavigation } from '@/components/hooks'; import { BoardDeleteButton } from './BoardDeleteButton'; diff --git a/src/app/(main)/boards/[boardId]/edit/BoardEditPage.tsx b/src/app/(main)/boards/[boardId]/edit/BoardEditPage.tsx index 4867cc5a8..69c813822 100644 --- a/src/app/(main)/boards/[boardId]/edit/BoardEditPage.tsx +++ b/src/app/(main)/boards/[boardId]/edit/BoardEditPage.tsx @@ -1,6 +1,6 @@ 'use client'; import { Column } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { BoardEditForm } from '@/app/(main)/boards/BoardEditForm'; import { BoardShareDialog } from '@/app/(main)/boards/[boardId]/BoardShareDialog'; import { IconLabel } from '@/components/common/IconLabel'; diff --git a/src/app/(main)/console/[websiteId]/TestConsolePage.tsx b/src/app/(main)/console/[websiteId]/TestConsolePage.tsx index 82c8e2494..e5dcd345a 100644 --- a/src/app/(main)/console/[websiteId]/TestConsolePage.tsx +++ b/src/app/(main)/console/[websiteId]/TestConsolePage.tsx @@ -1,6 +1,6 @@ 'use client'; import { Button, Column, Grid, Heading } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import Script from 'next/script'; import { WebsiteChart } from '@/app/(main)/websites/[websiteId]/WebsiteChart'; import { PageBody } from '@/components/common/PageBody'; diff --git a/src/app/(main)/links/LinksTable.tsx b/src/app/(main)/links/LinksTable.tsx index 76fcc6df0..4b7d38f1e 100644 --- a/src/app/(main)/links/LinksTable.tsx +++ b/src/app/(main)/links/LinksTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { DateDistance } from '@/components/common/DateDistance'; import { ExternalLink } from '@/components/common/ExternalLink'; import { useMessages, useNavigation, useSlug } from '@/components/hooks'; diff --git a/src/app/(main)/links/[linkId]/edit/LinkEditPage.tsx b/src/app/(main)/links/[linkId]/edit/LinkEditPage.tsx index 6094c3b8e..c87bec864 100644 --- a/src/app/(main)/links/[linkId]/edit/LinkEditPage.tsx +++ b/src/app/(main)/links/[linkId]/edit/LinkEditPage.tsx @@ -1,6 +1,6 @@ 'use client'; import { Column } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { LinkEditForm } from '@/app/(main)/links/LinkEditForm'; import { LinkProvider } from '@/app/(main)/links/LinkProvider'; import { LinkShareForm } from '@/app/(main)/links/[linkId]/LinkShareForm'; diff --git a/src/app/(main)/pixels/PixelsTable.tsx b/src/app/(main)/pixels/PixelsTable.tsx index 98ae6a8ac..e9bc76ad8 100644 --- a/src/app/(main)/pixels/PixelsTable.tsx +++ b/src/app/(main)/pixels/PixelsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { DateDistance } from '@/components/common/DateDistance'; import { ExternalLink } from '@/components/common/ExternalLink'; import { useMessages, useNavigation, useSlug } from '@/components/hooks'; diff --git a/src/app/(main)/pixels/[pixelId]/edit/PixelEditPage.tsx b/src/app/(main)/pixels/[pixelId]/edit/PixelEditPage.tsx index 2de91bfde..d339c756e 100644 --- a/src/app/(main)/pixels/[pixelId]/edit/PixelEditPage.tsx +++ b/src/app/(main)/pixels/[pixelId]/edit/PixelEditPage.tsx @@ -1,6 +1,6 @@ 'use client'; import { Column } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { PixelEditForm } from '@/app/(main)/pixels/PixelEditForm'; import { PixelProvider } from '@/app/(main)/pixels/PixelProvider'; import { PixelShareForm } from '@/app/(main)/pixels/[pixelId]/PixelShareForm'; diff --git a/src/app/(main)/settings/SettingsNav.tsx b/src/app/(main)/settings/SettingsNav.tsx index 47cdb9cb5..8c97b9d6c 100644 --- a/src/app/(main)/settings/SettingsNav.tsx +++ b/src/app/(main)/settings/SettingsNav.tsx @@ -1,5 +1,5 @@ import { Column, Focusable, Row, Text, Tooltip, TooltipTrigger } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { IconLabel } from '@/components/common/IconLabel'; import { useMessages, useNavigation } from '@/components/hooks'; import { ArrowLeft, Settings2, UserCircle, Users } from '@/components/icons'; diff --git a/src/app/(main)/teams/TeamsDataTable.tsx b/src/app/(main)/teams/TeamsDataTable.tsx index cdce7b936..6decff1be 100644 --- a/src/app/(main)/teams/TeamsDataTable.tsx +++ b/src/app/(main)/teams/TeamsDataTable.tsx @@ -1,4 +1,4 @@ -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { DataGrid } from '@/components/common/DataGrid'; import { useLoginQuery, useNavigation, useUserTeamsQuery } from '@/components/hooks'; import { TeamsTable } from './TeamsTable'; diff --git a/src/app/(main)/teams/[teamId]/TeamWebsitesTable.tsx b/src/app/(main)/teams/[teamId]/TeamWebsitesTable.tsx index f4ed2df7e..86d846bb2 100644 --- a/src/app/(main)/teams/[teamId]/TeamWebsitesTable.tsx +++ b/src/app/(main)/teams/[teamId]/TeamWebsitesTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { TeamMemberEditButton } from '@/app/(main)/teams/[teamId]/TeamMemberEditButton'; import { TeamMemberRemoveButton } from '@/app/(main)/teams/[teamId]/TeamMemberRemoveButton'; import { useMessages } from '@/components/hooks'; diff --git a/src/app/(main)/websites/WebsitesDataTable.tsx b/src/app/(main)/websites/WebsitesDataTable.tsx index f1ef6fb18..552784871 100644 --- a/src/app/(main)/websites/WebsitesDataTable.tsx +++ b/src/app/(main)/websites/WebsitesDataTable.tsx @@ -1,5 +1,5 @@ import { Icon, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { DataGrid } from '@/components/common/DataGrid'; import { useLoginQuery, useNavigation, useUserWebsitesQuery } from '@/components/hooks'; import { Favicon } from '@/index'; diff --git a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx index 1b99bac1e..9b4e7bded 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteNav.tsx @@ -1,5 +1,5 @@ import { Column, Focusable, Row, Text, Tooltip, TooltipTrigger } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { IconLabel } from '@/components/common/IconLabel'; import { useMessages, useNavigation, useWebsiteNavItems } from '@/components/hooks'; import { ArrowLeft } from '@/components/icons'; diff --git a/src/app/(main)/websites/[websiteId]/cohorts/CohortsTable.tsx b/src/app/(main)/websites/[websiteId]/cohorts/CohortsTable.tsx index fe9c95441..5641ed40c 100644 --- a/src/app/(main)/websites/[websiteId]/cohorts/CohortsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/cohorts/CohortsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { CohortDeleteButton } from '@/app/(main)/websites/[websiteId]/cohorts/CohortDeleteButton'; import { CohortEditButton } from '@/app/(main)/websites/[websiteId]/cohorts/CohortEditButton'; import { DateDistance } from '@/components/common/DateDistance'; diff --git a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx index 59310518e..57688e55c 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx @@ -10,7 +10,7 @@ import { Row, Text, } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { Avatar } from '@/components/common/Avatar'; import { DateDistance } from '@/components/common/DateDistance'; import { IconLabel } from '@/components/common/IconLabel'; diff --git a/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.tsx b/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.tsx index 69760eb75..1bfa79ccd 100644 --- a/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.tsx +++ b/src/app/(main)/websites/[websiteId]/realtime/RealtimeLog.tsx @@ -1,5 +1,5 @@ import { Column, Heading, Row, SearchField, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { useMemo, useState } from 'react'; import { FixedSizeList } from 'react-window'; import { SessionModal } from '@/app/(main)/websites/[websiteId]/sessions/SessionModal'; diff --git a/src/app/(main)/websites/[websiteId]/replays/ReplaysTable.tsx b/src/app/(main)/websites/[websiteId]/replays/ReplaysTable.tsx index 64e460f04..33fc7f13c 100644 --- a/src/app/(main)/websites/[websiteId]/replays/ReplaysTable.tsx +++ b/src/app/(main)/websites/[websiteId]/replays/ReplaysTable.tsx @@ -1,6 +1,6 @@ import { Button, DataColumn, DataTable, type DataTableProps, Icon } from '@umami/react-zen'; import { Play } from 'lucide-react'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { Avatar } from '@/components/common/Avatar'; import { DateDistance } from '@/components/common/DateDistance'; import { TypeIcon } from '@/components/common/TypeIcon'; diff --git a/src/app/(main)/websites/[websiteId]/segments/SegmentsTable.tsx b/src/app/(main)/websites/[websiteId]/segments/SegmentsTable.tsx index 7e8ddb2a6..4c9e27e38 100644 --- a/src/app/(main)/websites/[websiteId]/segments/SegmentsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/segments/SegmentsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps, Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { SegmentDeleteButton } from '@/app/(main)/websites/[websiteId]/segments/SegmentDeleteButton'; import { SegmentEditButton } from '@/app/(main)/websites/[websiteId]/segments/SegmentEditButton'; import { DateDistance } from '@/components/common/DateDistance'; diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index 1f3d451a7..e2b592eb0 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -1,5 +1,5 @@ import { DataColumn, DataTable, type DataTableProps } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { Avatar } from '@/components/common/Avatar'; import { DateDistance } from '@/components/common/DateDistance'; import { TypeIcon } from '@/components/common/TypeIcon'; diff --git a/src/app/(main)/websites/[websiteId]/settings/WebsiteSettingsHeader.tsx b/src/app/(main)/websites/[websiteId]/settings/WebsiteSettingsHeader.tsx index ec9eb0b81..42b968b5f 100644 --- a/src/app/(main)/websites/[websiteId]/settings/WebsiteSettingsHeader.tsx +++ b/src/app/(main)/websites/[websiteId]/settings/WebsiteSettingsHeader.tsx @@ -1,5 +1,5 @@ import { Row } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { IconLabel } from '@/components/common/IconLabel'; import { PageHeader } from '@/components/common/PageHeader'; import { useMessages, useNavigation, useWebsite } from '@/components/hooks'; diff --git a/src/app/share/[slug]/[[...path]]/ShareNav.tsx b/src/app/share/[slug]/[[...path]]/ShareNav.tsx index 1ad22926e..9bc238ad4 100644 --- a/src/app/share/[slug]/[[...path]]/ShareNav.tsx +++ b/src/app/share/[slug]/[[...path]]/ShareNav.tsx @@ -16,7 +16,7 @@ import { Tooltip, TooltipTrigger, } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { ShareBranding } from './ShareBranding'; export function ShareNav({ diff --git a/src/components/common/ExternalLink.tsx b/src/components/common/ExternalLink.tsx index dec0d16fe..89e9e6cba 100644 --- a/src/components/common/ExternalLink.tsx +++ b/src/components/common/ExternalLink.tsx @@ -1,17 +1,18 @@ import { Icon, Row, Text } from '@umami/react-zen'; -import Link, { type LinkProps } from 'next/link'; +import Link, { type LinkProps } from '@/components/common/Link'; import type { ReactNode } from 'react'; import { ExternalLink as LinkIcon } from '@/components/icons'; export function ExternalLink({ href, children, + prefetch = false, ...props }: LinkProps & { href: string; children: ReactNode }) { return ( - + {children} diff --git a/src/components/common/FilterLink.tsx b/src/components/common/FilterLink.tsx index df9eab9b7..f124706b9 100644 --- a/src/components/common/FilterLink.tsx +++ b/src/components/common/FilterLink.tsx @@ -1,5 +1,5 @@ import { Icon, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { type HTMLAttributes, type ReactNode, useState } from 'react'; import { useMessages, useNavigation } from '@/components/hooks'; import { ExternalLink } from '@/components/icons'; diff --git a/src/components/common/Link.tsx b/src/components/common/Link.tsx new file mode 100644 index 000000000..3590996ea --- /dev/null +++ b/src/components/common/Link.tsx @@ -0,0 +1,11 @@ +import NextLink from 'next/link'; +import { type ComponentPropsWithoutRef, forwardRef } from 'react'; + +export type LinkProps = ComponentPropsWithoutRef; +const cloudMode = !!process.env.cloudMode; + +const Link = forwardRef(function Link({ prefetch, ...props }, ref) { + return ; +}); + +export default Link; diff --git a/src/components/common/LinkButton.tsx b/src/components/common/LinkButton.tsx index 990feb1c8..826aedcf4 100644 --- a/src/components/common/LinkButton.tsx +++ b/src/components/common/LinkButton.tsx @@ -1,5 +1,5 @@ import { Button, type ButtonProps } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import type { ReactNode } from 'react'; import { useLocale } from '@/components/hooks'; diff --git a/src/components/common/NavMenu.tsx b/src/components/common/NavMenu.tsx index f0ae91fe2..9442b2486 100644 --- a/src/components/common/NavMenu.tsx +++ b/src/components/common/NavMenu.tsx @@ -1,5 +1,5 @@ import { Column, Heading, Row, Text } from '@umami/react-zen'; -import Link from 'next/link'; +import Link from '@/components/common/Link'; import { IconLabel } from '@/components/common/IconLabel'; interface NavMenuData {