From baada1457ac8805b4f5cd232535d9c8b48ccf448 Mon Sep 17 00:00:00 2001 From: SohamBhattacharjee2003 <125297948+SohamBhattacharjee2003@users.noreply.github.com> Date: Wed, 8 Apr 2026 04:28:41 +0530 Subject: [PATCH 1/2] fix: replace window.location with Next.js router for client-side navigation - Replace window.location.href with router.push() + router.refresh() in UserDropdown logout - Replace window.location.href with router.push() in CreateSearchSpaceDialog - Replace window.location.reload() with router.refresh() in login page retry action - Prevents full page reloads and preserves React state during in-app navigation --- surfsense_web/app/(home)/login/page.tsx | 4 +++- surfsense_web/components/UserDropdown.tsx | 12 ++++++------ .../layout/ui/dialogs/CreateSearchSpaceDialog.tsx | 5 +++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/surfsense_web/app/(home)/login/page.tsx b/surfsense_web/app/(home)/login/page.tsx index 09bf770d8..161951d97 100644 --- a/surfsense_web/app/(home)/login/page.tsx +++ b/surfsense_web/app/(home)/login/page.tsx @@ -1,6 +1,7 @@ "use client"; import { AnimatePresence, motion } from "motion/react"; +import { useRouter } from "next/navigation"; import { useSearchParams } from "next/navigation"; import { useTranslations } from "next-intl"; import { Suspense, useEffect, useState } from "react"; @@ -16,6 +17,7 @@ import { LocalLoginForm } from "./LocalLoginForm"; function LoginContent() { const t = useTranslations("auth"); const tCommon = useTranslations("common"); + const router = useRouter(); const [authType, setAuthType] = useState(null); const [isLoading, setIsLoading] = useState(true); const [urlError, setUrlError] = useState<{ title: string; message: string } | null>(null); @@ -79,7 +81,7 @@ function LoginContent() { if (shouldRetry(error)) { toastOptions.action = { label: "Retry", - onClick: () => window.location.reload(), + onClick: () => router.refresh(), }; } diff --git a/surfsense_web/components/UserDropdown.tsx b/surfsense_web/components/UserDropdown.tsx index 197db6287..17a1e0d6d 100644 --- a/surfsense_web/components/UserDropdown.tsx +++ b/surfsense_web/components/UserDropdown.tsx @@ -2,6 +2,7 @@ import { BadgeCheck, LogOut } from "lucide-react"; import Link from "next/link"; +import { useRouter } from "next/navigation"; import { useState } from "react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; @@ -27,6 +28,7 @@ export function UserDropdown({ avatar: string; }; }) { + const router = useRouter(); const [isLoggingOut, setIsLoggingOut] = useState(false); const handleLogout = async () => { @@ -40,16 +42,14 @@ export function UserDropdown({ // Revoke refresh token on server and clear all tokens from localStorage await logout(); - if (typeof window !== "undefined") { - window.location.href = "/"; - } + router.push("/"); + router.refresh(); } catch (error) { console.error("Error during logout:", error); // Even if there's an error, try to clear tokens and redirect await logout(); - if (typeof window !== "undefined") { - window.location.href = "/"; - } + router.push("/"); + router.refresh(); } }; diff --git a/surfsense_web/components/layout/ui/dialogs/CreateSearchSpaceDialog.tsx b/surfsense_web/components/layout/ui/dialogs/CreateSearchSpaceDialog.tsx index e39bee679..7d0ef73d2 100644 --- a/surfsense_web/components/layout/ui/dialogs/CreateSearchSpaceDialog.tsx +++ b/surfsense_web/components/layout/ui/dialogs/CreateSearchSpaceDialog.tsx @@ -2,6 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { useAtomValue } from "jotai"; +import { useRouter } from "next/navigation"; import { useTranslations } from "next-intl"; import { useState } from "react"; import { useForm } from "react-hook-form"; @@ -43,6 +44,7 @@ interface CreateSearchSpaceDialogProps { export function CreateSearchSpaceDialog({ open, onOpenChange }: CreateSearchSpaceDialogProps) { const t = useTranslations("searchSpace"); const tCommon = useTranslations("common"); + const router = useRouter(); const [isSubmitting, setIsSubmitting] = useState(false); const { mutateAsync: createSearchSpace } = useAtomValue(createSearchSpaceMutationAtom); @@ -65,8 +67,7 @@ export function CreateSearchSpaceDialog({ open, onOpenChange }: CreateSearchSpac trackSearchSpaceCreated(result.id, values.name); - // Hard redirect to ensure fresh state - window.location.href = `/dashboard/${result.id}/onboard`; + router.push(`/dashboard/${result.id}/onboard`); } catch (error) { console.error("Failed to create search space:", error); setIsSubmitting(false); From 4066cbc6f0b65cfb9f0fce62b7849498cbe1c823 Mon Sep 17 00:00:00 2001 From: SohamBhattacharjee2003 <125297948+SohamBhattacharjee2003@users.noreply.github.com> Date: Wed, 8 Apr 2026 04:39:39 +0530 Subject: [PATCH 2/2] fix: remove unnecessary 'use client' directives to reduce client bundle - Remove 'use client' from connector-document-mapping.ts (only exports constants and pure functions) - Remove 'use client' from sidebar-separator.tsx (purely presentational component) - Remove 'use client' and Framer Motion from logs/loading.tsx, replace with Tailwind animations - Reduces client bundle size by moving server-compatible code to server components --- .../[search_space_id]/logs/loading.tsx | 64 ++++--------------- surfsense_web/app/docs/sidebar-separator.tsx | 2 - .../utils/connector-document-mapping.ts | 2 - 3 files changed, 14 insertions(+), 54 deletions(-) diff --git a/surfsense_web/app/dashboard/[search_space_id]/logs/loading.tsx b/surfsense_web/app/dashboard/[search_space_id]/logs/loading.tsx index 961ca468e..e8ea64890 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/logs/loading.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/logs/loading.tsx @@ -1,22 +1,10 @@ -"use client"; - -import { motion } from "motion/react"; import { Skeleton } from "@/components/ui/skeleton"; export default function Loading() { return ( - +
{/* Summary Dashboard Skeleton */} - +
{[...Array(4)].map((_, i) => (
@@ -29,44 +17,29 @@ export default function Loading() {
))} - +
{/* Header Section Skeleton */} - +
- +
{/* Filters Skeleton */} - +
- +
{/* Table Skeleton */} - +
{/* Table Header */}
@@ -99,27 +72,18 @@ export default function Loading() {
))} - +
{/* Pagination Skeleton */}
- +
- +
- +
- +
@@ -128,6 +92,6 @@ export default function Loading() {
-
+
); } diff --git a/surfsense_web/app/docs/sidebar-separator.tsx b/surfsense_web/app/docs/sidebar-separator.tsx index 36fff09a4..ceb56b160 100644 --- a/surfsense_web/app/docs/sidebar-separator.tsx +++ b/surfsense_web/app/docs/sidebar-separator.tsx @@ -1,5 +1,3 @@ -"use client"; - import type { Separator } from "fumadocs-core/page-tree"; export function SidebarSeparator({ item }: { item: Separator }) { diff --git a/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts b/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts index f924bb15f..d194fd0ed 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts +++ b/surfsense_web/components/assistant-ui/connector-popup/utils/connector-document-mapping.ts @@ -1,5 +1,3 @@ -"use client"; - /** * Maps SearchSourceConnectorType to DocumentType for fetching document counts *