diff --git a/apps/sim/app/chat/components/message/components/markdown-renderer.tsx b/apps/sim/app/chat/components/message/components/markdown-renderer.tsx index ba69814cfc..8aa66579d5 100644 --- a/apps/sim/app/chat/components/message/components/markdown-renderer.tsx +++ b/apps/sim/app/chat/components/message/components/markdown-renderer.tsx @@ -1,4 +1,4 @@ -import React, { type HTMLAttributes, type ReactNode } from 'react' +import React, { type HTMLAttributes, memo, type ReactNode, useMemo } from 'react' import ReactMarkdown from 'react-markdown' import remarkGfm from 'remark-gfm' import { Tooltip } from '@/components/emcn' @@ -23,24 +23,16 @@ export function LinkWithPreview({ href, children }: { href: string; children: Re ) } -export default function MarkdownRenderer({ - content, - customLinkComponent, -}: { - content: string - customLinkComponent?: typeof LinkWithPreview -}) { - const LinkComponent = customLinkComponent || LinkWithPreview +const REMARK_PLUGINS = [remarkGfm] - const customComponents = { - // Paragraph +function createCustomComponents(LinkComponent: typeof LinkWithPreview) { + return { p: ({ children }: React.HTMLAttributes) => (

{children}

), - // Headings h1: ({ children }: React.HTMLAttributes) => (

{children} @@ -62,7 +54,6 @@ export default function MarkdownRenderer({

), - // Lists ul: ({ children }: React.HTMLAttributes) => (
    ), - // Code blocks pre: ({ children }: HTMLAttributes) => { let codeProps: HTMLAttributes = {} let codeContent: ReactNode = children @@ -120,7 +110,6 @@ export default function MarkdownRenderer({ ) }, - // Inline code code: ({ inline, className, @@ -144,24 +133,20 @@ export default function MarkdownRenderer({ ) }, - // Blockquotes blockquote: ({ children }: React.HTMLAttributes) => (
    {children}
    ), - // Horizontal rule hr: () =>
    , - // Links a: ({ href, children, ...props }: React.AnchorHTMLAttributes) => ( {children} ), - // Tables table: ({ children }: React.TableHTMLAttributes) => (
    @@ -193,7 +178,6 @@ export default function MarkdownRenderer({ ), - // Images img: ({ src, alt, ...props }: React.ImgHTMLAttributes) => ( ), } +} + +const DEFAULT_COMPONENTS = createCustomComponents(LinkWithPreview) + +const MarkdownRenderer = memo(function MarkdownRenderer({ + content, + customLinkComponent, +}: { + content: string + customLinkComponent?: typeof LinkWithPreview +}) { + const components = useMemo(() => { + if (!customLinkComponent) { + return DEFAULT_COMPONENTS + } + return createCustomComponents(customLinkComponent) + }, [customLinkComponent]) - // Pre-process content to fix common issues const processedContent = content.trim() return (
    - + {processedContent}
    ) -} +}) + +export default MarkdownRenderer diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index 166b260af8..6ab3aae353 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -7,7 +7,7 @@ import { generateBrandedMetadata, generateStructuredData } from '@/lib/branding/ import { PostHogProvider } from '@/app/_shell/providers/posthog-provider' import '@/app/_styles/globals.css' import { OneDollarStats } from '@/components/analytics/onedollarstats' -import { isReactGrabEnabled } from '@/lib/core/config/feature-flags' +import { isReactGrabEnabled, isReactScanEnabled } from '@/lib/core/config/feature-flags' import { HydrationErrorHandler } from '@/app/_shell/hydration-error-handler' import { QueryProvider } from '@/app/_shell/providers/query-provider' import { SessionProvider } from '@/app/_shell/providers/session-provider' @@ -35,6 +35,13 @@ export default function RootLayout({ children }: { children: React.ReactNode }) return ( + {isReactScanEnabled && ( +