From 55a08301f4b20984571759c8724ec73b3cd2f01b Mon Sep 17 00:00:00 2001 From: Usman Baig Date: Mon, 23 Mar 2026 13:29:53 +0100 Subject: [PATCH] fix(build): extract FAVICON_SERVICE_URL to prevent server-side createContext error The share/[id] layout is a server component that imported FAVICON_SERVICE_URL from icons.tsx, pulling in the entire React icon registry and triggering createContext on the server. Moved the constant to its own favicon.ts module. --- app/share/[id]/layout.tsx | 2 +- app/share/[id]/page.tsx | 2 +- components/dashboard/Sidebar.tsx | 2 +- components/sites/SiteList.tsx | 2 +- lib/utils/favicon.ts | 8 ++++++++ lib/utils/icons.tsx | 7 ++----- 6 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 lib/utils/favicon.ts diff --git a/app/share/[id]/layout.tsx b/app/share/[id]/layout.tsx index 60de8ee..7a0189e 100644 --- a/app/share/[id]/layout.tsx +++ b/app/share/[id]/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from 'next' -import { FAVICON_SERVICE_URL } from '@/lib/utils/icons' +import { FAVICON_SERVICE_URL } from '@/lib/utils/favicon' const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8082' diff --git a/app/share/[id]/page.tsx b/app/share/[id]/page.tsx index 780c17f..c5b00b9 100644 --- a/app/share/[id]/page.tsx +++ b/app/share/[id]/page.tsx @@ -16,7 +16,7 @@ import TechSpecs from '@/components/dashboard/TechSpecs' import { Select, DatePicker as DatePickerModal, Captcha, DownloadIcon, ZapIcon } from '@ciphera-net/ui' import { DashboardSkeleton, useMinimumLoading, useSkeletonFade } from '@/components/skeletons' import ExportModal from '@/components/dashboard/ExportModal' -import { FAVICON_SERVICE_URL } from '@/lib/utils/icons' +import { FAVICON_SERVICE_URL } from '@/lib/utils/favicon' // Helper to get date ranges const getDateRange = (days: number) => { diff --git a/components/dashboard/Sidebar.tsx b/components/dashboard/Sidebar.tsx index 284208d..b5d514b 100644 --- a/components/dashboard/Sidebar.tsx +++ b/components/dashboard/Sidebar.tsx @@ -9,7 +9,7 @@ import { useSettingsModal } from '@/lib/settings-modal-context' import { getUserOrganizations, switchContext, type OrganizationMember } from '@/lib/api/organization' import { setSessionAction } from '@/app/actions/auth' import { logger } from '@/lib/utils/logger' -import { FAVICON_SERVICE_URL } from '@/lib/utils/icons' +import { FAVICON_SERVICE_URL } from '@/lib/utils/favicon' import { Gauge as GaugeIcon } from '@phosphor-icons/react' import { LayoutDashboardIcon, diff --git a/components/sites/SiteList.tsx b/components/sites/SiteList.tsx index ea15114..7480442 100644 --- a/components/sites/SiteList.tsx +++ b/components/sites/SiteList.tsx @@ -7,7 +7,7 @@ import type { Stats } from '@/lib/api/stats' import { formatNumber } from '@ciphera-net/ui' import { BarChartIcon, SettingsIcon, BookOpenIcon, ExternalLinkIcon, Button } from '@ciphera-net/ui' import { useAuth } from '@/lib/auth/context' -import { FAVICON_SERVICE_URL } from '@/lib/utils/icons' +import { FAVICON_SERVICE_URL } from '@/lib/utils/favicon' export type SiteStatsMap = Record diff --git a/lib/utils/favicon.ts b/lib/utils/favicon.ts new file mode 100644 index 0000000..8e77df8 --- /dev/null +++ b/lib/utils/favicon.ts @@ -0,0 +1,8 @@ +/** + * Google's public favicon service base URL. + * Append `?domain=&sz=` to get a favicon. + * + * Kept in a separate module so server components can import it + * without pulling in the React-dependent icon registry. + */ +export const FAVICON_SERVICE_URL = 'https://www.google.com/s2/favicons' diff --git a/lib/utils/icons.tsx b/lib/utils/icons.tsx index d6a3d8d..71b1f28 100644 --- a/lib/utils/icons.tsx +++ b/lib/utils/icons.tsx @@ -43,11 +43,8 @@ function BingIcon({ size = 16, color = '#258FFA' }: { size?: number; color?: str return } -/** - * Google's public favicon service base URL. - * Append `?domain=&sz=` to get a favicon. - */ -export const FAVICON_SERVICE_URL = 'https://www.google.com/s2/favicons' +import { FAVICON_SERVICE_URL } from './favicon' +export { FAVICON_SERVICE_URL } // ─── Browser, OS, Device icons (unchanged) ───────────────────────────────────