From 97aac58e55ec68c3dfaeddfe0dcfbc681728ecd5 Mon Sep 17 00:00:00 2001 From: waleed Date: Wed, 1 Jul 2026 17:30:41 -0700 Subject: [PATCH] fix(integrations): resolve Server Components crash on the integration detail page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause (confirmed via staging server logs, digest 783665031): the [block] page.tsx is a server component whose Suspense fallback rendered — passing the lucide icon (a function) across the server->client boundary, which React rejects ("Functions cannot be passed directly to Client Components"). This surfaced as the integrations error boundary / "Failed to load integrations" on soft navigation to a detail page. Move the fallback into a client component so the icon never crosses the boundary. --- .../integration-block-detail-fallback.tsx | 33 +++++++++++++++++++ .../integrations/[block]/page.tsx | 15 ++------- 2 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail-fallback.tsx diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail-fallback.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail-fallback.tsx new file mode 100644 index 00000000000..e634e7806e7 --- /dev/null +++ b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail-fallback.tsx @@ -0,0 +1,33 @@ +'use client' + +import { ChipLink } from '@sim/emcn' +import { ArrowLeft } from 'lucide-react' + +interface IntegrationBlockDetailFallbackProps { + workspaceId: string +} + +/** + * Suspense fallback for the integration detail page — the back-link chrome + * shown while {@link IntegrationBlockDetail} hydrates. + * + * This MUST be a client component. The lucide `ArrowLeft` passed as `ChipLink`'s + * `leftIcon` is a function, and functions cannot cross the server→client + * boundary as props. Rendering the fallback from the server `page.tsx` directly + * threw a React Server Components error ("Functions cannot be passed directly to + * Client Components") that surfaced as the integrations error boundary. Keeping + * the icon inside a client component avoids the boundary crossing entirely. + */ +export function IntegrationBlockDetailFallback({ + workspaceId, +}: IntegrationBlockDetailFallbackProps) { + return ( +
+
+ + Integrations + +
+
+ ) +} diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/[block]/page.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/page.tsx index e3472de9b1a..d7765df9eb5 100644 --- a/apps/sim/app/workspace/[workspaceId]/integrations/[block]/page.tsx +++ b/apps/sim/app/workspace/[workspaceId]/integrations/[block]/page.tsx @@ -1,10 +1,9 @@ import { Suspense } from 'react' -import { ChipLink } from '@sim/emcn' -import { ArrowLeft } from 'lucide-react' import type { Metadata } from 'next' import { notFound } from 'next/navigation' import { INTEGRATIONS } from '@/lib/integrations' import { IntegrationBlockDetail } from '@/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail' +import { IntegrationBlockDetailFallback } from '@/app/workspace/[workspaceId]/integrations/[block]/integration-block-detail-fallback' export async function generateMetadata({ params, @@ -28,17 +27,7 @@ export default async function IntegrationBlockPage({ if (!integration) notFound() return ( - -
- - Integrations - -
- - } - > + }> )