Conversation
✅ Deploy Preview for tanstack ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe pull request adds Mermaid diagram rendering support to markdown CodeBlocks. When a code block specifies Changes
Sequence DiagramsequenceDiagram
participant User
participant CodeBlock
participant MermaidBlock
participant Mermaid as Mermaid Library
participant DOM
User->>CodeBlock: Render with lang='mermaid'
CodeBlock->>CodeBlock: Detect mermaid language
CodeBlock->>MermaidBlock: Route to MermaidBlock
MermaidBlock->>MermaidBlock: Initialize dark mode tracking
MermaidBlock->>DOM: Render placeholder CodeBlockView
MermaidBlock->>Mermaid: Dynamic import
MermaidBlock->>Mermaid: Initialize with theme (dark/default)
Mermaid->>Mermaid: Render code to SVG
MermaidBlock->>MermaidBlock: Update state with SVG
MermaidBlock->>DOM: Replace placeholder with SVG diagram
DOM->>User: Display interactive diagram
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/components/markdown/MermaidBlock.tsx (2)
61-65: Nit:useMemohere is unnecessary.
reactIdfromuseIdis already stable across renders of the same component instance, somermaidIdcan be computed with a plainconst(or inlined into the effect). Not a behavior issue — just dead ceremony.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/markdown/MermaidBlock.tsx` around lines 61 - 65, The mermaidId is computed with React.useMemo unnecessarily; replace the React.useMemo call with a plain constant computed from reactId (which comes from React.useId and is stable) — e.g., compute mermaidId = `mermaid-${reactId.replace(/[^a-zA-Z0-9_-]/g, '')}` directly in the MermaidBlock component (or inline where used) and remove the useMemo import/usage to simplify code.
26-43: Consider usinguseTheme()from ThemeProvider instead of implementingMutationObserverto detect theme changes.ThemeProvider (lines 43–71) already owns and publishes the
light/darkclass state ondocumentElementvia the exporteduseThemehook. MermaidBlock's customuseIsDarkMode(lines 26–43) reimplements this by observing the same class mutations directly.MutationObserver fires for every class change ThemeProvider makes — including transient toggles like adding
theme-switchingbefore updating to the final theme. Additionally, checking DOM state directly couples MermaidBlock to ThemeProvider's implementation detail.Instead, replace
useIsDarkModewith:const { resolvedTheme } = useTheme() const isDark = resolvedTheme === 'dark'This is simpler, avoids DOM-coupling, and ensures MermaidBlock always sees the consistent theme state.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/markdown/MermaidBlock.tsx` around lines 26 - 43, The custom hook useIsDarkMode reimplements theme detection via a MutationObserver; replace it by importing and using the ThemeProvider hook: call useTheme() (import from ThemeProvider), derive const isDark = resolvedTheme === 'dark', remove the MutationObserver-based useIsDarkMode function and any references to it, and update MermaidBlock to consume the new isDark variable where needed so it relies on ThemeProvider's resolvedTheme instead of DOM class mutations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/markdown/MermaidBlock.tsx`:
- Around line 90-117: The catch block inside the useEffect's renderMermaid flow
currently sets renderState to 'error' but neither logs the caught error nor
provides a distinct UI; update the catch to capture the error object, call
processLogger/error console (or existing logging utility) with the error and
context (e.g., mermaidId, code), call setRenderState({ status: 'error', error })
and then change the render branch that currently returns CodeBlockView when
renderState.status !== 'rendered' to distinguish 'loading' vs 'error' (e.g.,
when renderState.status === 'error' render CodeBlockView with an augmented title
like `${title ?? ''} (mermaid render failed)` or display a small inline error
message above the fallback) so parse failures are logged and visibly indicated
to authors; reference functions/identifiers: renderMermaid, setRenderState,
renderState, CodeBlockView, mermaidId, and code.
---
Nitpick comments:
In `@src/components/markdown/MermaidBlock.tsx`:
- Around line 61-65: The mermaidId is computed with React.useMemo unnecessarily;
replace the React.useMemo call with a plain constant computed from reactId
(which comes from React.useId and is stable) — e.g., compute mermaidId =
`mermaid-${reactId.replace(/[^a-zA-Z0-9_-]/g, '')}` directly in the MermaidBlock
component (or inline where used) and remove the useMemo import/usage to simplify
code.
- Around line 26-43: The custom hook useIsDarkMode reimplements theme detection
via a MutationObserver; replace it by importing and using the ThemeProvider
hook: call useTheme() (import from ThemeProvider), derive const isDark =
resolvedTheme === 'dark', remove the MutationObserver-based useIsDarkMode
function and any references to it, and update MermaidBlock to consume the new
isDark variable where needed so it relies on ThemeProvider's resolvedTheme
instead of DOM class mutations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3325a1eb-a2cc-4354-a6fd-0c74257a2a3b
📒 Files selected for processing (3)
src/components/markdown/CodeBlock.server.tsxsrc/components/markdown/CodeBlock.tsxsrc/components/markdown/MermaidBlock.tsx
| } catch { | ||
| if (!cancelled) { | ||
| setRenderState({ status: 'error' }) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void renderMermaid() | ||
|
|
||
| return () => { | ||
| cancelled = true | ||
| } | ||
| }, [code, isDark, mermaidId]) | ||
|
|
||
| if (renderState.status !== 'rendered') { | ||
| return ( | ||
| <CodeBlockView | ||
| className={className} | ||
| copyText={code.trimEnd()} | ||
| htmlMarkup={buildPlainCodeBlockHtml(code)} | ||
| isEmbedded={isEmbedded} | ||
| lang="mermaid" | ||
| showTypeCopyButton={showTypeCopyButton} | ||
| style={style} | ||
| title={title} | ||
| /> | ||
| ) | ||
| } |
There was a problem hiding this comment.
Error state is indistinguishable from the loading state and silently hides render failures.
On catch, renderState becomes 'error' but the UI renders the exact same CodeBlockView with the raw mermaid source as the 'loading' state does. A malformed diagram will therefore appear as a normal code block with no feedback that rendering failed — both to the user and to anyone debugging. At minimum, log the caught error (mermaid throws informative parse errors) and render a distinct error surface so authors can tell the difference.
🛠️ Suggested change
- } catch {
+ } catch (error) {
if (!cancelled) {
+ console.error('Failed to render mermaid diagram', error)
setRenderState({ status: 'error' })
}
}And branch the render so the error path is visible (e.g., render CodeBlockView with an added title like `${title ?? ''} (mermaid render failed)` or a small inline error message above the fallback).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/markdown/MermaidBlock.tsx` around lines 90 - 117, The catch
block inside the useEffect's renderMermaid flow currently sets renderState to
'error' but neither logs the caught error nor provides a distinct UI; update the
catch to capture the error object, call processLogger/error console (or existing
logging utility) with the error and context (e.g., mermaidId, code), call
setRenderState({ status: 'error', error }) and then change the render branch
that currently returns CodeBlockView when renderState.status !== 'rendered' to
distinguish 'loading' vs 'error' (e.g., when renderState.status === 'error'
render CodeBlockView with an augmented title like `${title ?? ''} (mermaid
render failed)` or display a small inline error message above the fallback) so
parse failures are logged and visibly indicated to authors; reference
functions/identifiers: renderMermaid, setRenderState, renderState,
CodeBlockView, mermaidId, and code.

Summary by CodeRabbit