From f430560894992493fb167d88eb60ec041ac6bd28 Mon Sep 17 00:00:00 2001 From: Ajit Pratap Singh Date: Thu, 26 Mar 2026 10:33:19 +0530 Subject: [PATCH 1/2] fix: resolve Sentry hydration mismatch and suppress extension noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FadeIn.tsx — fix SSR hydration mismatch (Sentry #104333516, #104333514): Framer Motion applies initial={{ opacity:0, y:16 }} before React hydrates, causing the server-rendered DOM (opacity:1) to mismatch the client DOM. Fix: render a plain
on server + during hydration (isMounted=false), then swap to after useEffect fires. No mismatch, no flash. instrumentation-client.ts — filter browser extension noise (Sentry #106232192, #105431404): Add beforeSend hook to drop two known extension-only error patterns: - "Cannot assign to read only property 'pushState'" — extensions wrap history.pushState before the app loads, making it read-only - "Object Not Found Matching Id:N, MethodName:update" — Chrome DevTools Protocol messages from extensions interacting with CodeMirror GitHub issue #435 (Object Not Found) closed as noise. Issues #436/#437 (hydration) resolved by the FadeIn fix. Issue #434 (pushState) silenced via beforeSend filter. Co-Authored-By: Claude Sonnet 4.6 --- website/src/components/ui/FadeIn.tsx | 17 ++++++++++++++++- website/src/instrumentation-client.ts | 21 +++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/website/src/components/ui/FadeIn.tsx b/website/src/components/ui/FadeIn.tsx index d3ccdd31..53651c35 100644 --- a/website/src/components/ui/FadeIn.tsx +++ b/website/src/components/ui/FadeIn.tsx @@ -1,9 +1,24 @@ 'use client'; import { motion, useReducedMotion } from 'framer-motion'; -import { ReactNode } from 'react'; +import { ReactNode, useState, useEffect } from 'react'; export function FadeIn({ children, delay = 0, className = '' }: { children: ReactNode; delay?: number; className?: string }) { const shouldReduce = useReducedMotion(); + const [isMounted, setIsMounted] = useState(false); + + // Defer Framer Motion's initial state until after hydration. Without this, + // Framer Motion applies initial={{ opacity: 0 }} before React hydrates, causing + // the server-rendered HTML (opacity:1) to mismatch the client DOM (opacity:0). + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) { + // Server + hydration pass: render without Framer Motion so the DOM matches + // the server HTML exactly. No opacity/transform styles applied. + return
{children}
; + } + return ( Date: Thu, 26 Mar 2026 12:54:31 +0530 Subject: [PATCH 2/2] fix: address PR review suggestions for #439 - Wrap FadeIn in memo() to prevent unnecessary re-renders from parent state changes that don't affect the component's own props - Log suppressed extension noise errors to console.debug in development so they remain visible locally while staying off Sentry in production Co-Authored-By: Claude Sonnet 4.6 --- website/src/components/ui/FadeIn.tsx | 6 +++--- website/src/instrumentation-client.ts | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/website/src/components/ui/FadeIn.tsx b/website/src/components/ui/FadeIn.tsx index 53651c35..ce1b4096 100644 --- a/website/src/components/ui/FadeIn.tsx +++ b/website/src/components/ui/FadeIn.tsx @@ -1,8 +1,8 @@ 'use client'; import { motion, useReducedMotion } from 'framer-motion'; -import { ReactNode, useState, useEffect } from 'react'; +import { ReactNode, useState, useEffect, memo } from 'react'; -export function FadeIn({ children, delay = 0, className = '' }: { children: ReactNode; delay?: number; className?: string }) { +export const FadeIn = memo(function FadeIn({ children, delay = 0, className = '' }: { children: ReactNode; delay?: number; className?: string }) { const shouldReduce = useReducedMotion(); const [isMounted, setIsMounted] = useState(false); @@ -29,4 +29,4 @@ export function FadeIn({ children, delay = 0, className = '' }: { children: Reac {children} ); -} +}); diff --git a/website/src/instrumentation-client.ts b/website/src/instrumentation-client.ts index fed26363..1a27bbab 100644 --- a/website/src/instrumentation-client.ts +++ b/website/src/instrumentation-client.ts @@ -24,10 +24,14 @@ Sentry.init({ // 2. "Object Not Found Matching Id:N, MethodName:update" — Chrome DevTools // Protocol messages from extensions interacting with CodeMirror/Monaco. // The error originates outside our code and only affects a single session. - if ( + const isExtensionNoise = msg.includes("Cannot assign to read only property 'pushState'") || - msg.includes("Object Not Found Matching Id:") - ) { + msg.includes("Object Not Found Matching Id:"); + + if (isExtensionNoise) { + if (process.env.NODE_ENV === "development") { + console.debug("[Sentry] Suppressed extension noise:", msg); + } return null; }