[Docs][Site] + [Dashboard][UI] - Adds docs to Stack Companion#869
[Docs][Site] + [Dashboard][UI] - Adds docs to Stack Companion#869madster456 merged 86 commits intodevfrom
Conversation
….ts to handle dashboard docs
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds a new UnifiedDocsWidget and embeds docs/api/dashboard content via iframe; adds embed routes/layouts, message bridge, link interception, CORS headers, dashboard docs source, styling, and an env var NEXT_PUBLIC_STACK_DOCS_BASE_URL; integrates the widget into the dashboard companion UI. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User as Dashboard UI
participant Widget as UnifiedDocsWidget
participant Iframe as Docs Iframe
participant DocsApp as Docs Server App
participant Bridge as EmbeddedDocsMessageBridge
User->>Widget: Open docs tab
Widget->>Widget: Resolve embed URL (env + route map)
Widget->>Iframe: Render iframe src="https://github.com/...-embed/..."
Iframe->>DocsApp: Request embedded page
DocsApp->>Iframe: Serve embed page (MDX with EmbeddedLinkInterceptor & Bridge)
Iframe->>Bridge: Mount & post initial DOCS_HISTORY_STATE
Bridge->>Widget: postMessage(DOCS_HISTORY_STATE, { canGoBack })
Widget->>Widget: Update canGoBack
User->>Iframe: Click internal link
Iframe->>Iframe: EmbeddedLinkInterceptor rewrites → /...-embed/...
Iframe->>Iframe: HEAD-check and navigate
User->>Widget: Click Back
Widget->>Iframe.contentWindow: postMessage(NAVIGATE_BACK)
Bridge->>Iframe: Navigate back, post updated DOCS_HISTORY_STATE
Bridge->>Widget: postMessage(DOCS_HISTORY_STATE, { canGoBack })
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Areas needing extra attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🪛 dotenv-linter (4.0.0)apps/dashboard/.env[warning] 6-6: [UnorderedKey] The NEXT_PUBLIC_STACK_DOCS_BASE_URL key should go before the NEXT_PUBLIC_STACK_PROJECT_ID key (UnorderedKey) [warning] 6-6: [ValueWithoutQuotes] This value needs to be surrounded in quotes (ValueWithoutQuotes) ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
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.
Greptile Summary
This PR implements the "Stack Companion" documentation system, which embeds contextual documentation directly within the Stack Auth dashboard interface. The changes introduce a comprehensive embedded documentation architecture with three main components:
-
Documentation Templates and Content: New MDX documentation files are added in
docs/templates-dashboard/covering all major dashboard sections (overview, users, teams, permissions, settings, auth-providers, analytics). These templates provide contextual help content that explains dashboard features and workflows. -
Embedded Documentation Infrastructure: The docs application is extended with embedded routes (
/docs-embed/,/api-embed/,/dashboard-embed/) that render documentation content optimized for iframe embedding. This includes specialized layouts without navigation elements, embedded link interceptors that rewrite internal links to maintain embedded context, and CORS configuration to allow cross-origin access from the dashboard. -
Dashboard Integration: The dashboard's Stack Companion sidebar is enhanced with sophisticated documentation widgets (
UnifiedDocsWidgetandDashboardDocsWidget) that automatically display relevant documentation based on the current dashboard page. These widgets support multiple documentation types, include navigation controls, and provide seamless switching between different documentation contexts.
The system uses fumadocs for content management, with a new dashboardSource loader that processes dashboard-specific MDX content. The embedded documentation system maintains proper styling with Tailwind CSS classes optimized for constrained iframe spaces, including overflow management and responsive design considerations. The architecture allows users to access comprehensive help without leaving their current workflow, significantly improving the developer experience by reducing context switching between the dashboard and external documentation.
Confidence score: 2/5
- This PR introduces significant functionality but contains critical production-breaking issues with hardcoded localhost URLs
- Score reflects major deployment concerns that will cause complete failure in non-development environments
- Pay close attention to
unified-docs-widget.tsxanddashboard-docs-widget.tsxfor hardcoded localhost:8104 URLs that must be resolved before deployment
26 files reviewed, 8 comments
apps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsx
Outdated
Show resolved
Hide resolved
Review by RecurseML🔍 Review performed on 6a3459e..dde5282 ✨ No bugs found, your code is sparkling clean ✅ Files analyzed, no issues (5)• ⏭️ Files skipped (low suspicion) (21)• |
There was a problem hiding this comment.
Actionable comments posted: 8
♻️ Duplicate comments (1)
docs/src/app/api-embed/layout.tsx (1)
1-16: Same embed-layout nits as docs-embed.Mirror the dvh change and verify
EmbeddedLinkInterceptoris a client component as noted in docs-embed/layout.tsx.
🧹 Nitpick comments (42)
docs/templates-dashboard/permissions.mdx (1)
48-57: Add a brief best-practices note and link the Companion.Strengthen the “Permission Validation” section with least-privilege guidance and make “Stack Companion” a clickable link to its entry point.
Apply:
## Permission Validation Ensure proper access control by: - Testing permission assignments - Reviewing access logs - Validating permission logic + +### Best Practices +- Prefer least-privilege roles; avoid granting broad project-wide permissions by default. +- Review effective permissions after team/role changes. +- Periodically audit dormant users and stale teams. ## Need Help? -Use the Stack Companion for detailed permission configuration guidance. +Use the [Stack Companion](</dashboard-embed/companion>) for detailed permission configuration guidance.docs/templates-dashboard/settings.mdx (1)
28-48: Clarify duplicated “Rate limiting” bullets.“Rate limiting” appears under both Security Settings and API Configuration; clarify scope or deduplicate to avoid confusion.
Option A (clarify scopes):
### Security Settings Configure security policies: - Password requirements - Multi-factor authentication - Session management -- Rate limiting +- Authentication rate limiting (login/signup, OTP attempts) ### API Configuration Manage API access: - API keys - Webhook endpoints - CORS settings -- Rate limiting +- API rate limiting (per-key/per-route quotas)Option B (deduplicate to Security Settings only and replace API bullet):
- - Rate limiting + - SDK configuration (environments, base URLs)docs/templates-dashboard/users.mdx (2)
2-7: Name consistency: prefer “User Management”.Use singular form to align with common docs conventions and sidebar patterns (“User Management”).
-title: Users Management +title: User Management @@ -# Users Management +# User Management
29-35: Add privacy/audit guidance when editing user data.A short caution helps set expectations around PII and compliance.
### Managing User Data You can update user information including: - Profile details - Custom metadata - Contact preferences - Account status +> Note: Limit access to PII to authorized roles only. Changes should be auditable (record who changed what and when).docs/templates-dashboard/teams.mdx (1)
2-7: Name consistency: prefer “Team Management”.Match singular form used elsewhere.
-title: Teams Management +title: Team Management @@ -# Teams Management +# Team Managementdocs/templates-dashboard/auth-providers.mdx (5)
21-26: Name the provider consistently as “X (formerly Twitter)”.Minor branding nit for clarity.
-- **Twitter/X**: Social media integration +- **X (formerly Twitter)**: Social media integration
27-31: Clarify SAML is a protocol and mention common IdPs.Prevents confusion vs. OAuth “providers.”
-### Enterprise Providers -- **Microsoft**: Azure AD and Office 365 integration -- **SAML**: Enterprise single sign-on -- **LinkedIn**: Professional network integration +### Enterprise Providers +- **Microsoft Entra ID (Azure AD)**: Enterprise Microsoft login +- **SAML (via IdPs like Okta, OneLogin, Entra ID, Auth0)**: Enterprise single sign‑on +- **LinkedIn**: Professional network integration
32-38: Add critical OAuth setup steps (security + reliability).PKCE, exact redirect URIs, and environment-specific callbacks are easy to miss.
### Configuration Steps -1. **Create OAuth Application**: Set up your app with the provider -2. **Configure Credentials**: Add client ID and secret to Stack Auth -3. **Set Callback URLs**: Configure redirect URLs for your application -4. **Test Integration**: Verify the authentication flow works correctly +1. **Create OAuth Application**: Set up your app with the provider +2. **Configure Credentials**: Add client ID and secret to Stack Auth (store secrets server-side only) +3. **Set Callback URLs**: Add exact authorized redirect URIs per environment (e.g., dev, staging, prod) +4. **Enable PKCE** (recommended) and required grant types per provider +5. (If supported) **Set post‑logout redirect URIs** +6. **Test Integration**: Verify success, error, and cancel flows
41-47: Call out post‑logout URIs and least‑privilege scopes.Keeps deployments secure by default.
### OAuth Configuration Each provider requires: - Client ID - Client Secret - Authorized redirect URIs - - Scope permissions + - (If supported) Post‑logout redirect URIs + - Scope permissions (use least privilege; request only what you need)
54-57: Link to provider‑specific runbooks from Companion.If you have deep links (Google/GitHub/etc.), adding them here reduces bounce.
I can add Companion deeplinks for top providers if you share their slugs.
docs/src/components/mdx/embedded-link.tsx (3)
9-26: Harden path rewriting and handle “/docs” root, queries, and hashes.Current replace() misses “/docs” without trailing slash and query/hash forms; also guard against re‑rewriting embedded routes.
-const getEmbeddedUrl = (href: string): string => { +const getEmbeddedUrl = (href: string): string => { // Handle relative links if (href.startsWith('/')) { - // Convert regular doc routes to embedded routes - if (href.startsWith('/docs/')) { - return href.replace('/docs/', '/docs-embed/'); - } - if (href.startsWith('/api/')) { - return href.replace('/api/', '/api-embed/'); - } - if (href.startsWith('/dashboard/')) { - return href.replace('/dashboard/', '/dashboard-embed/'); - } + // Skip if already embedded + if (href.startsWith('/docs-embed/') || href.startsWith('/api-embed/') || href.startsWith('/dashboard-embed/')) { + return href; + } + // Convert regular routes to embedded routes (match with or without trailing slash) + if (href === '/docs' || href.startsWith('/docs/') || href.startsWith('/docs?') || href.startsWith('/docs#')) { + return href.replace(/^\/docs(?=\/|$)/, '/docs-embed'); + } + if (href === '/api' || href.startsWith('/api/') || href.startsWith('/api?') || href.startsWith('/api#')) { + return href.replace(/^\/api(?=\/|$)/, '/api-embed'); + } + if (href === '/dashboard' || href.startsWith('/dashboard/') || href.startsWith('/dashboard?') || href.startsWith('/dashboard#')) { + return href.replace(/^\/dashboard(?=\/|$)/, '/dashboard-embed'); + } } // Return unchanged for external links or already embedded links return href; };
45-47: Protect target=_blank links against reverse‑tabnabbing.Add rel when opening new tabs.
- // For external links, use regular anchor tag - return <a href={embeddedHref} {...props}>{children}</a>; + // For external links, use regular anchor tag + const rel = props.target === '_blank' + ? [props.rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ') + : props.rel; + return <a href={embeddedHref} {...props} rel={rel}>{children}</a>;
8-26: Deduplicate getEmbeddedUrl across the codebase.If a similar helper exists in embedded-link-interceptor.tsx, consider exporting a shared util to avoid drift.
Would you like me to extract a shared helper (e.g., docs/src/lib/embedded-url.ts) and update both call sites?
docs/templates-dashboard/analytics.mdx (2)
46-51: Verify feature availability (“CSV export”, “PDF generation”, “API access”, “Custom dashboard”).If any are roadmap-only, mark as “coming soon” or scope by plan to avoid overpromising.
I can update copy once you confirm which features ship today vs. later.
21-37: Tighten metric definitions (time windows, filters).Add brief definitions (e.g., DAU/MAU timezones, sign‑in “success” criteria) to reduce ambiguity.
docs/src/app/global.css (3)
198-205: Be cautious hiding scrollbars (a11y).Hidden scrollbars can hurt discoverability and keyboard users. Limit usage to the embed container only, and ensure visible focus/scroll affordances.
Do all elements with .scrollbar-hide still meet WCAG 2.2 focus visibility?
241-249: Avoid aggressive word-break on links/code.
word-break: break-allcan shatter readable text. Prefer overflow-wrap:anywhere for long tokens/URLs.-.prose a[href*="://"] { - word-break: break-all; -} +.prose a[href*="://"] { + overflow-wrap: anywhere; + word-break: break-word; +} /* Break very long strings that have no spaces (like tokens, hashes, etc.) */ -.prose code:not(pre code) { - word-break: break-all; -} +.prose code:not(pre code) { + overflow-wrap: anywhere; + word-break: break-word; + hyphens: auto; +}
227-233: Consider momentum scrolling on narrow tables.Improves mobile UX inside embeds.
.prose table { /* Make tables responsive */ display: block; overflow-x: auto; white-space: nowrap; max-width: 100%; + -webkit-overflow-scrolling: touch; }apps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsx (7)
16-26: Remove unused ROUTE_TO_DOC_MAP and prefer ES6 Map per guidelinesThis constant isn’t referenced; drop it to avoid drift. Also, for future lookups, prefer Map over Record.
-// Map dashboard routes to documentation pages -const ROUTE_TO_DOC_MAP: Record<string, string> = { - '/users': 'users', - '/teams': 'teams', - '/permissions': 'permissions', - '/settings': 'settings', - '/auth-providers': 'auth-providers', - '/analytics': 'analytics', - '/': 'overview', - '': 'overview', -}; +// (removed) Unused; route resolution happens via DASHBOARD_ROUTE_PATTERNS.
29-37: Switch TITLE_MAP to ES6 MapAligns with repo guideline and avoids accidental key collisions.
-// Title mapping for pages -const TITLE_MAP: Record<string, string> = { - 'overview': 'Dashboard Overview', - 'users': 'Users Management', - 'teams': 'Teams Management', - 'permissions': 'Permissions Management', - 'settings': 'Project Settings', - 'auth-providers': 'Authentication Providers', - 'analytics': 'Analytics & Insights', -}; +// Title mapping for pages +const TITLE_MAP = new Map<string, string>([ + ['overview', 'Dashboard Overview'], + ['users', 'Users Management'], + ['teams', 'Teams Management'], + ['permissions', 'Permissions Management'], + ['settings', 'Project Settings'], + ['auth-providers', 'Authentication Providers'], + ['analytics', 'Analytics & Insights'], +]);Follow-ups needed where the map is read; see lines 75 and 212.
39-48: Auth route mapping: handle both /auth-methods and /auth-providersIf the app ever routes to /auth-providers directly, we’ll miss it. Add an explicit pattern.
{ pattern: /\/settings(?:\/.*)?$/, docPage: 'settings' }, { pattern: /\/auth-methods(?:\/.*)?$/, docPage: 'auth-providers' }, // Route is auth-methods but docs are auth-providers + { pattern: /\/auth-providers(?:\/.*)?$/, docPage: 'auth-providers' }, { pattern: /\/analytics(?:\/.*)?$/, docPage: 'analytics' },Please confirm actual dashboard paths.
191-199: Harden iframe attrs and improve UXAdd lazy loading, referrer policy, and popup allowances (if embedded links open windows).
- <iframe + <iframe src={docContent.url} className="w-full h-full border-0 rounded-md bg-white dark:bg-gray-900" onLoad={handleIframeLoad} onError={handleIframeError} title={`Documentation: ${docContent.title}`} - sandbox="allow-scripts allow-same-origin" + sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" + referrerPolicy="strict-origin-when-cross-origin" + loading="lazy" />If popups aren’t desired from inside the embed, drop the allow-popups flags.
75-75: Update title access for MapFollow-up to Map switch.
- const title = TITLE_MAP[page] || `Dashboard ${page}`; + const title = TITLE_MAP.get(page) ?? `Dashboard ${page}`;
212-213: Update prompt title access for MapFollow-up to Map switch.
- Switch to <span className="font-medium">{TITLE_MAP[getDashboardPage(pathname)] || 'current page'}</span>? + Switch to <span className="font-medium">{TITLE_MAP.get(getDashboardPage(pathname)) ?? 'current page'}</span>?
90-116: Simplify effect logic to avoid extra runsCurrent deps (docContent/currentPageDoc) can retrigger the effect; splitting “initial load” and “route change while active” into two effects will reduce state juggling.
I can provide a small refactor if you want it applied here.
apps/dashboard/src/components/stack-companion.tsx (2)
12-12: Lazy-load UnifiedDocsWidget to cut initial bundleAvoid pulling the docs embed code until the Docs tab is opened.
Example:
import dynamic from 'next/dynamic'; // … const UnifiedDocsWidget = dynamic( () => import('./stack-companion/unified-docs-widget').then(m => m.UnifiedDocsWidget), { ssr: false } );
366-366: Render condition is fine; consider passing isActive=activeItem==='docs' for clarityNo behavior change; slightly clearer intent and future-proof if reused.
- <UnifiedDocsWidget isActive={true} /> + <UnifiedDocsWidget isActive={activeItem === 'docs'} />docs/lib/source.ts (1)
42-50: Confirm /dashboard-embed loader exists (or add it here)Embeds point to /dashboard-embed/. If that route isn’t defined elsewhere, add a companion loader to mirror /dashboard with embedded components.
Example (add alongside):
export const dashboardEmbedSource = loader({ baseUrl: '/dashboard-embed', source: dashboard.toFumadocsSource(), pageTree: { attachFile }, icon: createIconResolver(), });docs/templates-dashboard/overview.mdx (1)
14-19: Link the quick navigation items to their pagesImproves discoverability and verifies routes.
- - **Users**: Manage user accounts, view user details, and handle user-related operations + - **[Users](/dashboard/users)**: Manage user accounts, view user details, and handle user-related operations - - **Teams**: Create and manage teams, handle team memberships and permissions + - **[Teams](/dashboard/teams)**: Create and manage teams, handle team memberships and permissions - - **Permissions**: Configure role-based access control and user permissions + - **[Permissions](/dashboard/permissions)**: Configure role-based access control and user permissions - - **Settings**: Configure your project settings, authentication providers, and integrations + - **[Settings](/dashboard/settings)**: Configure your project settings, authentication providers, and integrations - - **Analytics**: View authentication metrics and user engagement data + - **[Analytics](/dashboard/analytics)**: View authentication metrics and user engagement dataIf the embed uses a custom link component, swap for it as appropriate.
docs/src/app/docs-embed/[[...slug]]/page.tsx (2)
5-11: Fix params typing; Next.js App Router does not pass a Promise for params
paramsshould be a plain object. You don't needawait params. This also improves type-safety and consistency with Next types.-export default async function DocsEmbedPage({ +export default async function DocsEmbedPage({ params, }: { - params: Promise<{ slug?: string[] }>, + params: { slug?: string[] }, }) { - const { slug } = await params; + const { slug } = params;
3-3: Prefer notFound() over redirect("/") for missing pagesUse
notFound()to return a proper 404 and avoid unexpected cross-origin redirects inside embeds.-import { redirect } from 'next/navigation'; +import { notFound } from 'next/navigation'; ... - if (!page) redirect("/"); + if (!page) notFound();Also applies to: 13-13
docs/src/app/api-embed/[[...slug]]/page.tsx (2)
5-11: Align params typing with Next.js conventionsSame as docs-embed:
paramsshould not be a Promise; dropawait.-export default async function ApiEmbedPage({ +export default async function ApiEmbedPage({ params, }: { - params: Promise<{ slug?: string[] }>, + params: { slug?: string[] }, }) { - const { slug } = await params; + const { slug } = params;
3-3: Return 404 instead of redirect for missing pagesPrefer
notFound()for correct HTTP semantics in embeds.-import { redirect } from 'next/navigation'; +import { notFound } from 'next/navigation'; ... - if (!page) redirect("/"); + if (!page) notFound();Also applies to: 13-13
docs/src/app/dashboard-embed/layout.tsx (1)
6-14: Use dynamic viewport units to avoid mobile "100vh" issuesReplace
h-screen/min-h-screenwith 100dvh to prevent overflow under mobile browser UI.- <div className="min-h-screen bg-fd-background"> + <div className="min-h-[100dvh] bg-fd-background"> ... - <main className="h-screen overflow-hidden"> + <main className="h-[100dvh] overflow-hidden">docs/src/app/docs-embed/layout.tsx (1)
9-11: Use dvh to avoid mobile viewport bugs.Replace
h-screen/h-fullwithh-dvh(and keep the inneroverflow-y-auto) to avoid iOS Safari 100vh issues in iframes.Apply:
- <main className="h-screen overflow-hidden"> - <div className="h-full overflow-y-auto overflow-x-hidden scrollbar-hide"> + <main className="h-dvh overflow-hidden"> + <div className="h-dvh overflow-y-auto overflow-x-hidden scrollbar-hide">docs/scripts/generate-docs.js (1)
368-417: Include dashboard static assets (images) alongside MDX.
generateDashboardDocs()copies only.mdxand optionalmeta.json. If dashboard docs reference images (e.g.,imgs), they’ll 404.Append inside
generateDashboardDocs()after writingmeta.json:console.log('Dashboard documentation generation complete!'); } +// Copy dashboard asset dirs if present (parity with copyAssets()) +const DASHBOARD_ASSET_DIRS = ['imgs']; +for (const dir of DASHBOARD_ASSET_DIRS) { + const srcDir = path.join(DASHBOARD_TEMPLATE_DIR, dir); + if (fs.existsSync(srcDir)) { + const files = glob.sync('**/*', { cwd: srcDir, nodir: true }); + for (const file of files) { + const srcFile = path.join(srcDir, file); + const destFile = path.join(DASHBOARD_OUTPUT_DIR, dir, file); + fs.mkdirSync(path.dirname(destFile), { recursive: true }); + fs.copyFileSync(srcFile, destFile); + console.log(`Copied dashboard asset: ${srcFile} -> ${destFile}`); + } + } +}apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (2)
20-29: Prefer ES6 Map over Record for title map (per repo guideline).Use
Mapfor key lookups; adjust call site accordingly.Apply:
-const DASHBOARD_TITLE_MAP: Record<string, string> = { - 'overview': 'Dashboard Overview', - 'users': 'Users Management', - 'teams': 'Teams Management', - 'permissions': 'Permissions Management', - 'settings': 'Project Settings', - 'auth-providers': 'Authentication Providers', - 'analytics': 'Analytics & Insights', -}; +const DASHBOARD_TITLE_MAP = new Map<string, string>([ + ['overview', 'Dashboard Overview'], + ['users', 'Users Management'], + ['teams', 'Teams Management'], + ['permissions', 'Permissions Management'], + ['settings', 'Project Settings'], + ['auth-providers', 'Authentication Providers'], + ['analytics', 'Analytics & Insights'], +]);- const title = DASHBOARD_TITLE_MAP[page] || `Dashboard ${page}`; + const title = DASHBOARD_TITLE_MAP.get(page) ?? `Dashboard ${page}`;Also applies to: 88-89
58-75: Remove unused DOC_TYPE_OPTIONS or wire it to UI.It’s currently unused; trim to reduce dead code or integrate into a selector.
Apply:
-// Navigation options for different doc types -const DOC_TYPE_OPTIONS: Array<{ type: DocType, label: string, description: string }> = [ - { - type: 'dashboard', - label: 'Dashboard Docs', - description: 'Documentation for this dashboard page' - }, - { - type: 'docs', - label: 'Main Docs', - description: 'Complete Stack Auth documentation' - }, - { - type: 'api', - label: 'API Reference', - description: 'API endpoints and reference' - }, -];docs/src/components/embedded-link-interceptor.tsx (4)
80-86: Remove unused navigation history state.
setNavigationHistoryis write-only and not rendered. Trim for clarity.- const [, setNavigationHistory] = useState<string[]>([]); - - // Initialize navigation history with current URL - useEffect(() => { - setNavigationHistory([window.location.pathname]); - }, []); + // (removed) navigation history state- // Add to navigation history - setNavigationHistory(prev => [...prev, embeddedHref]); + // navigation history removedAlso applies to: 140-142
127-133: Guard console logging or remove.Avoid noisy logs in production.
- // Debug logging - console.log('Link Debug:', { - originalHref: href, - currentPath, - resolvedHref: embeddedHref - }); + // Debug logging (guarded) + if (process.env.NEXT_PUBLIC_EMBED_DEBUG === '1') { + console.debug('Link Debug:', { originalHref: href, currentPath, resolvedHref: embeddedHref }); + }
171-181: Hide the debug UI behind an env flag to avoid exposing it to end users.Gate the toggle/window with
NEXT_PUBLIC_EMBED_DEBUG === '1'.- {/* Debug Toggle Button */} - <div className="fixed top-4 right-4 z-50"> + {process.env.NEXT_PUBLIC_EMBED_DEBUG === '1' && ( + {/* Debug Toggle Button */} + <div className="fixed top-4 right-4 z-50"> <button onClick={() => setShowDebug(!showDebug)} className="px-3 py-2 bg-gray-800 hover:bg-gray-700 text-white text-xs font-medium rounded-md shadow-lg transition-colors" title="Toggle debug window" > Debug {showDebug ? '▼' : '▲'} </button> </div> - {/* Debug Window */} - {showDebug && ( + {/* Debug Window */} + {showDebug && ( <div className="fixed top-16 right-4 w-96 max-h-96 bg-gray-900 text-white text-xs rounded-lg shadow-2xl z-50 overflow-hidden"> ... </div> - )} + )} + )}Also applies to: 183-257
5-67: Extract shared URL‐rewriting helper. Bothembedded-link-interceptor.tsxandmdx/embedded-link.tsxduplicate the/docs/,/api/, and/dashboard/→-embed/mappings—pull that logic into a common util to keep them in sync.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (26)
apps/dashboard/src/components/stack-companion.tsx(2 hunks)apps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsx(1 hunks)apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx(1 hunks)docs/.gitignore(1 hunks)docs/lib/source.ts(2 hunks)docs/next.config.mjs(1 hunks)docs/scripts/generate-docs.js(3 hunks)docs/source.config.ts(1 hunks)docs/src/app/api-embed/[[...slug]]/page.tsx(1 hunks)docs/src/app/api-embed/layout.tsx(1 hunks)docs/src/app/dashboard-embed/[[...slug]]/page.tsx(1 hunks)docs/src/app/dashboard-embed/layout.tsx(1 hunks)docs/src/app/docs-embed/[[...slug]]/page.tsx(1 hunks)docs/src/app/docs-embed/layout.tsx(1 hunks)docs/src/app/global.css(1 hunks)docs/src/components/embedded-link-interceptor.tsx(1 hunks)docs/src/components/mdx/embedded-link.tsx(1 hunks)docs/src/mdx-components.tsx(3 hunks)docs/templates-dashboard/analytics.mdx(1 hunks)docs/templates-dashboard/auth-providers.mdx(1 hunks)docs/templates-dashboard/meta.json(1 hunks)docs/templates-dashboard/overview.mdx(1 hunks)docs/templates-dashboard/permissions.mdx(1 hunks)docs/templates-dashboard/settings.mdx(1 hunks)docs/templates-dashboard/teams.mdx(1 hunks)docs/templates-dashboard/users.mdx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer ES6 Map over Record where feasible
Files:
docs/src/app/dashboard-embed/layout.tsxapps/dashboard/src/components/stack-companion.tsxdocs/source.config.tsdocs/lib/source.tsdocs/src/mdx-components.tsxdocs/src/components/mdx/embedded-link.tsxdocs/src/app/docs-embed/layout.tsxdocs/src/app/api-embed/layout.tsxdocs/src/app/dashboard-embed/[[...slug]]/page.tsxdocs/src/app/api-embed/[[...slug]]/page.tsxdocs/src/app/docs-embed/[[...slug]]/page.tsxdocs/src/components/embedded-link-interceptor.tsxapps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsxapps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
🧬 Code graph analysis (8)
docs/src/app/dashboard-embed/layout.tsx (1)
docs/src/components/embedded-link-interceptor.tsx (1)
EmbeddedLinkInterceptor(77-260)
docs/src/mdx-components.tsx (1)
docs/src/components/mdx/embedded-link.tsx (1)
EmbeddedLink(28-47)
docs/src/app/docs-embed/layout.tsx (1)
docs/src/components/embedded-link-interceptor.tsx (1)
EmbeddedLinkInterceptor(77-260)
docs/src/app/api-embed/layout.tsx (1)
docs/src/components/embedded-link-interceptor.tsx (1)
EmbeddedLinkInterceptor(77-260)
docs/src/app/dashboard-embed/[[...slug]]/page.tsx (1)
docs/src/mdx-components.tsx (1)
getEmbeddedMDXComponents(88-94)
docs/src/app/api-embed/[[...slug]]/page.tsx (1)
docs/src/mdx-components.tsx (1)
getEmbeddedMDXComponents(88-94)
docs/src/app/docs-embed/[[...slug]]/page.tsx (1)
docs/src/mdx-components.tsx (1)
getEmbeddedMDXComponents(88-94)
docs/next.config.mjs (1)
apps/dashboard/next.config.mjs (1)
async headers() {(94-127)
🪛 LanguageTool
docs/templates-dashboard/settings.mdx
[grammar] ~14-~14: There might be a mistake here.
Context: ...c.) - Security policies and requirements - Email templates and branding - API keys ...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...uirements - Email templates and branding - API keys and webhooks - Project integrat...
(QB_NEW_EN)
[grammar] ~16-~16: There might be a mistake here.
Context: ...tes and branding - API keys and webhooks - Project integrations ## Configuration A...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...Microsoft, etc. - Custom OAuth providers - Provider-specific settings - Callback UR...
(QB_NEW_EN)
[grammar] ~25-~25: There might be a mistake here.
Context: ...h providers - Provider-specific settings - Callback URL configuration ### Security...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...URL configuration ### Security Settings Configure security policies: - Password ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...ty Settings Configure security policies: - Password requirements - Multi-factor aut...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...curity policies: - Password requirements - Multi-factor authentication - Session ma...
(QB_NEW_EN)
[grammar] ~31-~31: There might be a mistake here.
Context: ...quirements - Multi-factor authentication - Session management - Rate limiting ### ...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ...ctor authentication - Session management - Rate limiting ### Branding & Templates ...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ... Rate limiting ### Branding & Templates Customize the user experience: - Email t...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...Templates Customize the user experience: - Email templates - Login page branding - ...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...e the user experience: - Email templates - Login page branding - Custom domains - T...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ... - Email templates - Login page branding - Custom domains - Theme configuration ##...
(QB_NEW_EN)
[grammar] ~39-~39: There might be a mistake here.
Context: ...s - Login page branding - Custom domains - Theme configuration ### API Configurati...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...eme configuration ### API Configuration Manage API access: - API keys - Webhook ...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...### API Configuration Manage API access: - API keys - Webhook endpoints - CORS sett...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...figuration Manage API access: - API keys - Webhook endpoints - CORS settings - Rate...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...I access: - API keys - Webhook endpoints - CORS settings - Rate limiting ## Need H...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...keys - Webhook endpoints - CORS settings - Rate limiting ## Need Help? Consult th...
(QB_NEW_EN)
docs/templates-dashboard/analytics.mdx
[grammar] ~12-~12: There might be a mistake here.
Context: ...erview Track key metrics to understand: - User authentication patterns - Sign-up a...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ...derstand: - User authentication patterns - Sign-up and conversion rates - Popular a...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ... patterns - Sign-up and conversion rates - Popular authentication methods - User en...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...n rates - Popular authentication methods - User engagement trends - System performa...
(QB_NEW_EN)
[grammar] ~16-~16: There might be a mistake here.
Context: ...ication methods - User engagement trends - System performance metrics ## Key Metri...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...ey Metrics ### Authentication Analytics - Daily/Monthly Active Users: Track user...
(QB_NEW_EN)
[grammar] ~27-~27: There might be a mistake here.
Context: ...ders are most popular ### User Behavior - Session Duration: Understand user enga...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ...users' platforms ### System Performance - API Response Times: Monitor system per...
(QB_NEW_EN)
[grammar] ~40-~40: There might be a mistake here.
Context: ...ata Visualization ### Charts and Graphs - Time series data for trends - Pie charts...
(QB_NEW_EN)
[grammar] ~41-~41: There might be a mistake here.
Context: ...and Graphs - Time series data for trends - Pie charts for distribution analysis - B...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...s - Pie charts for distribution analysis - Bar charts for comparative metrics - Hea...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...sis - Bar charts for comparative metrics - Heatmaps for geographic data ### Export...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ... for geographic data ### Export Options - CSV data export - PDF report generation ...
(QB_NEW_EN)
[grammar] ~47-~47: There might be a mistake here.
Context: ...ta ### Export Options - CSV data export - PDF report generation - API access to an...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ... CSV data export - PDF report generation - API access to analytics data - Custom da...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...eneration - API access to analytics data - Custom dashboard creation ## Need Help?...
(QB_NEW_EN)
docs/templates-dashboard/permissions.mdx
[grammar] ~12-~12: There might be a mistake here.
Context: ...access to your application resources by: - Defining custom permissions - Creating r...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ...ources by: - Defining custom permissions - Creating roles and permission sets - Ass...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ...ons - Creating roles and permission sets - Assigning permissions to users and teams...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...Assigning permissions to users and teams - Managing permission inheritance ## Perm...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...ermission Types ### Project Permissions Global permissions that apply across you...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...s that apply across your entire project: - Admin access - User management - Team ma...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...ross your entire project: - Admin access - User management - Team management - Sett...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...roject: - Admin access - User management - Team management - Settings configuration...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...cess - User management - Team management - Settings configuration ### Team Permiss...
(QB_NEW_EN)
[grammar] ~27-~27: There might be a mistake here.
Context: ...ings configuration ### Team Permissions Permissions specific to team contexts: -...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...s Permissions specific to team contexts: - Team membership management - Team resour...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...m contexts: - Team membership management - Team resource access - Team-specific ope...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...ership management - Team resource access - Team-specific operations ### Custom Per...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ...cific operations ### Custom Permissions Define your own permissions for: - Appli...
(QB_NEW_EN)
[grammar] ~34-~34: There might be a mistake here.
Context: ...issions Define your own permissions for: - Application-specific features - Resource...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...ons for: - Application-specific features - Resource-level access control - Custom b...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...features - Resource-level access control - Custom business logic ## Managing Permi...
(QB_NEW_EN)
[grammar] ~41-~41: There might be a mistake here.
Context: ...g Permissions ### Assigning Permissions Grant permissions through: - Direct user...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...g Permissions Grant permissions through: - Direct user assignment - Team membership...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...ssions through: - Direct user assignment - Team membership - Role-based assignment ...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...Direct user assignment - Team membership - Role-based assignment - Permission inher...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ... Team membership - Role-based assignment - Permission inheritance ### Permission V...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...n inheritance ### Permission Validation Ensure proper access control by: - Testi...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...idation Ensure proper access control by: - Testing permission assignments - Reviewi...
(QB_NEW_EN)
docs/templates-dashboard/teams.mdx
[grammar] ~12-~12: There might be a mistake here.
Context: ...ontrol at scale. From this page you can: - Create new teams - Manage team membershi...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ... ## Team Operations ### Creating Teams Set up new teams with: - Team name and d...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...## Creating Teams Set up new teams with: - Team name and description - Initial memb...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ... teams with: - Team name and description - Initial members - Default permissions - ...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...m name and description - Initial members - Default permissions - Team settings ###...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ... - Initial members - Default permissions - Team settings ### Managing Members Cont...
(QB_NEW_EN)
[grammar] ~27-~27: There might be a mistake here.
Context: ...ns - Team settings ### Managing Members Control team membership by: - Adding new...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...ging Members Control team membership by: - Adding new members - Removing members - ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...team membership by: - Adding new members - Removing members - Changing member roles...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ... - Adding new members - Removing members - Changing member roles - Setting team-spe...
(QB_NEW_EN)
[grammar] ~31-~31: There might be a mistake here.
Context: ...Removing members - Changing member roles - Setting team-specific permissions ### T...
(QB_NEW_EN)
[grammar] ~34-~34: There might be a mistake here.
Context: ...ecific permissions ### Team Permissions Configure what team members can access: ...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ... Configure what team members can access: - Team-level permissions - Resource access...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...ers can access: - Team-level permissions - Resource access control - Role-based res...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...el permissions - Resource access control - Role-based restrictions ## Need Help? ...
(QB_NEW_EN)
docs/templates-dashboard/users.mdx
[grammar] ~12-~12: There might be a mistake here.
Context: ...n. ## Overview From this page you can: - View all registered users - Search and f...
(QB_NEW_EN)
[grammar] ~25-~25: There might be a mistake here.
Context: ...uthentication methods - Team memberships - Permission assignments - Recent activity...
(QB_NEW_EN)
[grammar] ~26-~26: There might be a mistake here.
Context: ...eam memberships - Permission assignments - Recent activity ### Managing User Data ...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ... Recent activity ### Managing User Data You can update user information includin...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...u can update user information including: - Profile details - Custom metadata - Cont...
(QB_NEW_EN)
[grammar] ~31-~31: There might be a mistake here.
Context: ...information including: - Profile details - Custom metadata - Contact preferences - ...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ...ing: - Profile details - Custom metadata - Contact preferences - Account status ##...
(QB_NEW_EN)
[grammar] ~33-~33: There might be a mistake here.
Context: ... - Custom metadata - Contact preferences - Account status ### User Permissions Con...
(QB_NEW_EN)
[grammar] ~36-~36: There might be a mistake here.
Context: ...s - Account status ### User Permissions Control what users can access by: - Assi...
(QB_NEW_EN)
[grammar] ~37-~37: There might be a mistake here.
Context: ...ssions Control what users can access by: - Assigning roles - Setting specific permi...
(QB_NEW_EN)
[grammar] ~38-~38: There might be a mistake here.
Context: ...t users can access by: - Assigning roles - Setting specific permissions - Managing ...
(QB_NEW_EN)
[grammar] ~39-~39: There might be a mistake here.
Context: ...ing roles - Setting specific permissions - Managing team memberships ## Need Help?...
(QB_NEW_EN)
docs/templates-dashboard/auth-providers.mdx
[grammar] ~13-~13: There might be a mistake here.
Context: ...oviders (Google, GitHub, Facebook, etc.) - Enterprise providers (Microsoft, SAML, e...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...ft, SAML, etc.) - Custom OAuth providers - Passwordless options ## Supported Provi...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ... Providers ### Popular Social Providers - Google: OAuth 2.0 integration with Goo...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...uth 2.0 integration with Google accounts - GitHub: Perfect for developer-focused ...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...rfect for developer-focused applications - Facebook: Social login for consumer ap...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...: Social login for consumer applications - Discord: Great for gaming and communit...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...d**: Great for gaming and community apps - Twitter/X: Social media integration #...
(QB_NEW_EN)
[grammar] ~27-~27: There might be a mistake here.
Context: ...ia integration ### Enterprise Providers - Microsoft: Azure AD and Office 365 int...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ...t**: Azure AD and Office 365 integration - SAML: Enterprise single sign-on - **Li...
(QB_NEW_EN)
[grammar] ~29-~29: There might be a mistake here.
Context: ...on - SAML: Enterprise single sign-on - LinkedIn: Professional network integra...
(QB_NEW_EN)
[grammar] ~41-~41: There might be a mistake here.
Context: ...ovider Settings ### OAuth Configuration Each provider requires: - Client ID - Cl...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...th Configuration Each provider requires: - Client ID - Client Secret - Authorized r...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...tion Each provider requires: - Client ID - Client Secret - Authorized redirect URIs...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...er requires: - Client ID - Client Secret - Authorized redirect URIs - Scope permiss...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...Client Secret - Authorized redirect URIs - Scope permissions ### Advanced Options ...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ... Scope permissions ### Advanced Options - Custom button styling - Provider-specifi...
(QB_NEW_EN)
[grammar] ~49-~49: There might be a mistake here.
Context: ...Advanced Options - Custom button styling - Provider-specific settings - User data m...
(QB_NEW_EN)
[grammar] ~50-~50: There might be a mistake here.
Context: ...ton styling - Provider-specific settings - User data mapping - Permission scopes #...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...er-specific settings - User data mapping - Permission scopes ## Need Help? Use th...
(QB_NEW_EN)
🪛 Biome (2.1.2)
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
[error] 220-220: src is assigned to itself.
This is where is assigned.
Self assignments have no effect and can be removed.
(lint/correctness/noSelfAssign)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: all-good
- GitHub Check: lint_and_build (latest)
- GitHub Check: docker
- GitHub Check: setup-tests
- GitHub Check: build (22.x)
- GitHub Check: restart-dev-and-test
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: Security Check
🔇 Additional comments (14)
docs/.gitignore (1)
30-35: Good addition: ignore generated dashboard docs output.Adding
/content/dashboard/aligns with existing generated content ignores and prevents noisy diffs. No action needed.docs/templates-dashboard/teams.mdx (1)
12-17: Verify “team analytics” availability or rephrase.If analytics aren’t yet in the Teams section, reword to avoid overpromising (e.g., “View team activity”).
Would you confirm the current dashboard includes team-level analytics in this view? If not, I can propose precise wording.
docs/next.config.mjs (1)
12-51: Scope CORS headers to development, use dynamic origin, restrict methods, add Vary and caching, and verify credentials
- Wrap the existing
headers()return in aif (process.env.NODE_ENV === 'development')guard indocs/next.config.mjs.- Replace hard-coded origin with
process.env.DASHBOARD_APP_ORIGIN ?? 'http://localhost:8101'.- Change
Access-Control-Allow-Methodsto onlyGET, OPTIONS.- Add
Vary: OriginandAccess-Control-Max-Age: 600to each route.- Confirm whether cookies are sent; if so, also add
Access-Control-Allow-Credentials: trueand echo the exact origin.docs/templates-dashboard/meta.json (1)
4-15: Validate slugs and group markers with generatorEnsure the generator supports section dividers like "---General---" and that each slug matches the corresponding MDX filename (users, teams, permissions, settings, auth-providers, analytics).
If needed, I can script-check for missing/extra pages against content/dashboard.
docs/lib/source.ts (1)
1-1: Import looks goodExtending to include dashboard is consistent with the loaders below.
docs/src/app/docs-embed/[[...slug]]/page.tsx (1)
15-23: MDX render path looks correctUsing
page.data.bodywithgetEmbeddedMDXComponents()aligns with the embed strategy.docs/source.config.ts (1)
30-39: Dashboard collection wiring LGTM
defineDocs({ dir: './content/dashboard', ... })mirrors the API collection. No issues spotted.docs/src/app/api-embed/[[...slug]]/page.tsx (1)
15-23: MDX embed rendering looks goodConsistent with the embedded MDX components strategy.
docs/src/app/dashboard-embed/layout.tsx (2)
1-8: EmbeddedLinkInterceptor includes 'use client' directive; no changes required
10-10: scrollbar-hide utility confirmed in global.css; no changes needed.docs/src/mdx-components.tsx (2)
5-5: Imports look correct
ComponentPropstyping andEmbeddedLinkimport are appropriate.Also applies to: 17-17
87-94: Embedded MDX components override is solidOverriding
atoEmbeddedLinkwithisEmbeddedenforces embedded URL rewriting as intended.docs/src/app/docs-embed/layout.tsx (1)
1-8: No action needed—EmbeddedLinkInterceptoralready declares"use client"at the top.apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (1)
330-331: Minimize iframe sandbox permissions (verify necessity of allow-same-origin).
allow-same-originsignificantly increases the embedded page’s capabilities. If not required, drop it to harden the sandbox.Proposed tightened sandbox (pending validation with embedded link behavior):
- sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox" + sandbox="allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox"Please confirm embedded navigation and external links still function as expected.
apps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/components/stack-companion/dashboard-docs-widget.tsx
Outdated
Show resolved
Hide resolved
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/src/components/layouts/docs.tsx (2)
96-108: Prefer Map over Record for accordion state (guideline) and avoid object churnSwitch to Map to align with project guideline and reduce spread-copy churn on updates.
Apply this diff:
-export function AccordionProvider({ children }: { children: ReactNode }) { - const [accordionState, setAccordionStateInternal] = useState<Record<string, boolean>>({}); +export function AccordionProvider({ children }: { children: ReactNode }) { + const [accordionState, setAccordionStateInternal] = useState<Map<string, boolean>>(new Map()); @@ - const setAccordionState = (key: string, isOpen: boolean) => { - setAccordionStateInternal(prev => ({ ...prev, [key]: isOpen })); - }; + const setAccordionState = (key: string, isOpen: boolean) => { + setAccordionStateInternal((prev) => { + const next = new Map(prev); + next.set(key, isOpen); + return next; + }); + };And update the context type accordingly (outside this hunk):
type AccordionContextType = { accordionState: Map<string, boolean>; setAccordionState: (key: string, isOpen: boolean) => void; };
268-294: Avoid substring matches that can mis-route platforms (e.g., “react” matching “preact”); also prefer Map over RecordDrop the includes() check and use a Map. This prevents accidental matches and follows the Map guideline.
Apply this diff:
-export function findPlatformContent(tree: PageTree.Root, platform: string): PageTree.Node[] { - // Platform folder name mappings - const platformMappings: Record<string, string[]> = { - 'next': ['next.js', 'nextjs'], - 'react': ['react'], - 'js': ['javascript'], - 'python': ['python'] - }; +export function findPlatformContent(tree: PageTree.Root, platform: string): PageTree.Node[] { + // Platform folder name mappings + const platformMappings = new Map<string, string[]>([ + ['next', ['next.js', 'nextjs']], + ['react', ['react']], + ['js', ['javascript']], + ['python', ['python']], + ]); @@ - const possibleNames = platformKey in platformMappings ? platformMappings[platformKey] : [platformKey]; + const possibleNames = platformMappings.get(platformKey) ?? [platformKey]; @@ - if (possibleNames.some(name => { - const normalizedName = name.trim().toLowerCase(); - return itemName === normalizedName || itemName.includes(normalizedName); - })) { + if (possibleNames.some((name) => itemName === name.trim().toLowerCase())) { return item.children; }
♻️ Duplicate comments (2)
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (2)
99-113: Remove hardcoded localhost; parameterize docs origin (avoids mixed-content and non-prod breakage).Build embed URLs from a configurable origin (e.g., NEXT_PUBLIC_DOCS_ORIGIN) or current origin; stop hardcoding http://localhost:8104.
Apply:
- const url = `http://localhost:8104/docs-embed/${docMapping.path}`; + const url = joinDocUrl(`/docs-embed/${docMapping.path}`);- const url = `http://localhost:8104/docs-embed/${platform}/getting-started/setup`; + const url = joinDocUrl(`/docs-embed/${platform}/getting-started/setup`);- const url = `http://localhost:8104/api-embed/overview`; + const url = joinDocUrl(`/api-embed/overview`);Add near the top (after types):
+const DOCS_ORIGIN = process.env.NEXT_PUBLIC_DOCS_ORIGIN ?? ''; +const joinDocUrl = (p: string) => { + const base = + DOCS_ORIGIN.trim() || + (typeof window !== 'undefined' ? window.location.origin : ''); + return `${base.replace(/\/$/, '')}${p.startsWith('/') ? p : `/${p}`}`; +};
241-255: Fix iframe reload fallback (no-op self-assign + Biome error).Replace self-assign with cache-busting URL update to actually trigger reload.
- } catch (error) { - // If we can't access iframe history, try to reload the previous page - // This is a fallback that at least resets the iframe - console.warn('Cannot access iframe history, reloading current page'); - if (iframeRef) { - iframeRef.src = iframeRef.src; - } - } + } catch (error) { + console.warn('Cannot access iframe history, forcing reload via cache-buster'); + if (iframeRef?.src) { + try { + const u = new URL(iframeRef.src, window.location.origin); + u.searchParams.set('_r', Date.now().toString()); + setDocContent(prev => (prev ? { ...prev, url: u.toString() } : prev)); + } catch { + setDocContent(prev => (prev ? { ...prev } : prev)); // react remount fallback + } + } + }
🧹 Nitpick comments (12)
docs/src/components/layouts/docs.tsx (3)
110-124: Use Map accessors in the hook; expose stable tupleIf you adopt Map in the provider, read via get().
Apply this diff:
-export function useAccordionState(key: string, defaultValue: boolean) { +export function useAccordionState(key: string, defaultValue: boolean) { @@ - const { accordionState, setAccordionState } = context; - const isOpen = accordionState[key] ?? defaultValue; + const { accordionState, setAccordionState } = context; + const isOpen = (accordionState instanceof Map + ? accordionState.get(key) + : // backward-compat if context not yet migrated + (accordionState as Record<string, boolean>)[key]) ?? defaultValue;
297-344: Use stable React keys; avoid index to prevent reorder bugsKeys using index can cause state leakage on reordering. Prefer semantic keys.
Apply this diff:
- {item.children.map((child, index) => ( - <PageTreeItem key={child.type === 'page' ? child.url : index} item={child} currentPlatform={currentPlatform} /> - ))} + {item.children.map((child) => ( + <PageTreeItem + key={`${child.type}:${child.type === 'page' ? child.url : String(child.name ?? '')}`} + item={child} + currentPlatform={currentPlatform} + /> + ))} @@ - {item.children.map((child, index) => ( - <PageTreeItem key={child.type === 'page' ? child.url : index} item={child} currentPlatform={currentPlatform} /> - ))} + {item.children.map((child) => ( + <PageTreeItem + key={`${child.type}:${child.type === 'page' ? child.url : String(child.name ?? '')}`} + item={child} + currentPlatform={currentPlatform} + /> + ))}
346-376: LGTM on making renderSidebarContent public; just one key nitApproach looks good. Mirror the stable-key change here too.
Apply this diff:
- {tree.children.map((item, index) => ( - <PageTreeItem key={item.type === 'page' ? item.url : index} item={item} currentPlatform={currentPlatform} /> - ))} + {tree.children.map((item) => ( + <PageTreeItem + key={`${item.type}:${item.type === 'page' ? item.url : String(item.name ?? '')}`} + item={item} + currentPlatform={currentPlatform} + /> + ))}docs/src/app/docs-embed/[[...slug]]/page.tsx (1)
18-23: Consider 404 for unknown pages (optional)Redirecting unknown slugs to overview can mask broken links. Using notFound() yields a proper 404.
Apply this diff:
- if (!page) { - // Try to redirect to a sensible default if page not found - redirect('/docs-embed/next/overview'); - } + if (!page) { + // Unknown page → 404 (keeps bad links visible) + // import { notFound } from 'next/navigation' + // notFound(); + redirect('/docs-embed/next/overview'); + }docs/src/components/embedded-docs-with-sidebar.tsx (3)
24-34: Harden postMessage handling with a simple channel guardAnyone can postMessage into the iframe; add a shared “source” token check (keeps cross-origin support without origin allowlists).
Apply this diff:
- useEffect(() => { + useEffect(() => { const handleMessage = (event: MessageEvent) => { - if (event.data?.type === 'TOGGLE_SIDEBAR') { + if (event.data?.source === 'STACK_EMBED' && event.data?.type === 'TOGGLE_SIDEBAR') { setIsSidebarVisible(event.data.visible); } };Parent should send: window.postMessage({ source: 'STACK_EMBED', type: 'TOGGLE_SIDEBAR', visible: true }, '*').
56-74: Add dialog semantics for accessibility on the DrawerMark the drawer as a modal dialog for AT users.
Apply this diff:
- <div className="fixed left-0 top-0 bottom-0 w-[268px] z-50 bg-fd-background/95 backdrop-blur-md border-r border-fd-border shadow-lg"> + <div + className="fixed left-0 top-0 bottom-0 w-[268px] z-50 bg-fd-background/95 backdrop-blur-md border-r border-fd-border shadow-lg" + role="dialog" + aria-modal="true" + aria-label="Documentation navigation" + >
11-15: Remove unused currentSlug prop (keeps API tight)The prop isn’t used; drop it here and at the call site.
Apply this diff:
type EmbeddedDocsWithSidebarProps = { pageTree: PageTree.Root, - currentSlug: string[], children: React.ReactNode, } -export function EmbeddedDocsWithSidebar({ pageTree, currentSlug, children }: EmbeddedDocsWithSidebarProps) { +export function EmbeddedDocsWithSidebar({ pageTree, children }: EmbeddedDocsWithSidebarProps) {And in docs/src/app/docs-embed/[[...slug]]/page.tsx remove the prop:
- <EmbeddedDocsWithSidebar - pageTree={source.pageTree} - currentSlug={slug} - > + <EmbeddedDocsWithSidebar pageTree={source.pageTree}>Also applies to: 17-18
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (5)
85-101: Prefer Map over Record for key–value collections (repo guideline).Use Map and safe fallback for unknown pages.
- const dashboardToDocsMap: Record<string, { path: string, title: string }> = { - 'overview': { path: `${platform}/overview`, title: 'Stack Auth Overview' }, - 'users': { path: `${platform}/getting-started/users`, title: 'User Management' }, - 'auth-methods': { path: `${platform}/concepts/auth-providers`, title: 'Authentication Providers' }, - 'orgs-and-teams': { path: `${platform}/concepts/orgs-and-teams`, title: 'Teams & Organizations' }, - 'team-permissions': { path: `${platform}/concepts/permissions#team-permissions`, title: 'Team Permissions' }, - 'emails': { path: `${platform}/concepts/emails`, title: 'Emails' }, - 'domains': { path: `${platform}/getting-started/production#domains`, title: 'Domains' }, - 'webhooks': { path: `${platform}/concepts/webhooks`, title: 'Webhooks' }, - 'stack-auth-keys': { path: `${platform}/getting-started/setup#update-api-keys`, title: 'Stack Auth Keys' }, - 'project-settings': { path: `${platform}/getting-started/production#enabling-production-mode`, title: 'Project Configuration' }, - }; - - const docMapping = dashboardToDocsMap[page]; + const dashboardToDocsMap = new Map<string, { path: string; title: string }>([ + ['overview', { path: `${platform}/overview`, title: 'Stack Auth Overview' }], + ['users', { path: `${platform}/getting-started/users`, title: 'User Management' }], + ['auth-methods', { path: `${platform}/concepts/auth-providers`, title: 'Authentication Providers' }], + ['orgs-and-teams', { path: `${platform}/concepts/orgs-and-teams`, title: 'Teams & Organizations' }], + ['team-permissions', { path: `${platform}/concepts/permissions#team-permissions`, title: 'Team Permissions' }], + ['emails', { path: `${platform}/concepts/emails`, title: 'Emails' }], + ['domains', { path: `${platform}/getting-started/production#domains`, title: 'Domains' }], + ['webhooks', { path: `${platform}/concepts/webhooks`, title: 'Webhooks' }], + ['stack-auth-keys', { path: `${platform}/getting-started/setup#update-api-keys`, title: 'Stack Auth Keys' }], + ['project-settings', { path: `${platform}/getting-started/production#enabling-production-mode`, title: 'Project Configuration' }], + ]); + + const docMapping = + dashboardToDocsMap.get(page) ?? dashboardToDocsMap.get('overview')!;
136-147: Reset back-button state on new loads.Avoid stale “Back” visibility after reloads.
setLoading(true); setError(null); setIframeLoaded(false); + setCanGoBack(false); setCurrentPageDoc(newPageDoc);
149-158: Guard debug logs for production.Keep console noise out of prod.
- console.log('Debug mapping:', { + if (process.env.NODE_ENV !== 'production') console.log('Debug mapping:', { pathname, normalizedPath: pathname.replace(/^\/projects\/[^/]+/, ''), detectedPage: page, platform: selectedPlatform }); - const content = getDocContentForPath(pathname, selectedDocType, selectedPlatform); - console.log('Loading docs:', { page, platform: selectedPlatform, url: content.url }); + const content = getDocContentForPath(pathname, selectedDocType, selectedPlatform); + if (process.env.NODE_ENV !== 'production') console.log('Loading docs:', { page, platform: selectedPlatform, url: content.url });
149-149: Avoid recomputing getDashboardPage.Use the already computed value.
- const page = getDashboardPage(pathname); + const page = newPageDoc;
224-230: Hide sidebar in the embed when switching doc types.Mirror local state to the iframe.
setSelectedDocType(docType); setShowSwitchPrompt(false); setIsSidebarVisible(false); // Hide sidebar when switching doc types + if (iframeRef) toggleEmbeddedSidebar(iframeRef, false);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx(1 hunks)docs/src/app/docs-embed/[[...slug]]/page.tsx(1 hunks)docs/src/components/embedded-docs-with-sidebar.tsx(1 hunks)docs/src/components/layouts/docs.tsx(5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer ES6 Map over Record when representing key–value collections
Files:
docs/src/components/embedded-docs-with-sidebar.tsxdocs/src/app/docs-embed/[[...slug]]/page.tsxdocs/src/components/layouts/docs.tsxapps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
For blocking alerts and errors in UI, do not use toast notifications; use alerts instead
Files:
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
Keep hover/click animations snappy; avoid pre-transition delays on hover and apply transitions after the action (e.g., fade-out on hover end)
Files:
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
🧬 Code graph analysis (3)
docs/src/components/embedded-docs-with-sidebar.tsx (2)
docs/src/components/layouts/docs.tsx (2)
AccordionProvider(96-108)renderSidebarContent(346-376)docs/src/components/layouts/sidebar-context.tsx (1)
SidebarProvider(51-184)
docs/src/app/docs-embed/[[...slug]]/page.tsx (3)
docs/lib/source.ts (1)
source(23-30)docs/src/components/embedded-docs-with-sidebar.tsx (1)
EmbeddedDocsWithSidebar(17-91)docs/src/mdx-components.tsx (1)
getEmbeddedMDXComponents(88-94)
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (1)
docs/src/components/icons.tsx (2)
Menu(137-141)ExternalLink(98-108)
🪛 Biome (2.1.2)
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
[error] 252-252: src is assigned to itself.
This is where is assigned.
Self assignments have no effect and can be removed.
(lint/correctness/noSelfAssign)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: build (22.x)
- GitHub Check: lint_and_build (latest)
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: all-good
- GitHub Check: docker
- GitHub Check: setup-tests
- GitHub Check: restart-dev-and-test
- GitHub Check: Security Check
🔇 Additional comments (3)
docs/src/app/docs-embed/[[...slug]]/page.tsx (1)
1-5: Import 'lib/source' resolves correctly via baseUrl
docs/tsconfig.json sets baseUrl to "." so non-relative imports map to project root (docs/lib/source.ts exists and is already used via relative paths); no changes needed.apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx (2)
398-406: Revisit sandbox allowances; narrow if possible.If not strictly required, drop allow-same-origin and/or allow-popups-to-escape-sandbox to reduce risk. PostMessage doesn’t need same-origin.
Do you know if the embedded docs require same-origin APIs (e.g., localStorage)? If not, I can propose a tightened sandbox string.
286-313: Good: inline alert for errors (no toasts).Complies with the repo’s UI guideline for blocking errors.
apps/dashboard/src/components/stack-companion/unified-docs-widget.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
docs/src/components/embedded-link-interceptor.tsx (2)
92-99: Consider making URL existence check optional via feature flag.The
checkUrlExistsHEAD request is now non-blocking (navigation proceeds regardless), but still adds latency and can fail on hosts that return 405/308 for HEAD. Since multiple previous reviewers flagged HEAD requests as unreliable and the check is purely advisory, consider gating it behind an environment variable (e.g.,NEXT_PUBLIC_ENABLE_LINK_VALIDATION) or removing it entirely.Apply this diff to gate the check behind a feature flag:
+const ENABLE_LINK_VALIDATION = process.env.NEXT_PUBLIC_ENABLE_LINK_VALIDATION === 'true'; + export function EmbeddedLinkInterceptor() { const router = useRouter(); // Function to check if a URL exists const checkUrlExists = useCallback(async (url: string): Promise<boolean> => { + if (!ENABLE_LINK_VALIDATION) return true; try { const response = await fetch(url, { method: 'HEAD' }); return response.ok;
131-144: Optionally prevent duplicate in-flight navigations.Rapid repeated clicks on the same link will queue multiple navigations. While
router.pushshould handle this gracefully, you could add deduplication by tracking in-flight URLs to improve UX consistency.Apply this diff to add deduplication:
useEffect(() => { + const inFlightUrls = new Set<string>(); + const handleClick = (event: MouseEvent) => { if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { return; } const target = event.target as HTMLElement; // Find the closest anchor tag const anchor = target.closest('a'); if (!anchor) return; const href = anchor.getAttribute('href'); if (!href) return; if (anchor.target === '_blank' || anchor.hasAttribute('download')) { return; } if (href.startsWith('javascript:') || href.startsWith('data:') || href.startsWith('blob:')) { return; } // Intercept internal links that need to be rewritten OR relative links if ( href.startsWith('/docs/') || href.startsWith('/api/') || href.startsWith('/dashboard/') || (!/^[a-zA-Z][a-zA-Z+\-.]*:/.test(href) && !href.startsWith('#')) ) { event.preventDefault(); const currentPath = window.location.pathname; const embeddedHref = getEmbeddedUrl(href, currentPath); + + if (inFlightUrls.has(embeddedHref)) { + return; // Skip if already navigating to this URL + } + const navigate = () => router.push(embeddedHref); // Check if the URL exists before navigating (async operation) runAsynchronously(async () => { + inFlightUrls.add(embeddedHref); + try { const urlExists = await checkUrlExists(embeddedHref); if (!urlExists) { console.warn(`Embedded link not found, navigating anyway: ${embeddedHref}`); } navigate(); + } finally { + inFlightUrls.delete(embeddedHref); + } }); } };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/dashboard/.env(1 hunks)apps/dashboard/.env.development(1 hunks)docs/src/components/embedded-docs-message-bridge.tsx(1 hunks)docs/src/components/embedded-link-interceptor.tsx(1 hunks)docs/src/components/mdx/embedded-link.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/src/components/mdx/embedded-link.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use ES6 Maps instead of Records wherever possible in TypeScript code
Files:
docs/src/components/embedded-docs-message-bridge.tsxdocs/src/components/embedded-link-interceptor.tsx
🧠 Learnings (1)
📚 Learning: 2025-10-20T22:25:40.427Z
Learnt from: CR
PR: stack-auth/stack-auth#0
File: AGENTS.md:0-0
Timestamp: 2025-10-20T22:25:40.427Z
Learning: Applies to apps/{dashboard,dev-launchpad}/**/*.{css,tsx,jsx} : Animations: keep hover/click transitions snappy; do not delay actions with pre-hover transitions; apply transitions after the action (e.g., fade-out on hover end)
Applied to files:
docs/src/components/embedded-link-interceptor.tsx
🧬 Code graph analysis (1)
docs/src/components/embedded-link-interceptor.tsx (1)
packages/stack-shared/src/utils/promises.tsx (1)
runAsynchronously(343-366)
🪛 dotenv-linter (4.0.0)
apps/dashboard/.env
[warning] 8-8: [UnorderedKey] The NEXT_PUBLIC_STACK_DOCS_BASE_URL key should go before the NEXT_PUBLIC_STACK_EXTRA_REQUEST_HEADERS key
(UnorderedKey)
[warning] 8-8: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
apps/dashboard/.env.development
[warning] 2-2: [SubstitutionKey] The NEXT_PUBLIC_STACK_DOCS_BASE_URL key is not assigned properly
(SubstitutionKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: Vercel Agent Review
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: lint_and_build (latest)
- GitHub Check: setup-tests
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: all-good
- GitHub Check: restart-dev-and-test
- GitHub Check: build (22.x)
- GitHub Check: build (22.x)
- GitHub Check: Security Check
🔇 Additional comments (9)
apps/dashboard/.env.development (1)
2-2: New environment variable follows established patterns correctly.The
NEXT_PUBLIC_STACK_DOCS_BASE_URLis positioned logically withNEXT_PUBLIC_STACK_API_URLand uses the same port-prefix substitution pattern as other infrastructure variables (NEXT_PUBLIC_STACK_SVIX_SERVER_URLon line 8). The port assignment (8104) fits the existing scheme.docs/src/components/embedded-docs-message-bridge.tsx (7)
1-4: LGTM! Proper client component setup.The
'use client'directive and imports are appropriate for a component that uses hooks and browser APIs likewindowandpostMessage.
6-14: LGTM! Well-defined message types.The type definitions are clear and the
ParentMessageunion type allows for future extensibility with the{ type: string }fallback.
16-22: LGTM! Appropriate origin allowlist for postMessage security.The environment-based origin allowlist properly restricts cross-origin communication to trusted parent windows.
24-37: LGTM! Robust parent origin resolution.The function safely resolves the parent origin from the referrer with appropriate fallback and error handling.
39-71: LGTM! Well-structured state management and notification logic.The component setup uses appropriate hooks and refs. The
notifyParentcallback has proper guards, constructs correct messages, and usespostMessagewith a target origin for security.
73-98: LGTM! Correct navigation history tracking.The effect properly maintains a browser-like history stack, handling initial state, same-path navigation, and forward navigation after going back. The history splice at line 92 correctly clears forward entries when navigating to a new path.
100-131: LGTM! Correct back navigation handling with proper security.The message listener properly validates origin and source, and the
NAVIGATE_BACKhandling is now correct:
- Updates the index before calling
router.push(line 121-122)- Removes the immediate
notifyParentcall afterrouter.push(as noted in past reviews)- Lets the pathname effect (lines 74-98) handle notification, preventing duplicate messages
The guards on lines 116-119 correctly handle edge cases where history entries might be missing.
docs/src/components/embedded-link-interceptor.tsx (1)
101-155: Previous concerns addressed effectively.The click handler now properly:
- Respects user intent by checking for modified clicks and special link attributes (lines 103, 116-118, 120-122)
- Uses
router.pushfor client-side navigation instead of full page reload- Navigates even when URL existence check fails, preventing broken links
- Filters unsafe schemes before interception
These changes address the major concerns raised in previous reviews.
|
Deployment failed with the following error: |
Important
Adds a unified documentation widget to the dashboard, enabling in-app viewing and switching of documentation types with platform-specific adaptations.
UnifiedDocsWidgettostack-companion.tsxfor viewing docs within the dashboard.docs/src/appforapi-embed,dashboard-embed, anddocs-embed.EmbeddedLinkInterceptorandPlatformChangeNotifierfor link handling and platform change notifications.generate-docs.jsto include dashboard docs generation.NEXT_PUBLIC_STACK_DOCS_BASE_URLto.env.developmentandenv.tsx.next.config.mjsfor dashboard embedding.global.cssto support embedded content.EmbeddedLinkcomponent for MDX link handling inmdx-components.tsx.This description was created by
for 5760b90. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Style
Chores
UX