From 7a41775c7e1ae35284c052be90771784939d00b5 Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 29 Aug 2026 19:27:13 +0200 Subject: [PATCH] fix: disable route prefetching app-wide to avoid spurious requests Wrap next/link in a shared Link component that ships prefetch=false by default, so no route is ever prefetched (viewport or hover) anymore, and drop the DNS prefetch hint. Removes hidden background requests that were the source of intermittent issues. --- src/app/(site)/community/page.tsx | 2 +- src/app/(site)/error.tsx | 2 +- src/app/(site)/events/[slugOrId]/page.tsx | 2 +- src/app/(site)/events/page.tsx | 2 +- src/app/(site)/forgot/page.tsx | 2 +- src/app/(site)/friends/page.tsx | 2 +- src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx | 2 +- src/app/(site)/guilds/[id]/forum/new/page.tsx | 2 +- src/app/(site)/guilds/[id]/forum/page.tsx | 2 +- src/app/(site)/guilds/[id]/page.tsx | 2 +- src/app/(site)/guilds/page.tsx | 2 +- src/app/(site)/help/[category]/page.tsx | 2 +- src/app/(site)/help/page.tsx | 2 +- src/app/(site)/help/tickets/[id]/page.tsx | 2 +- src/app/(site)/help/tickets/page.tsx | 2 +- src/app/(site)/leaderboard/page.tsx | 2 +- src/app/(site)/login/page.tsx | 2 +- src/app/(site)/me/page.tsx | 3 +-- src/app/(site)/messages/page.tsx | 2 +- src/app/(site)/news/[...slug]/page.tsx | 2 +- src/app/(site)/news/page.tsx | 2 +- src/app/(site)/page.tsx | 2 +- src/app/(site)/polls/[id]/page.tsx | 2 +- src/app/(site)/polls/page.tsx | 2 +- src/app/(site)/radio/contests/[id]/page.tsx | 2 +- src/app/(site)/radio/contests/page.tsx | 2 +- src/app/(site)/radio/giveaways/[id]/page.tsx | 2 +- src/app/(site)/radio/giveaways/page.tsx | 2 +- src/app/(site)/radio/layout.tsx | 2 +- src/app/(site)/radio/leaderboard/page.tsx | 2 +- src/app/(site)/radio/page.tsx | 2 +- src/app/(site)/rankings/page.tsx | 2 +- src/app/(site)/rares/[category]/page.tsx | 2 +- src/app/(site)/rares/page.tsx | 2 +- src/app/(site)/register/page.tsx | 2 +- src/app/(site)/reset/page.tsx | 2 +- src/app/(site)/room/[id]/page.tsx | 2 +- src/app/(site)/search/page.tsx | 2 +- src/app/(site)/settings/2fa/page.tsx | 2 +- src/app/(site)/settings/page.tsx | 2 +- src/app/(site)/shop/page.tsx | 2 +- src/app/(site)/staff/page.tsx | 2 +- src/app/(site)/u/[username]/page.tsx | 2 +- src/app/(site)/verify/page.tsx | 2 +- src/app/admin/ads/[id]/page.tsx | 2 +- src/app/admin/ads/ads-table.tsx | 2 +- src/app/admin/ads/new/page.tsx | 2 +- src/app/admin/ads/page.tsx | 2 +- src/app/admin/applications/page.tsx | 2 +- src/app/admin/articles/[id]/page.tsx | 2 +- src/app/admin/articles/new/page.tsx | 2 +- src/app/admin/articles/page.tsx | 2 +- src/app/admin/calendar/[id]/page.tsx | 2 +- src/app/admin/calendar/page.tsx | 2 +- src/app/admin/catalog/[id]/catalog-page-form.tsx | 2 +- src/app/admin/catalog/[id]/page.tsx | 2 +- src/app/admin/catalog/builder-club/bc-manager.tsx | 2 +- src/app/admin/catalog/catalog-table.tsx | 2 +- src/app/admin/devops/page.tsx | 2 +- src/app/admin/error.tsx | 2 +- src/app/admin/events/events-table.tsx | 2 +- src/app/admin/events/page.tsx | 2 +- src/app/admin/guilds/[id]/page.tsx | 2 +- src/app/admin/guilds/page.tsx | 2 +- src/app/admin/help-questions/[id]/page.tsx | 2 +- src/app/admin/help-questions/new/page.tsx | 2 +- src/app/admin/help-questions/page.tsx | 2 +- .../help-tickets/[id]/admin-help-ticket-detail.tsx | 2 +- src/app/admin/help-tickets/help-tickets-table.tsx | 2 +- src/app/admin/housekeeping/page.tsx | 2 +- src/app/admin/items/[id]/items-base-edit-form.tsx | 2 +- src/app/admin/items/items-table.tsx | 2 +- src/app/admin/layout.tsx | 2 +- src/app/admin/marketplace/page.tsx | 2 +- src/app/admin/moderation/cfh/[id]/cfh-detail.tsx | 2 +- src/app/admin/moderation/cfh/cfh-table.tsx | 2 +- src/app/admin/moderation/page.tsx | 2 +- src/app/admin/moderation/team/page.tsx | 2 +- src/app/admin/page.tsx | 2 +- src/app/admin/permissions/[id]/rank-edit-client.tsx | 2 +- src/app/admin/permissions/permissions-list.tsx | 2 +- src/app/admin/photos/page.tsx | 2 +- src/app/admin/polls/page.tsx | 2 +- src/app/admin/polls/polls-table.tsx | 2 +- src/app/admin/radio/embed/page.tsx | 2 +- src/app/admin/rooms/[id]/furni/furni-client.tsx | 2 +- src/app/admin/rooms/edit/[id]/page.tsx | 2 +- src/app/admin/rooms/rooms-table.tsx | 2 +- src/app/admin/rooms/show/[id]/page.tsx | 2 +- src/app/admin/shop/[id]/page.tsx | 2 +- src/app/admin/shop/new/page.tsx | 2 +- src/app/admin/shop/page.tsx | 2 +- src/app/admin/studio/layout.tsx | 2 +- src/app/admin/tickets/[id]/admin-ticket-detail.tsx | 2 +- src/app/admin/tickets/tickets-table.tsx | 2 +- src/app/admin/transactions/transactions-table.tsx | 2 +- src/app/admin/translations/emulator/page.tsx | 2 +- src/app/admin/translations/translations-tabs.tsx | 2 +- src/app/admin/users/[id]/user-activity-log.tsx | 2 +- src/app/admin/users/[id]/user-rooms.tsx | 2 +- src/app/admin/users/_components/user-account-info.tsx | 2 +- src/app/admin/users/_components/user-hero.tsx | 2 +- .../admin/users/_components/user-sanction-timeline.tsx | 2 +- src/app/admin/users/multi-accounts/page.tsx | 2 +- src/app/admin/users/users-table.tsx | 2 +- src/app/admin/vpn/page.tsx | 2 +- src/app/client/client-view.tsx | 10 ++-------- src/app/error.tsx | 2 +- src/app/layout.tsx | 1 - src/app/mod/layout.tsx | 2 +- src/app/mod/page.tsx | 2 +- src/app/mod/team/page.tsx | 2 +- src/app/mod/tickets/page.tsx | 2 +- src/app/mod/users/[id]/page.tsx | 2 +- src/app/mod/users/page.tsx | 2 +- src/app/not-found.tsx | 2 +- src/components/admin/admin-breadcrumb.tsx | 2 +- src/components/admin/admin-nav-link.tsx | 2 +- src/components/admin/admin-section-tabs.tsx | 2 +- src/components/admin/admin-simple-pager.tsx | 2 +- src/components/admin/article-card.tsx | 2 +- src/components/admin/catalog-manager/inline-editor.tsx | 2 +- src/components/admin/catalog-tree.tsx | 2 +- src/components/admin/stats-card.tsx | 2 +- src/components/admin/ticket-queue-banner.tsx | 2 +- src/components/admin/unified-tickets-table.tsx | 2 +- src/components/auth/login-form.tsx | 2 +- src/components/auth/register-form.tsx | 2 +- src/components/link.tsx | 6 ++++++ src/components/navigation.tsx | 2 +- src/components/site-header.tsx | 2 +- src/components/surface-card.tsx | 2 +- src/components/top-header.tsx | 2 +- .../housekeeping/foundation/shell/context-nav.tsx | 2 +- .../housekeeping/foundation/shell/domain-rail.tsx | 2 +- .../foundation/shell/housekeeping-shell.tsx | 2 +- 136 files changed, 141 insertions(+), 143 deletions(-) create mode 100644 src/components/link.tsx diff --git a/src/app/(site)/community/page.tsx b/src/app/(site)/community/page.tsx index 0a276be5..49a697e6 100644 --- a/src/app/(site)/community/page.tsx +++ b/src/app/(site)/community/page.tsx @@ -1,5 +1,5 @@ -import Link from "next/link"; import { useTranslations } from "next-intl"; +import Link from "@/components/link"; import { ContentCard } from "@/components/public/ui"; export const metadata = { title: "Community" }; diff --git a/src/app/(site)/error.tsx b/src/app/(site)/error.tsx index 0f6d9bb9..696637f5 100644 --- a/src/app/(site)/error.tsx +++ b/src/app/(site)/error.tsx @@ -1,10 +1,10 @@ "use client"; import { Home, RefreshCw } from "lucide-react"; -import Link from "next/link"; import { useTranslations } from "next-intl"; import { useEffect } from "react"; import { ErrorScreen } from "@/components/error-screen"; +import Link from "@/components/link"; /** * Site route-segment error boundary. Renders inside the site shell layout. diff --git a/src/app/(site)/events/[slugOrId]/page.tsx b/src/app/(site)/events/[slugOrId]/page.tsx index 6d6ef9d4..d6137dc6 100644 --- a/src/app/(site)/events/[slugOrId]/page.tsx +++ b/src/app/(site)/events/[slugOrId]/page.tsx @@ -1,8 +1,8 @@ import { and, asc, count, eq, inArray } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { diff --git a/src/app/(site)/events/page.tsx b/src/app/(site)/events/page.tsx index ed625baf..89f66a36 100644 --- a/src/app/(site)/events/page.tsx +++ b/src/app/(site)/events/page.tsx @@ -1,7 +1,7 @@ import { count, desc, eq, inArray } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { db, diff --git a/src/app/(site)/forgot/page.tsx b/src/app/(site)/forgot/page.tsx index 289fea1b..c32dfe64 100644 --- a/src/app/(site)/forgot/page.tsx +++ b/src/app/(site)/forgot/page.tsx @@ -1,8 +1,8 @@ import { headers } from "next/headers"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { requestReset } from "@/actions/password-reset"; import { CaptchaWidget } from "@/components/auth/captcha-widget"; +import Link from "@/components/link"; import { ContentCard } from "@/components/public/ui"; import { captchaConfig } from "@/lib/services/captcha"; diff --git a/src/app/(site)/friends/page.tsx b/src/app/(site)/friends/page.tsx index 85a56018..8376ca44 100644 --- a/src/app/(site)/friends/page.tsx +++ b/src/app/(site)/friends/page.tsx @@ -1,9 +1,9 @@ import { asc, eq, inArray, or } from "drizzle-orm"; -import Link from "next/link"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; import { removeFriendship } from "@/actions/messenger"; +import Link from "@/components/link"; import { ContentCard, EmptyState, OnlineBadge } from "@/components/public/ui"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { auth } from "@/lib/auth"; diff --git a/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx b/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx index 238664d5..f20b456b 100644 --- a/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx @@ -1,9 +1,9 @@ import { and, asc, eq, inArray } from "drizzle-orm"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; import { replyToThread } from "@/actions/social"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { diff --git a/src/app/(site)/guilds/[id]/forum/new/page.tsx b/src/app/(site)/guilds/[id]/forum/new/page.tsx index c5b7294b..7fc66365 100644 --- a/src/app/(site)/guilds/[id]/forum/new/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/new/page.tsx @@ -1,9 +1,9 @@ import { eq } from "drizzle-orm"; -import Link from "next/link"; import { notFound, redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; import { postThread } from "@/actions/social"; +import Link from "@/components/link"; import { ContentCard } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { db, Guilds } from "@/lib/db"; diff --git a/src/app/(site)/guilds/[id]/forum/page.tsx b/src/app/(site)/guilds/[id]/forum/page.tsx index e8d2e1fe..ae4df681 100644 --- a/src/app/(site)/guilds/[id]/forum/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/page.tsx @@ -1,8 +1,8 @@ import { and, desc, eq, inArray } from "drizzle-orm"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { db, Guilds, GuildsForumsThreads, User } from "@/lib/db"; import { formatDate } from "@/lib/format-date"; diff --git a/src/app/(site)/guilds/[id]/page.tsx b/src/app/(site)/guilds/[id]/page.tsx index df6056e9..ff595863 100644 --- a/src/app/(site)/guilds/[id]/page.tsx +++ b/src/app/(site)/guilds/[id]/page.tsx @@ -1,7 +1,7 @@ import { asc, eq, inArray } from "drizzle-orm"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { db, Guilds, GuildsMembers, User } from "@/lib/db"; diff --git a/src/app/(site)/guilds/page.tsx b/src/app/(site)/guilds/page.tsx index 0da0d868..c1f80ddc 100644 --- a/src/app/(site)/guilds/page.tsx +++ b/src/app/(site)/guilds/page.tsx @@ -1,6 +1,6 @@ import { desc } from "drizzle-orm"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { db, Guilds } from "@/lib/db"; import { excerpt } from "@/lib/format"; diff --git a/src/app/(site)/help/[category]/page.tsx b/src/app/(site)/help/[category]/page.tsx index 71f35f2d..65cb9e52 100644 --- a/src/app/(site)/help/[category]/page.tsx +++ b/src/app/(site)/help/[category]/page.tsx @@ -1,7 +1,7 @@ import { asc, eq, ne } from "drizzle-orm"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard } from "@/components/public/ui"; import { SanitizedHtml } from "@/components/shared/sanitized-html"; import { db, WebsiteHelpCenterCategories } from "@/lib/db"; diff --git a/src/app/(site)/help/page.tsx b/src/app/(site)/help/page.tsx index 3497d37e..7b758b5e 100644 --- a/src/app/(site)/help/page.tsx +++ b/src/app/(site)/help/page.tsx @@ -1,6 +1,6 @@ import { asc } from "drizzle-orm"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { db, diff --git a/src/app/(site)/help/tickets/[id]/page.tsx b/src/app/(site)/help/tickets/[id]/page.tsx index 1e2048e0..a7293404 100644 --- a/src/app/(site)/help/tickets/[id]/page.tsx +++ b/src/app/(site)/help/tickets/[id]/page.tsx @@ -1,9 +1,9 @@ import { asc, eq, inArray } from "drizzle-orm"; -import Link from "next/link"; import { notFound, redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; import { closeHelpTicket, replyHelpTicket } from "@/actions/help-tickets"; +import Link from "@/components/link"; import { ContentCard } from "@/components/public/ui"; import { positiveBigInt } from "@/lib/api"; import { auth } from "@/lib/auth"; diff --git a/src/app/(site)/help/tickets/page.tsx b/src/app/(site)/help/tickets/page.tsx index 9a06b75b..1812f6ab 100644 --- a/src/app/(site)/help/tickets/page.tsx +++ b/src/app/(site)/help/tickets/page.tsx @@ -1,9 +1,9 @@ import { desc, eq } from "drizzle-orm"; -import Link from "next/link"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { CSSProperties } from "react"; import { createTicket } from "@/actions/help-tickets"; +import Link from "@/components/link"; import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { db, WebsiteHelpCenterTickets } from "@/lib/db"; diff --git a/src/app/(site)/leaderboard/page.tsx b/src/app/(site)/leaderboard/page.tsx index ad6cbc30..77724944 100644 --- a/src/app/(site)/leaderboard/page.tsx +++ b/src/app/(site)/leaderboard/page.tsx @@ -1,6 +1,6 @@ import { desc, eq } from "drizzle-orm"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { ContentCard, EmptyState, RankBadge } from "@/components/public/ui"; import { CurrencyIcon, diff --git a/src/app/(site)/login/page.tsx b/src/app/(site)/login/page.tsx index 02dea8b8..40bbb392 100644 --- a/src/app/(site)/login/page.tsx +++ b/src/app/(site)/login/page.tsx @@ -1,11 +1,11 @@ import { count, desc, eq } from "drizzle-orm"; import { headers } from "next/headers"; import Image from "next/image"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { LoginForm } from "@/components/auth/login-form"; import { Clock } from "@/components/clock"; import { LanguageSwitcher } from "@/components/language-switcher"; +import Link from "@/components/link"; import { Reveal } from "@/components/motion-reveal"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { SurfaceCard } from "@/components/surface-card"; diff --git a/src/app/(site)/me/page.tsx b/src/app/(site)/me/page.tsx index 7aee9cca..72927846 100644 --- a/src/app/(site)/me/page.tsx +++ b/src/app/(site)/me/page.tsx @@ -1,9 +1,9 @@ import { and, asc, count, desc, eq, gt, or } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import { redirect } from "next/navigation"; import type { CSSProperties, ReactNode } from "react"; import { claimReferral } from "@/actions/referral"; +import Link from "@/components/link"; import { Reveal } from "@/components/motion-reveal"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; @@ -282,7 +282,6 @@ export default async function MePage({ /> + {children} ); diff --git a/src/app/error.tsx b/src/app/error.tsx index 0daaaa6e..e85e19d2 100644 --- a/src/app/error.tsx +++ b/src/app/error.tsx @@ -1,10 +1,10 @@ "use client"; import { Home, RefreshCw } from "lucide-react"; -import Link from "next/link"; import { useTranslations } from "next-intl"; import { useEffect } from "react"; import { ErrorScreen } from "@/components/error-screen"; +import Link from "@/components/link"; /** * Route-segment error boundary. Renders inside the root layout (so the shell diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 293bc9d3..63e8efd6 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -86,7 +86,6 @@ export default async function RootLayout({ nonce={nonce} /> - {nitroUrl?.startsWith("http") ? ( ) : null} diff --git a/src/app/mod/layout.tsx b/src/app/mod/layout.tsx index 1fdff78d..3694be4d 100644 --- a/src/app/mod/layout.tsx +++ b/src/app/mod/layout.tsx @@ -9,11 +9,11 @@ import { UserRound, Users, } from "lucide-react"; -import Link from "next/link"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import type { ReactNode } from "react"; import { LanguageSwitcher } from "@/components/language-switcher"; +import Link from "@/components/link"; import { ThemeSwitcher } from "@/components/theme-switcher"; import { requireMod } from "@/lib/admin/guard"; import { db, User } from "@/lib/db"; diff --git a/src/app/mod/page.tsx b/src/app/mod/page.tsx index 1b8c211b..a05edc70 100644 --- a/src/app/mod/page.tsx +++ b/src/app/mod/page.tsx @@ -8,9 +8,9 @@ import { Ticket, Users, } from "lucide-react"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { StatsCard } from "@/components/admin/stats-card"; +import Link from "@/components/link"; import { getMinStaffRank } from "@/lib/admin/min-staff-rank"; import { Ban as BanTable, diff --git a/src/app/mod/team/page.tsx b/src/app/mod/team/page.tsx index 00cb6e25..6fdc04cc 100644 --- a/src/app/mod/team/page.tsx +++ b/src/app/mod/team/page.tsx @@ -1,5 +1,5 @@ import { and, count, desc, gte, inArray, like } from "drizzle-orm"; -import Link from "next/link"; +import Link from "@/components/link"; import { AvatarImage } from "@/components/shared/avatar-image"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent } from "@/components/ui/card"; diff --git a/src/app/mod/tickets/page.tsx b/src/app/mod/tickets/page.tsx index f470b471..9ececc41 100644 --- a/src/app/mod/tickets/page.tsx +++ b/src/app/mod/tickets/page.tsx @@ -1,7 +1,7 @@ -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { StatusCard } from "@/components/admin/dashboard"; import { UnifiedTicketsTable } from "@/components/admin/unified-tickets-table"; +import Link from "@/components/link"; import { requireModPermission } from "@/lib/admin/guard"; import { fetchUnifiedTicketInbox, diff --git a/src/app/mod/users/[id]/page.tsx b/src/app/mod/users/[id]/page.tsx index 6ccac107..1661392b 100644 --- a/src/app/mod/users/[id]/page.tsx +++ b/src/app/mod/users/[id]/page.tsx @@ -1,7 +1,7 @@ import { eq } from "drizzle-orm"; -import Link from "next/link"; import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { requireModPermission } from "@/lib/admin/guard"; import { db, User } from "@/lib/db"; diff --git a/src/app/mod/users/page.tsx b/src/app/mod/users/page.tsx index dd8a2e4d..e3bcda42 100644 --- a/src/app/mod/users/page.tsx +++ b/src/app/mod/users/page.tsx @@ -1,7 +1,7 @@ import { and, asc, count, desc, eq, like, or, type SQL } from "drizzle-orm"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { DataTable } from "@/components/admin/data-table"; +import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { requireModPermission } from "@/lib/admin/guard"; import { calcPagination, parseListParams } from "@/lib/admin-helpers"; diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx index 94e50873..70db4020 100644 --- a/src/app/not-found.tsx +++ b/src/app/not-found.tsx @@ -1,7 +1,7 @@ import { Home, Newspaper } from "lucide-react"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { ErrorScreen } from "@/components/error-screen"; +import Link from "@/components/link"; export default async function NotFound() { const t = await getTranslations("pages.notFound"); diff --git a/src/components/admin/admin-breadcrumb.tsx b/src/components/admin/admin-breadcrumb.tsx index 399c8d1a..1979f7aa 100644 --- a/src/components/admin/admin-breadcrumb.tsx +++ b/src/components/admin/admin-breadcrumb.tsx @@ -1,6 +1,6 @@ import { ChevronRight, Home } from "lucide-react"; -import Link from "next/link"; import { Fragment } from "react"; +import Link from "@/components/link"; export type { BreadcrumbItem } from "@/types/common"; diff --git a/src/components/admin/admin-nav-link.tsx b/src/components/admin/admin-nav-link.tsx index 3f63ba0a..2f49b84d 100644 --- a/src/components/admin/admin-nav-link.tsx +++ b/src/components/admin/admin-nav-link.tsx @@ -1,9 +1,9 @@ "use client"; -import Link from "next/link"; import { usePathname } from "next/navigation"; import type { ReactNode } from "react"; import { useAdminMobile } from "@/components/admin/admin-mobile-wrapper"; +import Link from "@/components/link"; /** * Sidebar link that highlights when its route is active. diff --git a/src/components/admin/admin-section-tabs.tsx b/src/components/admin/admin-section-tabs.tsx index a5dd3bf2..deef62c5 100644 --- a/src/components/admin/admin-section-tabs.tsx +++ b/src/components/admin/admin-section-tabs.tsx @@ -1,8 +1,8 @@ "use client"; -import Link from "next/link"; import { usePathname } from "next/navigation"; import { useTranslations } from "next-intl"; +import Link from "@/components/link"; import { cn } from "@/lib/utils"; export interface AdminTab { diff --git a/src/components/admin/admin-simple-pager.tsx b/src/components/admin/admin-simple-pager.tsx index cbd73d15..b0980d9a 100644 --- a/src/components/admin/admin-simple-pager.tsx +++ b/src/components/admin/admin-simple-pager.tsx @@ -1,4 +1,4 @@ -import Link from "next/link"; +import Link from "@/components/link"; /** Minimal prev/next pager for admin list pages without DataTable. */ export function AdminSimplePager({ diff --git a/src/components/admin/article-card.tsx b/src/components/admin/article-card.tsx index 65ce1215..464534fe 100644 --- a/src/components/admin/article-card.tsx +++ b/src/components/admin/article-card.tsx @@ -1,11 +1,11 @@ "use client"; -import Link from "next/link"; import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { useTransition } from "react"; import { deleteArticle } from "@/actions/admin-articles"; import { useConfirmDialog } from "@/components/admin/confirm-dialog"; +import Link from "@/components/link"; export function ArticleCard({ id, diff --git a/src/components/admin/catalog-manager/inline-editor.tsx b/src/components/admin/catalog-manager/inline-editor.tsx index 42b13d61..8d8fec90 100644 --- a/src/components/admin/catalog-manager/inline-editor.tsx +++ b/src/components/admin/catalog-manager/inline-editor.tsx @@ -11,7 +11,6 @@ import { Save, Settings, } from "lucide-react"; -import Link from "next/link"; import { useCallback, useEffect, useMemo, useState } from "react"; import { toast } from "sonner"; import { updateCatalogPage } from "@/actions/catalog"; @@ -27,6 +26,7 @@ import { IconPicker } from "@/components/admin/catalog/icon-picker"; import { ItemsShopPreview } from "@/components/admin/catalog/items-shop-preview"; import { QuickAddFurni } from "@/components/admin/catalog/quick-add-furni"; import { CatalogIcon, LAYOUT_COLORS } from "@/components/admin/catalog-tree"; +import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; diff --git a/src/components/admin/catalog-tree.tsx b/src/components/admin/catalog-tree.tsx index 5e371ad4..a09db55e 100644 --- a/src/components/admin/catalog-tree.tsx +++ b/src/components/admin/catalog-tree.tsx @@ -21,7 +21,6 @@ import { Trash2, X, } from "lucide-react"; -import Link from "next/link"; import { useRouter } from "next/navigation"; import { createContext, @@ -33,6 +32,7 @@ import { } from "react"; import { toast } from "sonner"; import { useConfirmDialog } from "@/components/admin/confirm-dialog"; +import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { diff --git a/src/components/admin/stats-card.tsx b/src/components/admin/stats-card.tsx index 08b14058..a84255fb 100644 --- a/src/components/admin/stats-card.tsx +++ b/src/components/admin/stats-card.tsx @@ -1,5 +1,5 @@ import { Minus, TrendingDown, TrendingUp } from "lucide-react"; -import Link from "next/link"; +import Link from "@/components/link"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; interface StatsCardProps { diff --git a/src/components/admin/ticket-queue-banner.tsx b/src/components/admin/ticket-queue-banner.tsx index d62058c9..7264badd 100644 --- a/src/components/admin/ticket-queue-banner.tsx +++ b/src/components/admin/ticket-queue-banner.tsx @@ -1,4 +1,4 @@ -import Link from "next/link"; +import Link from "@/components/link"; /** Shared clarity banner for dual ticket products (CMS desk vs help-center). */ export function TicketQueueBanner({ diff --git a/src/components/admin/unified-tickets-table.tsx b/src/components/admin/unified-tickets-table.tsx index dfd16fd3..991d777b 100644 --- a/src/components/admin/unified-tickets-table.tsx +++ b/src/components/admin/unified-tickets-table.tsx @@ -1,8 +1,8 @@ "use client"; -import Link from "next/link"; import { useTranslations } from "next-intl"; import { DataTable } from "@/components/admin/data-table"; +import Link from "@/components/link"; import { Badge } from "@/components/ui/badge"; import type { TicketInboxRow } from "@/lib/admin/ticket-inbox"; import type { DataTableColumn, PaginatedResult } from "@/types/common"; diff --git a/src/components/auth/login-form.tsx b/src/components/auth/login-form.tsx index f76d7801..e293e94d 100644 --- a/src/components/auth/login-form.tsx +++ b/src/components/auth/login-form.tsx @@ -1,6 +1,5 @@ "use client"; -import Link from "next/link"; import { signIn } from "next-auth/react"; import { useTranslations } from "next-intl"; import { type FormEvent, useState } from "react"; @@ -10,6 +9,7 @@ import { CaptchaWidget, readCaptchaToken, } from "@/components/auth/captcha-widget"; +import Link from "@/components/link"; import { signInWithTransientRetry } from "@/lib/auth/sign-in-retry"; export function LoginForm({ diff --git a/src/components/auth/register-form.tsx b/src/components/auth/register-form.tsx index 398bf968..69be714f 100644 --- a/src/components/auth/register-form.tsx +++ b/src/components/auth/register-form.tsx @@ -1,12 +1,12 @@ "use client"; import Image from "next/image"; -import Link from "next/link"; import Script from "next/script"; import { signIn } from "next-auth/react"; import { useTranslations } from "next-intl"; import { useActionState, useEffect, useRef, useState } from "react"; import { type RegisterState, register } from "@/actions/register"; +import Link from "@/components/link"; import { signInWithTransientRetry } from "@/lib/auth/sign-in-retry"; interface RegisterFormProps { diff --git a/src/components/link.tsx b/src/components/link.tsx new file mode 100644 index 00000000..88053aeb --- /dev/null +++ b/src/components/link.tsx @@ -0,0 +1,6 @@ +import NextLink from "next/link"; +import type { ComponentProps } from "react"; + +export default function Link(props: ComponentProps) { + return ; +} diff --git a/src/components/navigation.tsx b/src/components/navigation.tsx index 9da9d14f..95b65ead 100644 --- a/src/components/navigation.tsx +++ b/src/components/navigation.tsx @@ -1,9 +1,9 @@ import { count, eq } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import type { Session } from "next-auth"; import { getTranslations } from "next-intl/server"; import { LanguageSwitcher } from "@/components/language-switcher"; +import Link from "@/components/link"; import { MobileNav } from "@/components/mobile-nav"; import { NavDropdown } from "@/components/nav-dropdown"; import { NavbarColorPicker } from "@/components/navbar-color-picker"; diff --git a/src/components/site-header.tsx b/src/components/site-header.tsx index 6ca95772..4fcfe59b 100644 --- a/src/components/site-header.tsx +++ b/src/components/site-header.tsx @@ -1,7 +1,7 @@ import { count, eq } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import { getTranslations } from "next-intl/server"; +import Link from "@/components/link"; import { cached } from "@/lib/cache"; import { db, User } from "@/lib/db"; import { resolveHotelName } from "@/lib/hotel-name"; diff --git a/src/components/surface-card.tsx b/src/components/surface-card.tsx index 6782784f..19c2722f 100644 --- a/src/components/surface-card.tsx +++ b/src/components/surface-card.tsx @@ -1,6 +1,6 @@ import Image from "next/image"; -import Link from "next/link"; import type { CSSProperties, ReactNode } from "react"; +import Link from "@/components/link"; const CARD_BORDER = "color-mix(in srgb, var(--color-text-muted) 12%, transparent)"; diff --git a/src/components/top-header.tsx b/src/components/top-header.tsx index 646a7a67..6fb3ceb9 100644 --- a/src/components/top-header.tsx +++ b/src/components/top-header.tsx @@ -1,9 +1,9 @@ import { count, eq, inArray } from "drizzle-orm"; import Image from "next/image"; -import Link from "next/link"; import type { Session } from "next-auth"; import { getTranslations } from "next-intl/server"; import { HeaderUserIdentity } from "@/components/header-user-identity"; +import Link from "@/components/link"; import { RoomQuickEntry } from "@/components/room-quick-entry"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { signOut } from "@/lib/auth"; diff --git a/src/features/housekeeping/foundation/shell/context-nav.tsx b/src/features/housekeeping/foundation/shell/context-nav.tsx index 46926fb0..d89baae1 100644 --- a/src/features/housekeeping/foundation/shell/context-nav.tsx +++ b/src/features/housekeeping/foundation/shell/context-nav.tsx @@ -1,4 +1,4 @@ -import Link from "next/link"; +import Link from "@/components/link"; interface ContextNavProps { items: readonly { id: string; href: string; label: string }[]; diff --git a/src/features/housekeeping/foundation/shell/domain-rail.tsx b/src/features/housekeeping/foundation/shell/domain-rail.tsx index 9bcdc5a6..da85cc3c 100644 --- a/src/features/housekeeping/foundation/shell/domain-rail.tsx +++ b/src/features/housekeeping/foundation/shell/domain-rail.tsx @@ -1,5 +1,5 @@ import { FileText, Gem, Hotel, Inbox, Settings, Users } from "lucide-react"; -import Link from "next/link"; +import Link from "@/components/link"; import type { HousekeepingNavigationDomain } from "../navigation"; interface DomainRailProps { diff --git a/src/features/housekeeping/foundation/shell/housekeeping-shell.tsx b/src/features/housekeeping/foundation/shell/housekeeping-shell.tsx index 921db4ce..4c8b6dfe 100644 --- a/src/features/housekeeping/foundation/shell/housekeeping-shell.tsx +++ b/src/features/housekeeping/foundation/shell/housekeeping-shell.tsx @@ -1,5 +1,5 @@ -import Link from "next/link"; import type { ReactNode } from "react"; +import Link from "@/components/link"; import type { HousekeepingDomainId } from "../../migration/types"; import type { HousekeepingActor } from "../contracts"; import type { HousekeepingNavigationDomain } from "../navigation";