Conversation
- New flow-builder.mdx with iframe embedding the visualizer - Bidirectional theme sync via postMessage with theme-request handshake - Full-bleed fixed container (desktop 112px, mobile 120px offset) - Hide Mintlify chrome: header, page title, pagination, breadcrumb text - Replace breadcrumb with hamburger + (0, 0, 0) label - Prevent outer page scroll when flow-builder is active - Kill Mintlify's aspect-ratio wrapper on iframe - Flash prevention via document.write in head.raw Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace sandbox access CTA with flow builder entry point: "Ready to build? Get the API calls for your exact use case" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Title: "Build your flow" → "Build your flow - Grid API Documentation" Description: removed "payment" to reflect broader use cases Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Greptile SummaryAdded Flow Builder iframe embed page with theme synchronization between docs and embedded visualizer, updated homepage CTA to promote the new flow builder tool, and added OG metadata for link previews. Key changes:
Issues found:
Confidence Score: 2/5
|
| Filename | Overview |
|---|---|
| mintlify/flow-builder.mdx | New Flow Builder page with iframe embed and theme sync - violates style guide by using React.useEffect, has postMessage security issues |
| mintlify/docs.json | Added "Build your flow" tab navigation and page-hiding CSS for flow-builder page |
| mintlify/index.mdx | Updated homepage banner CTA from sandbox access to flow builder with new copy and link |
| mintlify/style.css | Added full-viewport iframe styles with responsive layout and mobile breadcrumb customization |
| mintlify/images/og/og-flow-builder.png | Added OG image for flow builder page (243KB PNG) |
Sequence Diagram
sequenceDiagram
participant Docs as Mintlify Docs
participant Iframe as Flow Builder Iframe
Note over Docs,Iframe: Initial Theme Setup
Docs->>Docs: Detect theme (dark/light)
Docs->>Iframe: Set src with theme param
Iframe->>Docs: postMessage: theme-request
Docs->>Iframe: postMessage: theme-sync
Note over Docs,Iframe: User Changes Theme in Docs
Docs->>Docs: MutationObserver detects class change
Docs->>Iframe: postMessage: theme-sync
Iframe->>Iframe: Update iframe theme
Note over Docs,Iframe: User Changes Theme in Iframe
Iframe->>Docs: postMessage: theme-sync
Docs->>Docs: Toggle dark class
Docs->>Docs: Ignore next mutation (flag set)
Docs->>Iframe: postMessage: theme-sync (from observer)
Last reviewed commit: 177c63e
| React.useEffect(() => { | ||
| const isDark = document.documentElement.classList.contains('dark'); | ||
| setSrc('https://grid-visualizer-opal.vercel.app/?embed=true&theme=' + (isDark ? 'dark' : 'light')); | ||
|
|
||
| let ignoreNextMutation = false; | ||
|
|
||
| const sendTheme = () => { | ||
| const t = document.documentElement.classList.contains('dark') ? 'dark' : 'light'; | ||
| const iframe = document.getElementById('flow-builder-iframe'); | ||
| if (iframe && iframe.contentWindow) { | ||
| iframe.contentWindow.postMessage({ type: 'theme-sync', theme: t }, '*'); | ||
| } | ||
| }; | ||
|
|
||
| const handleMessage = (e) => { | ||
| if (e.data && e.data.type === 'theme-request') { | ||
| sendTheme(); | ||
| return; | ||
| } | ||
| if (e.data && e.data.type === 'theme-sync') { | ||
| const isDark = document.documentElement.classList.contains('dark'); | ||
| const wantsDark = e.data.theme === 'dark'; | ||
| if (isDark !== wantsDark) { | ||
| ignoreNextMutation = true; | ||
| document.documentElement.classList.toggle('dark'); | ||
| } | ||
| } | ||
| }; | ||
| window.addEventListener('message', handleMessage); | ||
|
|
||
| const obs = new MutationObserver(() => { | ||
| if (ignoreNextMutation) { ignoreNextMutation = false; return; } | ||
| sendTheme(); | ||
| }); | ||
| obs.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] }); | ||
|
|
||
| return () => { | ||
| window.removeEventListener('message', handleMessage); | ||
| obs.disconnect(); | ||
| }; | ||
| }, []); |
There was a problem hiding this comment.
Using React.useEffect breaks Mintlify's acorn parser per CLAUDE.md style guide. Replace with initialization code that doesn't use useEffect.
Context Used: Context from dashboard - CLAUDE.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/flow-builder.mdx
Line: 11-51
Comment:
Using `React.useEffect` breaks Mintlify's acorn parser per CLAUDE.md style guide. Replace with initialization code that doesn't use `useEffect`.
**Context Used:** Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=21abe025-35ab-4ae8-a4a1-0071c2ac3b98))
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
this is wrong BTW, mintlify's own examples use useEffect https://www.mintlify.com/docs/customize/react-components#example-2
this was an old rule i added out of caution from a debugging session. i'll remove it
| const t = document.documentElement.classList.contains('dark') ? 'dark' : 'light'; | ||
| const iframe = document.getElementById('flow-builder-iframe'); | ||
| if (iframe && iframe.contentWindow) { | ||
| iframe.contentWindow.postMessage({ type: 'theme-sync', theme: t }, '*'); |
There was a problem hiding this comment.
Using '*' as targetOrigin in postMessage allows any window to receive the message. Should validate and use specific origin like 'https://grid-visualizer-opal.vercel.app'.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/flow-builder.mdx
Line: 21
Comment:
Using `'*'` as targetOrigin in `postMessage` allows any window to receive the message. Should validate and use specific origin like `'https://grid-visualizer-opal.vercel.app'`.
How can I resolve this? If you propose a fix, please make it concise.| const handleMessage = (e) => { | ||
| if (e.data && e.data.type === 'theme-request') { | ||
| sendTheme(); | ||
| return; | ||
| } | ||
| if (e.data && e.data.type === 'theme-sync') { | ||
| const isDark = document.documentElement.classList.contains('dark'); | ||
| const wantsDark = e.data.theme === 'dark'; | ||
| if (isDark !== wantsDark) { | ||
| ignoreNextMutation = true; | ||
| document.documentElement.classList.toggle('dark'); | ||
| } | ||
| } | ||
| }; |
There was a problem hiding this comment.
Message handler doesn't validate e.origin before processing messages, allowing any site to send theme-sync commands. Add origin check like if (e.origin !== 'https://grid-visualizer-opal.vercel.app') return;.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/flow-builder.mdx
Line: 25-38
Comment:
Message handler doesn't validate `e.origin` before processing messages, allowing any site to send theme-sync commands. Add origin check like `if (e.origin !== 'https://grid-visualizer-opal.vercel.app') return;`.
How can I resolve this? If you propose a fix, please make it concise.
Summary
Files changed
mintlify/flow-builder.mdx— New page with iframe embed + theme syncmintlify/docs.json— "Build your flow" tab + page-hiding CSSmintlify/index.mdx— Homepage banner copy + link updatemintlify/style.css— Iframe and flow builder layout stylesmintlify/images/og/og-flow-builder.png— OG imageTest plan
🤖 Generated with Claude Code