-
Notifications
You must be signed in to change notification settings - Fork 619
Add API Reference section to portal app #7968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduces a new API Reference page at /reference, including a sidebar link in the header. Implements ModernApiReference with endpoint grouping, detailed documentation, and code examples. Adds supporting page and metadata for the new section.
|
|
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 /reference App Router page that embeds the Scalar API Reference viewer with theme synchronization and mobile sticky CSS, introduces the @scalar/api-reference-react dependency, and updates the header to include an "API Reference" nav item and safer pathname checks. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Browser
participant NextApp as Next.js App Router
participant Page as /reference (SSR)
participant Client as ScalarApiReference (client)
participant Scalar as ApiReferenceReact
participant API as api.thirdweb.com
User->>Browser: Navigate to /reference
Browser->>NextApp: Request route
NextApp-->>Browser: Serve /reference page markup & metadata
Browser->>Page: Hydrate client components
Page->>Client: Mount ScalarApiReference (use client)
Client->>Client: useTheme() -> toggle body classes (dark/light)
Client->>Scalar: Init with config (openapi url, theme, layout, flags)
Scalar->>API: Fetch openapi.json
API-->>Scalar: Return OpenAPI spec
Scalar-->>Browser: Render API Reference UI (sidebar, docs)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (4)
✨ Finishing Touches🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7968 +/- ##
=======================================
Coverage 56.52% 56.53%
=======================================
Files 904 904
Lines 58623 58626 +3
Branches 4146 4146
=======================================
+ Hits 33138 33145 +7
+ Misses 25380 25375 -5
- Partials 105 106 +1
🚀 New features to boost your workflow:
|
Replaces explicit width and height utility classes (e.g., w-4 h-4) with the 'size-*' utility for consistency and brevity. Also removes unnecessary flex-shrink-0 in favor of shrink-0 and simplifies overflow handling in code blocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/portal/src/app/Header.tsx (1)
477-483: Harden external links: add rel="noopener noreferrer" and avoid empty targetPrevent reverse tabnabbing and avoid rendering target="" on internal links.
- target={info.href.startsWith("http") ? "_blank" : ""} + target={info.href.startsWith("http") ? "_blank" : undefined} + rel={info.href.startsWith("http") ? "noopener noreferrer" : undefined} ... - target={props.href.startsWith("http") ? "_blank" : ""} + target={props.href.startsWith("http") ? "_blank" : undefined} + rel={props.href.startsWith("http") ? "noopener noreferrer" : undefined}Also applies to: 540-541
🧹 Nitpick comments (9)
apps/portal/src/app/Header.tsx (1)
288-291: Fix active-state matching to avoid false positives (e.g., “/reference” vs “/references”)startsWith() will mark “API Reference” active on paths like “/references/typescript/v5”. Use segment-aware matching.
+// add near the top-level (module scope) +const isActive = (pathname: string | null, href: string) => { + if (!pathname) return false; + if (href === "/") return pathname === "/"; + return pathname === href || pathname.startsWith(`${href}/`); +}; ... - {pathname?.startsWith(link.href) && ( + {isActive(pathname, link.href) && ( <div className="bg-violet-700 h-[2px] inset-x-0 rounded-full absolute -bottom-1" /> )} ... - pathname?.startsWith(props.href) + isActive(pathname, props.href) ? "text-foreground" : "text-muted-foreground",Also applies to: 533-536
apps/portal/src/app/reference/ModernApiReference.tsx (7)
3-3: React Query provider is unused — remove to cut bundle sizeNo useQuery/useMutation in this module; drop QueryClient to trim JS.
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +// React Query not used here ... -const queryClient = new QueryClient(); - -export default function ModernApiReference() { - return ( - <QueryClientProvider client={queryClient}> - <ModernApiReferenceContent /> - </QueryClientProvider> - ); -} +export default function ModernApiReference(): JSX.Element { + return <ModernApiReferenceContent />; +}Also applies to: 396-404
341-356: Lazy-load Shiki to reduce initial client bundleMove shiki import inside the effect (already shown in the XSS fix) to code-split highlighting.
479-498: Use stable keys in skeleton to avoid unnecessary re-rendersDate.now() inside render changes keys across frames.
- {Array.from({ length: 5 }, (_, i) => { - const groupId = `skeleton-group-${Date.now()}-${i}`; - return ( - <div key={groupId} className="space-y-2"> + {Array.from({ length: 5 }, (_, i) => ( + <div key={`skeleton-group-${i}`} className="space-y-2"> ... - {Array.from({ length: 3 }, (_, j) => { - const itemId = `skeleton-item-${Date.now()}-${i}-${j}`; - return ( - <div - key={itemId} - className="h-8 bg-muted/40 rounded animate-pulse" - /> - ); - })} + {Array.from({ length: 3 }, (_, j) => ( + <div + key={`skeleton-item-${i}-${j}`} + className="h-8 bg-muted/40 rounded animate-pulse" + /> + ))} ... - ); - })} + ))}Also applies to: 486-496
872-893: External “View in API Reference” link may be incorrect; add noopener as wellConstructing anchors by stripping “/” is likely incompatible with the reference site’s anchor scheme. Prefer operationId when available, or fall back to tag-only; add window features for security.
- const tagFromEndpoint = - selectedEndpoint.endpoint.tags?.[0]?.toLowerCase() || - "default"; - const methodLower = selectedEndpoint.method.toLowerCase(); - const pathForUrl = selectedEndpoint.path.replace( - /\//g, - "", - ); - window.open( - `https://api.thirdweb.com/reference#tag/${tagFromEndpoint}/${methodLower}${pathForUrl}`, - "_blank", - ); + const tagFromEndpoint = + selectedEndpoint.endpoint.tags?.[0]?.toLowerCase() || + "default"; + const opId = (selectedEndpoint.endpoint as any)?.operationId as + | string + | undefined; + let dest = `https://api.thirdweb.com/reference#tag/${encodeURIComponent(tagFromEndpoint)}`; + if (opId) { + dest += `/${encodeURIComponent(opId)}`; + } + window.open(dest, "_blank", "noopener,noreferrer");
1014-1018: Show the JSON schema itself instead of the entire requestBody wrapperImproves signal; the wrapper includes media-type boilerplate.
- <JsonViewer - data={selectedEndpoint.endpoint.requestBody} - title="Request Body Schema" - defaultOpen={false} - /> + <JsonViewer + data={ + (selectedEndpoint.endpoint.requestBody?.content as any)?.[ + "application/json" + ]?.schema ?? selectedEndpoint.endpoint.requestBody + } + title="Request Body Schema" + defaultOpen={false} + />
19-34: Type/style nits: prefer type aliases and explicit component return types
- Switch interfaces to type aliases per repo guidance.
- Add explicit return types: ModernApiReference(): JSX.Element, ModernApiReferenceContent(): JSX.Element, CodeExample(): JSX.Element, JsonViewer(): JSX.Element | null.
Example:
-export default function ModernApiReference() { +export default function ModernApiReference(): JSX.Element { ... -function ModernApiReferenceContent() { +function ModernApiReferenceContent(): JSX.Element { ... -function CodeExample({ ... }: { ... }) { +function CodeExample({ ... }: { ... }): JSX.Element { ... -function JsonViewer({ data, title, defaultOpen = false }: JsonViewerProps) { +function JsonViewer({ data, title, defaultOpen = false }: JsonViewerProps): JSX.Element | null {Also applies to: 36-52, 54-67, 68-73, 398-404, 406-416, 327-336, 290-325
221-265: Schema-driven generators: consider $ref/oneOf/allOf and non-JSON bodies laterCurrent helpers cover common cases; plan support for $ref and arrays/oneOf to improve fidelity; also handle form-data/URL-encoded content types.
I can wire a lightweight $ref resolver against spec.components.schemas without pulling a heavy OpenAPI parser.
Also applies to: 74-167, 169-219
apps/portal/src/app/reference/page.tsx (1)
13-15: Add explicit return type and consider dynamic import to keep server bundle leanMark return type; optionally client-only dynamic import for the heavy viewer.
-import ModernApiReference from "./ModernApiReference"; +import dynamic from "next/dynamic"; +const ModernApiReference = dynamic(() => import("./ModernApiReference"), { + ssr: false, +}); ... -export default function ApiReferencePage() { +export default function ApiReferencePage(): JSX.Element { return <ModernApiReference />; }
📜 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 (3)
apps/portal/src/app/Header.tsx(3 hunks)apps/portal/src/app/reference/ModernApiReference.tsx(1 hunks)apps/portal/src/app/reference/page.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/portal/src/app/Header.tsxapps/portal/src/app/reference/page.tsxapps/portal/src/app/reference/ModernApiReference.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/portal/src/app/Header.tsxapps/portal/src/app/reference/page.tsxapps/portal/src/app/reference/ModernApiReference.tsx
🧠 Learnings (6)
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use `NavLink` for internal navigation with automatic active states in dashboard and playground apps
Applied to files:
apps/portal/src/app/Header.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use `NavLink` (`@/components/ui/NavLink`) for internal navigation so active states are handled automatically.
Applied to files:
apps/portal/src/app/Header.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to apps/{dashboard,playground}/**/*.{ts,tsx} : Use `NavLink` for internal navigation to get active state handling
Applied to files:
apps/portal/src/app/Header.tsx
📚 Learning: 2025-06-18T04:27:16.172Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:27:16.172Z
Learning: Next.js Link component supports external URLs without throwing errors. When used with absolute URLs (like https://...), it behaves like a regular anchor tag without client-side routing, but does not cause runtime crashes or errors as previously believed.
Applied to files:
apps/portal/src/app/Header.tsx
📚 Learning: 2025-06-18T04:30:04.326Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:30:04.326Z
Learning: Next.js Link component fully supports both internal and external URLs and works appropriately with all standard anchor attributes including target="_blank", rel="noopener noreferrer", etc. Using Link for external URLs is completely appropriate and recommended.
Applied to files:
apps/portal/src/app/Header.tsx
📚 Learning: 2025-08-07T17:24:31.965Z
Learnt from: MananTank
PR: thirdweb-dev/js#7812
File: apps/dashboard/src/app/(app)/team/~/~project/[[...paths]]/page.tsx:1-11
Timestamp: 2025-08-07T17:24:31.965Z
Learning: In Next.js App Router, page components (page.tsx files) are server components by default and do not require the "server-only" import directive. The "server-only" directive is primarily used for utility functions, API helpers, and data access modules that should never be included in the client bundle.
Applied to files:
apps/portal/src/app/reference/page.tsx
🧬 Code graph analysis (2)
apps/portal/src/app/reference/page.tsx (1)
apps/portal/src/app/reference/ModernApiReference.tsx (1)
ModernApiReference(398-404)
apps/portal/src/app/reference/ModernApiReference.tsx (2)
apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (1)
ApiEndpoint(45-229)apps/playground-web/src/components/code/code-example.tsx (1)
CodeExample(17-56)
🪛 ast-grep (0.38.6)
apps/portal/src/app/reference/ModernApiReference.tsx
[warning] 384-384: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 GitHub Check: Lint Packages
apps/portal/src/app/reference/ModernApiReference.tsx
[warning] 543-543:
Classname 'no-scrollbar' is not a Tailwind CSS class!
⏰ 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). (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (3)
apps/portal/src/app/Header.tsx (1)
30-33: Add “API Reference” nav item — looks goodMatches the new /reference route and integrates cleanly with existing nav.
apps/portal/src/app/reference/ModernApiReference.tsx (1)
543-543: .no-scrollbar utility is defined
The .no-scrollbar class is present in packages/ui/src/global.css (and apps/nebula/src/global.css), so no-op risk is avoided.apps/portal/src/app/reference/page.tsx (1)
4-11: Metadata block — looks goodConcise and consistent with docs pages.
size-limit report 📦
|
Removed the custom ModernApiReference implementation and replaced it with the ScalarApiReference component using @scalar/api-reference-react. Updated dependencies and imports accordingly to leverage the official Scalar API reference UI, ensuring theme consistency and easier maintenance.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/portal/src/app/reference/ScalarClient.tsx (1)
3-7: Lazy‑load Scalar and add explicit JSX type import to reduce initial bundle and avoid SSR issues.Use next/dynamic for the heavy lib and import JSX for explicit return type. Keeps hydration safe and aligns with guidelines.
-import { ApiReferenceReact } from "@scalar/api-reference-react"; +import dynamic from "next/dynamic"; import "@scalar/api-reference-react/style.css"; import "./scaler-app.css"; import { useTheme } from "next-themes"; -import { useEffect } from "react"; +import { useEffect, useState, type JSX } from "react"; + +const ApiReferenceReact = dynamic( + () => import("@scalar/api-reference-react").then((m) => m.ApiReferenceReact), + { ssr: false }, +);
🧹 Nitpick comments (4)
apps/portal/src/app/reference/scaler-app.css (2)
1-4: Ensure the.scalar-appwrapper exists or widen scope so CSS vars apply.If the page doesn’t wrap Scalar with a
.scalar-appcontainer, these vars won’t resolve. Either add the wrapper (see ScalarClient.tsx suggestion) or widen scope.Option A (widen scope):
-.scalar-app { +:root, .scalar-app { --scalar-background-1: hsl(var(--background)); --scalar-background-2: hsl(var(--card)); }
7-11: Improve sticky reliability: fallback, stacking, and background.Prevents overlap/bleed under headers and missing custom property.
.scalar-app .references-navigation-list, .scalar-app .references-header { position: sticky; - top: var(--sticky-top-height); + top: var(--sticky-top-height, 64px); + z-index: 10; + background: var(--scalar-background-1); }apps/portal/src/app/reference/ScalarClient.tsx (2)
9-21: UseresolvedTheme+ mount guard to avoid FOUC and ‘system’ mismatch; clean up classes.Prevents incorrect mode when theme=system and avoids first‑paint flash. Also fixes the “scaler” typo in the comment.
-export function ScalarApiReference() { - const { theme } = useTheme(); +export function ScalarApiReference(): JSX.Element | null { + const { resolvedTheme } = useTheme(); + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); - // scaler is using light-mode and dark-mode classes for theming - useEffect(() => { - if (theme === "dark") { - document.body.classList.remove("light-mode"); - document.body.classList.add("dark-mode"); - } else { - document.body.classList.remove("dark-mode"); - document.body.classList.add("light-mode"); - } - }, [theme]); + // scalar uses light-mode and dark-mode classes for theming + useEffect(() => { + const cls = resolvedTheme === "dark" ? "dark-mode" : "light-mode"; + const inverse = cls === "dark-mode" ? "light-mode" : "dark-mode"; + document.body.classList.add(cls); + document.body.classList.remove(inverse); + return () => { + document.body.classList.remove(cls); + }; + }, [resolvedTheme]); + + if (!mounted) return null;
23-36: Wrap with.scalar-appto activate the new CSS variables and sticky rules.Ensures theme vars and sticky behavior apply.
- return ( - <ApiReferenceReact - configuration={{ - url: "https://api.thirdweb.com/openapi.json", - theme: "deepSpace", - layout: "modern", - showSidebar: true, - hideModels: false, - hideDarkModeToggle: true, // Hide since portal controls theme - hideDownloadButton: false, - hideTestRequestButton: false, - }} - /> - ); + return ( + <div className="scalar-app"> + <ApiReferenceReact + configuration={{ + url: "https://api.thirdweb.com/openapi.json", + theme: "deepSpace", + layout: "modern", + showSidebar: true, + hideModels: false, + hideDarkModeToggle: true, // Hide since portal controls theme + hideDownloadButton: false, + hideTestRequestButton: false, + }} + /> + </div> + );
📜 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 (3)
apps/portal/src/app/reference/ScalarClient.tsx(1 hunks)apps/portal/src/app/reference/page.tsx(1 hunks)apps/portal/src/app/reference/scaler-app.css(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/portal/src/app/reference/page.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/portal/src/app/reference/ScalarClient.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/portal/src/app/reference/ScalarClient.tsx
🧠 Learnings (3)
📚 Learning: 2025-07-31T16:17:42.753Z
Learnt from: MananTank
PR: thirdweb-dev/js#7768
File: apps/playground-web/src/app/navLinks.ts:1-1
Timestamp: 2025-07-31T16:17:42.753Z
Learning: Configuration files that import and reference React components (like icon components from lucide-react) need the "use client" directive, even if they primarily export static data, because the referenced components need to be executed in a client context when used by other client components.
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
⏰ 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). (7)
- GitHub Check: E2E Tests (pnpm, vite)
- GitHub Check: E2E Tests (pnpm, webpack)
- GitHub Check: Unit Tests
- GitHub Check: Build Packages
- GitHub Check: Size
- GitHub Check: Lint Packages
- GitHub Check: Analyze (javascript)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (4)
apps/portal/src/app/reference/ScalarClient.tsx (4)
7-7: Add JSX return type and mounted state import.Makes return type explicit and prepares for a hydration guard.
-import { useEffect } from "react"; +import { useEffect, useState, type JSX } from "react";
3-3: Lazy‑load Scalar to keep initial bundles lean.Replace the static import with next/dynamic per our guideline to load heavy deps lazily.
-import { ApiReferenceReact } from "@scalar/api-reference-react"; +import dynamic from "next/dynamic";
8-9: Define dynamic import for ApiReferenceReact (SSR off).Prevents DOM access during SSR and trims the initial bundle.
+ +const ApiReferenceReact = dynamic( + () => import("@scalar/api-reference-react").then((m) => m.ApiReferenceReact), + { ssr: false }, +);
9-11: Add explicit return type and hydration guard.Avoids theme flicker/hydration mismatch and follows explicit return‑type guideline.
-export function ScalarApiReference() { - const { theme } = useTheme(); +export function ScalarApiReference(): JSX.Element | null { + const { resolvedTheme } = useTheme(); + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + if (!mounted) return null;
🧹 Nitpick comments (2)
apps/portal/src/app/reference/ScalarClient.tsx (2)
12-12: Fix typo in comment.- // scaler is using light-mode and dark-mode classes for theming + // Scalar uses "light-mode" and "dark-mode" classes for theming
26-26: Externalize the OpenAPI URL.Allow overriding via env while keeping a sane default.
- url: "https://api.thirdweb.com/openapi.json", + url: process.env.NEXT_PUBLIC_THIRDWEB_OPENAPI_URL ?? "https://api.thirdweb.com/openapi.json",
📜 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 (2)
apps/portal/src/app/reference/ScalarClient.tsx(1 hunks)apps/portal/src/app/reference/scalar.css(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- apps/portal/src/app/reference/scalar.css
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from@/typesor localtypes.tsbarrels
Prefer type aliases over interface except for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial,Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from@/typeswhere applicable
Prefertypealiases overinterfaceexcept for nominal shapes
Avoidanyandunknownunless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Files:
apps/portal/src/app/reference/ScalarClient.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Files:
apps/portal/src/app/reference/ScalarClient.tsx
🧠 Learnings (3)
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to **/*.{ts,tsx} : Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
📚 Learning: 2025-07-31T16:17:42.753Z
Learnt from: MananTank
PR: thirdweb-dev/js#7768
File: apps/playground-web/src/app/navLinks.ts:1-1
Timestamp: 2025-07-31T16:17:42.753Z
Learning: Configuration files that import and reference React components (like icon components from lucide-react) need the "use client" directive, even if they primarily export static data, because the referenced components need to be executed in a client context when used by other client components.
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)
Applied to files:
apps/portal/src/app/reference/ScalarClient.tsx
⏰ 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). (3)
- GitHub Check: Size
- GitHub Check: Unit Tests
- GitHub Check: Analyze (javascript)
🔇 Additional comments (1)
apps/portal/src/app/reference/ScalarClient.tsx (1)
24-35: Config looks good.The Scalar viewer options align with Portal theming and expected UX.
Introduces a new API Reference page at /reference, including a sidebar link in the header. Implements ModernApiReference with endpoint grouping, detailed documentation, and code examples. Adds supporting page and metadata for the new section.
Closes BLD-230
PR-Codex overview
This PR introduces the
@scalar/api-reference-reactpackage to the portal, enhances styling for the API reference page, and integrates a newScalarApiReferencecomponent. It also updates theHeaderto include a link to the API reference.Detailed summary
@scalar/api-reference-reacttopackage.json..scalar-appstyles inscalar.css.ApiReferencePagecomponent inpage.tsx.Headercomponent to include "API Reference" link.ScalarApiReferenceto render API documentation.Summary by CodeRabbit
New Features
Bug Fixes
Chores