Skip to content

Conversation

@MananTank
Copy link
Member

@MananTank MananTank commented Sep 24, 2025


PR-Codex overview

This PR focuses on improving the UI components and layout of the application. It includes adjustments to styling, spacing, and structure, enhancing overall user experience and visual consistency.

Detailed summary

  • Updated grid spacing in Grid.tsx.
  • Increased max width in layout.tsx.
  • Changed border styles in various components.
  • Adjusted button variants and styles in chat-button.tsx and page.tsx.
  • Enhanced accessibility and visual hierarchy in DocLayout.tsx and Sidebar.tsx.
  • Improved responsiveness and spacing in Feedback.tsx and Header.tsx.
  • Refined text styles and sizes in multiple components for better readability.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Style

    • UI polish across the site: refined typography, spacing, tighter headings, dashed borders for dividers/images/code, smaller author avatar, absolute date display, wider content area, updated button visuals (ghost/outline), adjusted icons/shadows, refreshed link/inline-code/grid/card styles, tabs and header/menu visual updates.
    • Footer, sidebar, docs search, subscribe, feedback, and table-of-contents presentational tweaks (including fade-in and conditional hiding).
  • Refactor

    • Simplified changelog/post layout to a single-column, header-first flow and removed the changelog index TOC.

@vercel
Copy link

vercel bot commented Sep 24, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Ready Preview Comment Sep 25, 2025 8:42am
thirdweb_playground Ready Ready Preview Comment Sep 25, 2025 8:42am
thirdweb-www Ready Ready Preview Comment Sep 25, 2025 8:42am
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
nebula Skipped Skipped Sep 25, 2025 8:42am
wallet-ui Skipped Skipped Sep 25, 2025 8:42am

@linear
Copy link

linear bot commented Sep 24, 2025

@vercel vercel bot temporarily deployed to Preview – thirdweb-www September 24, 2025 20:33 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 24, 2025 20:33 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground September 24, 2025 20:33 Inactive
@changeset-bot
Copy link

changeset-bot bot commented Sep 24, 2025

⚠️ No Changeset found

Latest commit: 7bc513c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 24, 2025

Walkthrough

Widespread presentational updates across the Portal app: changelog layouts widened and simplified, dashed borders and adjusted spacing added, dates switched to absolute format, a TOC component removed, typography and avatar sizes tweaked, and various UI components restyled without changing public APIs (except TOC removal).

Changes

Cohort / File(s) Summary
Changelog slug layout & page
apps/portal/src/app/changelog/[slug]/layout.tsx, apps/portal/src/app/changelog/[slug]/page.tsx
Increased container width (max-w-3xlmax-w-4xl); back navigation Button now variant="ghost"; divider changed to border-t border-dashed; layout and header spacing adjusted.
Changelog index page
apps/portal/src/app/changelog/page.tsx
Reworked to a single-column flow with a bordered "Changelog" header; removed TOC/Author imports and PlusIcon; per-post date badge and simplified avatar/metadata placement; content wrapper and spacing updated.
Removed component
apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx
File deleted; exported ChangelogIndexTOC (client component) and its helper removed.
Per-post metadata & date rendering
apps/portal/src/app/changelog/components/Author.tsx, apps/portal/src/app/changelog/components/RenderData.tsx
Avatar size reduced (size-8size-6); author name font-weight removed; RenderDate switched from formatDistance (relative) to formatDate (absolute "MMM d, yyyy") and simplified time element classes.
Changelog content transforms
apps/portal/src/app/changelog/utils/transform.tsx
Paragraphs get leading-7; image blocks now render as larger dashed/semi-transparent card containers with padding/margins; code blocks added bg-card/50 and border-dashed.
Document images & headings
apps/portal/src/components/Document/DocImage.tsx, apps/portal/src/components/Document/Heading.tsx
DocImage adds border-dashed; headings h2–h4 font weight changed (font-mediumfont-semibold), h3/h4 add tracking-tight.
Header, NavLink & navigation
apps/portal/src/app/Header.tsx
Header spacing, background, dropdowns and menu styles adjusted; right-side dropdowns consolidated; NavLink signature extended with optional className prop.
Document/UI component styling updates
apps/portal/src/components/Document/*, apps/portal/src/components/others/*, apps/portal/src/components/ui/tabs.tsx, packages/ui/src/components/code/CodeBlockContainer.tsx
Multiple presentational tweaks: DocLink, Grid, InlineCode, SDKCard, PageFooter (new dashed-border footer layout), DocLayout middle column widened (720px820px), DocSearch, Feedback (DialogHeader/DialogTitle/DialogDescription/Textarea exports added), Sidebar, Subscribe, TableOfContents (early return if empty + animate-in), Tabs triggers, and default ScrollShadow color changed (--muted--card). No API signature removals except the TOC component.

Sequence Diagram(s)

sequenceDiagram
    participant Browser
    participant ChangelogPage as Changelog Page
    participant DataSource as DataLoader
    participant Renderer as Renderer

    Note over Browser,ChangelogPage: Request /changelog or /changelog/[slug]
    Browser->>ChangelogPage: GET
    ChangelogPage->>DataSource: fetch posts / post data
    DataSource-->>ChangelogPage: posts data
    ChangelogPage->>Renderer: render list/post
    note right of Renderer #F3F4F6: Renderer outputs absolute dates, dashed borders, updated layout\nTOC component call removed
    Renderer-->>Browser: HTML/CSS with updated presentation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Possibly related PRs

  • Portal: UI tweaks/fixes #7978 — Overlapping presentational UI changes across the Portal app affecting components like AuthMethodsTabs, DocLayout, and TableOfContents.

Suggested reviewers

  • jnsdls

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning This pull request introduces styling and structural updates across numerous unrelated components—such as Header, Feedback dialog, Document components, and navigation elements—which exceed the scope of the linked issue focused solely on the changelog page. Consider extracting or moving unrelated changes into separate pull requests so that this PR remains focused on the changelog layout adjustments.
Description Check ⚠️ Warning The pull request description contains only the commented template and a generic PR-Codex overview without filling in required sections such as “Notes for the reviewer” and “How to test,” leaving it incomplete relative to the repository’s description template. Please complete the PR description by adding the concise summary, reviewer notes, and testing instructions as specified in the repository template.
Docstring Coverage ⚠️ Warning Docstring coverage is 3.23% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title “[BLD-328] Portal: Update changelog page layout” clearly and concisely summarizes the primary change of updating the changelog page layout, includes the appropriate issue tag and scope, and avoids unnecessary details or formatting noise, making it easily understandable for teammates scanning the history.
Linked Issues Check ✅ Passed The changes remove the ChangeLogIndexTOC component to eliminate the “On this page” section and adjust the page layout so that the timestamp and author render below the title, directly addressing both objectives of issue BLD-328.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bld-328

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel vercel bot temporarily deployed to Preview – nebula September 24, 2025 20:33 Inactive
@github-actions github-actions bot added the Portal Involves changes to the Portal (docs) codebase. label Sep 24, 2025
@MananTank MananTank marked this pull request as ready for review September 24, 2025 20:33
@MananTank MananTank requested review from a team as code owners September 24, 2025 20:33
Copy link
Member Author

MananTank commented Sep 24, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

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.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codecov
Copy link

codecov bot commented Sep 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.26%. Comparing base (9069351) to head (7bc513c).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8124   +/-   ##
=======================================
  Coverage   56.26%   56.26%           
=======================================
  Files         906      906           
  Lines       59193    59193           
  Branches     4173     4173           
=======================================
  Hits        33305    33305           
  Misses      25783    25783           
  Partials      105      105           
Flag Coverage Δ
packages 56.26% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 24, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.09 KB (0%) 1.3 s (0%) 249 ms (+354.68% 🔺) 1.6 s
thirdweb (cjs) 361.63 KB (0%) 7.3 s (0%) 672 ms (+34.32% 🔺) 8 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 105 ms (+3336.19% 🔺) 220 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 105 ms (+5902.3% 🔺) 115 ms
thirdweb/react (minimal + tree-shaking) 19.14 KB (0%) 383 ms (0%) 107 ms (+3920.06% 🔺) 490 ms

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/portal/src/app/changelog/[slug]/page.tsx (2)

37-65: Timestamp still renders above the title

The linked issue calls for the timestamp to appear below the changelog entry title. We still render the <RenderDate> block ahead of the <h1>, so the acceptance criterion isn’t met. Please move the date (and authors, if needed) underneath the title.

Apply something like the following:

-      {data.updated_at && (
-        <div className="mb-10">
-          <RenderDate iso={data.updated_at} />
-        </div>
-      )}
-
-      <h1
+      <h1
         className={cn(
           "mb-8 break-words font-bold text-4xl text-foreground tracking-tight md:text-5xl",
         )}
       >
         {data.title}
       </h1>
 
+      {data.updated_at && (
+        <div className="mt-4 mb-6">
+          <RenderDate iso={data.updated_at} />
+        </div>
+      )}

47-53: Guard timeline date against missing published_at

On the XL timeline rail we render <RenderDate iso={post.published_at} /> without checking that published_at exists. When Ghost leaves that field null, new Date(undefined) produces “now,” giving users a misleading timestamp. Please skip the date display when the field is empty.

-              <div className="-left-16 -translate-x-full absolute top-12 hidden xl:flex gap-5 ml-3 items-center">
-                <div className="hidden xl:block text-sm text-muted-foreground">
-                  <RenderDate iso={post.published_at} />
-                </div>
+              <div className="-left-16 -translate-x-full absolute top-12 hidden xl:flex gap-5 ml-3 items-center">
+                {post.published_at && (
+                  <div className="hidden xl:block text-sm text-muted-foreground">
+                    <RenderDate iso={post.published_at} />
+                  </div>
+                )}
                 <div className="size-6 rounded-[50%] border bg-background flex items-center justify-center">
                   <div className="size-2 bg-blue-500 rounded-full" />
                 </div>
               </div>
🧹 Nitpick comments (2)
apps/portal/src/components/Document/Heading.tsx (1)

36-36: Verify typographic hierarchy (h2 and h3 both text-xl).

Design-wise, h3 equals h2 in size now; confirm this is intentional. tracking-tight and increased weight are fine.

If needed, consider making h3 slightly smaller for clearer hierarchy:

- "break-words font-semibold text-foreground text-xl tracking-tight",
+ "break-words font-semibold text-foreground text-lg tracking-tight",

Also applies to: 55-56, 74-75

apps/portal/src/app/changelog/utils/transform.tsx (1)

80-83: Image wrapper styling LGTM; consider reusing DocImage for consistency.

To reduce divergence with DocImage defaults and keep image treatment consistent across docs, you could reuse DocImage here (with containerClassName overrides) instead of duplicating a wrapper.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ed47e93 and dbcf2ab.

📒 Files selected for processing (9)
  • apps/portal/src/app/changelog/[slug]/layout.tsx (1 hunks)
  • apps/portal/src/app/changelog/[slug]/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/components/Author.tsx (1 hunks)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx (0 hunks)
  • apps/portal/src/app/changelog/components/RenderData.tsx (1 hunks)
  • apps/portal/src/app/changelog/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/utils/transform.tsx (3 hunks)
  • apps/portal/src/components/Document/DocImage.tsx (1 hunks)
  • apps/portal/src/components/Document/Heading.tsx (3 hunks)
💤 Files with no reviewable changes (1)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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/changelog/[slug]/layout.tsx
  • apps/portal/src/app/changelog/[slug]/page.tsx
  • apps/portal/src/components/Document/Heading.tsx
  • apps/portal/src/components/Document/DocImage.tsx
  • apps/portal/src/app/changelog/page.tsx
  • apps/portal/src/app/changelog/components/Author.tsx
  • apps/portal/src/app/changelog/components/RenderData.tsx
  • apps/portal/src/app/changelog/utils/transform.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/changelog/[slug]/layout.tsx
  • apps/portal/src/app/changelog/[slug]/page.tsx
  • apps/portal/src/components/Document/Heading.tsx
  • apps/portal/src/components/Document/DocImage.tsx
  • apps/portal/src/app/changelog/page.tsx
  • apps/portal/src/app/changelog/components/Author.tsx
  • apps/portal/src/app/changelog/components/RenderData.tsx
  • apps/portal/src/app/changelog/utils/transform.tsx
🧠 Learnings (7)
📚 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 the `container` class with a `max-w-7xl` cap for page width consistency.

Applied to files:

  • apps/portal/src/app/changelog/[slug]/layout.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/**/layout.tsx : Building layout shells (`layout.tsx`) and top-level pages that mainly assemble data.

Applied to files:

  • apps/portal/src/app/changelog/[slug]/layout.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 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/changelog/[slug]/page.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/changelog/[slug]/page.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} : Combine class names via `cn`, expose `className` prop if useful.

Applied to files:

  • apps/portal/src/components/Document/DocImage.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: Surface breaking changes prominently in PR descriptions

Applied to files:

  • apps/portal/src/app/changelog/page.tsx
📚 Learning: 2025-06-05T23:07:58.286Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7290
File: apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx:13-13
Timestamp: 2025-06-05T23:07:58.286Z
Learning: `formatDate` is a valid export from `date-fns` library version 4.1.0 and can be imported and used alongside other date-fns functions like `parseISO`.

Applied to files:

  • apps/portal/src/app/changelog/components/RenderData.tsx
🧬 Code graph analysis (1)
apps/portal/src/app/changelog/page.tsx (2)
apps/portal/src/app/changelog/components/RenderData.tsx (1)
  • RenderDate (4-10)
apps/portal/src/components/Document/Heading.tsx (1)
  • Heading (4-122)
⏰ 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: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Unit Tests
  • GitHub Check: Lint Packages
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
apps/portal/src/app/changelog/components/RenderData.tsx (1)

1-8: No action needed: date-fns@4.1.0 supports formatDate
Verified in apps/portal/package.json that date-fns is at v4.1.0, which exports formatDate.

apps/portal/src/app/changelog/[slug]/layout.tsx (1)

3-3: Wider container LGTM; confirm width consistency with index page.

The 4xl cap matches the index list wrapper (max-w-4xl). Good for readability.

If other changelog views ([slug] page body) still use 3xl, consider aligning them to avoid width jumps.

apps/portal/src/app/changelog/components/Author.tsx (1)

9-10: Avatar sizing/text tone tweak looks good.

The reduced avatar size and subtler name style read cleanly in lists.

Also applies to: 13-13

apps/portal/src/components/Document/DocImage.tsx (1)

18-18: Dashed container border LGTM; check global impact.

This affects all DocImage usages, not just changelog. Ensure downstream pages expect the dashed look, otherwise gate via a prop or override via containerClassName.

apps/portal/src/app/changelog/utils/transform.tsx (2)

67-67: Paragraph leading adjustment LGTM.

leading-7 improves readability without affecting layout.


112-118: CodeBlock already applies border width
CodeBlock’s default <code> includes border, so border-dashed alone is sufficient; no change needed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (6)
apps/portal/src/app/changelog/components/Author.tsx (1)

7-11: Add width/height and lazy-loading to avatar to avoid CLS and improve perf

Provide intrinsic size and defer decoding.

         <img
           alt=""
           className="size-6 rounded-[50%] border"
           src={props.profileImage}
+          width={24}
+          height={24}
+          loading="lazy"
+          decoding="async"
         />
apps/portal/src/app/changelog/[slug]/page.tsx (2)

29-35: Add an aria-label to the back link icon

Improves accessibility for icon-only navigation.

-        <Link
+        <Link
+          aria-label="Back to changelog"
           className="-translate-x-1/4 !p-2 !text-muted-foreground hover:!text-foreground mb-4 bg-transparent"
           href="/changelog"
         >

15-21: Next.js params type should not be Promise

App Router passes a plain object; remove Promise type and unnecessary await.

-export default async function Page(props: {
-  params: Promise<{
-    slug: string;
-  }>;
-}) {
-  const data = (await fetchPost((await props.params).slug))[0];
+export default async function Page(props: {
+  params: {
+    slug: string;
+  };
+}) {
+  const data = (await fetchPost(props.params.slug))[0];
apps/portal/src/app/changelog/components/RenderData.tsx (2)

1-1: Use parseISO for safer date parsing

Ensures consistent parsing of ISO strings across environments.

-import { formatDate } from "date-fns";
+import { formatDate, parseISO } from "date-fns";

6-8: Parse ISO string before formatting

Avoids relying on Date constructor quirks.

-    <time className={cn("text-sm", props.className)} dateTime={props.iso}>
-      {formatDate(new Date(props.iso), "MMM d, yyyy")}
-    </time>
+    <time className={cn("text-sm", props.className)} dateTime={props.iso}>
+      {formatDate(parseISO(props.iso), "MMM d, yyyy")}
+    </time>
apps/portal/src/app/changelog/page.tsx (1)

42-42: Avoid overflow-hidden on the page container to prevent focus ring clipping

Can cut off focus outlines/shadows. Consider dropping it unless strictly needed.

-    <div className="changelog-page overflow-hidden">
+    <div className="changelog-page">
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dbcf2ab and 746afa3.

📒 Files selected for processing (9)
  • apps/portal/src/app/changelog/[slug]/layout.tsx (1 hunks)
  • apps/portal/src/app/changelog/[slug]/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/components/Author.tsx (1 hunks)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx (0 hunks)
  • apps/portal/src/app/changelog/components/RenderData.tsx (1 hunks)
  • apps/portal/src/app/changelog/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/utils/transform.tsx (3 hunks)
  • apps/portal/src/components/Document/DocImage.tsx (1 hunks)
  • apps/portal/src/components/Document/Heading.tsx (3 hunks)
💤 Files with no reviewable changes (1)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/portal/src/app/changelog/[slug]/layout.tsx
  • apps/portal/src/components/Document/Heading.tsx
  • apps/portal/src/components/Document/DocImage.tsx
  • apps/portal/src/app/changelog/utils/transform.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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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/changelog/components/RenderData.tsx
  • apps/portal/src/app/changelog/[slug]/page.tsx
  • apps/portal/src/app/changelog/components/Author.tsx
  • apps/portal/src/app/changelog/page.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/changelog/components/RenderData.tsx
  • apps/portal/src/app/changelog/[slug]/page.tsx
  • apps/portal/src/app/changelog/components/Author.tsx
  • apps/portal/src/app/changelog/page.tsx
🧠 Learnings (5)
📚 Learning: 2025-06-05T23:07:58.286Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7290
File: apps/dashboard/src/app/(app)/team/[team_slug]/(team)/~/usage/page.tsx:13-13
Timestamp: 2025-06-05T23:07:58.286Z
Learning: `formatDate` is a valid export from `date-fns` library version 4.1.0 and can be imported and used alongside other date-fns functions like `parseISO`.

Applied to files:

  • apps/portal/src/app/changelog/components/RenderData.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 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/changelog/[slug]/page.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/changelog/[slug]/page.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/changelog/[slug]/page.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: Surface breaking changes prominently in PR descriptions

Applied to files:

  • apps/portal/src/app/changelog/page.tsx
🧬 Code graph analysis (1)
apps/portal/src/app/changelog/page.tsx (2)
apps/portal/src/app/changelog/components/RenderData.tsx (1)
  • RenderDate (4-10)
apps/portal/src/components/Document/Heading.tsx (1)
  • Heading (4-122)
⏰ 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 (5)
apps/portal/src/app/changelog/components/Author.tsx (1)

13-13: Typography tweak LGTM

The lighter author name weight reads better with the tighter layout.

apps/portal/src/app/changelog/[slug]/page.tsx (2)

37-49: Move date below the title to meet BLD-328

Current placement renders the date above the H1. The issue requests timestamp (and author) below the title.

-      {data.updated_at && (
-        <div className="mb-10">
-          <RenderDate iso={data.updated_at} />
-        </div>
-      )}
-
       <h1
         className={cn(
           "mb-8 break-words font-bold text-4xl text-foreground tracking-tight md:text-5xl",
         )}
       >
         {data.title}
       </h1>
+
+      {data.updated_at && (
+        <div className="mb-10">
+          <RenderDate iso={data.updated_at} />
+        </div>
+      )}

37-41: Confirm whether detail page should use published_at for consistency

Listing uses published_at; detail uses updated_at. If consistency is desired, switch or confirm product intent (publish vs. last updated).

-      {data.updated_at && (
+      {(data.published_at ?? data.updated_at) && (
         <div className="mb-10">
-          <RenderDate iso={data.updated_at} />
+          <RenderDate iso={(data.published_at ?? data.updated_at)!} />
         </div>
       )}
apps/portal/src/app/changelog/page.tsx (2)

47-55: Guard the entire XL date column (avoid orphaned dot when no date)

Wrap the whole side column to avoid showing the dot without a date.

-              <div className="-left-16 -translate-x-full absolute top-12 hidden xl:flex gap-5 ml-3 items-center">
-                {post.published_at && (
-                  <div className="hidden xl:block text-sm text-muted-foreground">
-                    <RenderDate iso={post.published_at} />
-                  </div>
-                )}
-                <div className="size-6 rounded-[50%] border bg-background flex items-center justify-center">
-                  <div className="size-2 bg-blue-500 rounded-full" />
-                </div>
-              </div>
+              {post.published_at && (
+                <div className="-left-16 -translate-x-full absolute top-12 hidden xl:flex gap-5 ml-3 items-center">
+                  <div className="hidden xl:block text-sm text-muted-foreground">
+                    <RenderDate iso={post.published_at} />
+                  </div>
+                  <div className="size-6 rounded-[50%] border bg-background flex items-center justify-center">
+                    <div className="size-2 bg-blue-500 rounded-full" />
+                  </div>
+                </div>
+              )}

58-64: Move the mobile date badge below the title (matches BLD-328)

Reorder so timestamp appears under the title.

-              <div>
-                {post.published_at && (
-                  <div className="xl:hidden inline-flex rounded-full border px-3 py-2 mb-4 text-muted-foreground text-xs bg-card">
-                    <RenderDate iso={post.published_at} />
-                  </div>
-                )}
-
-                <div className="space-y-3 mb-5">
+              <div>
+                <div className="space-y-3 mb-5">
                   <Heading
                     anchorClassName="[&>a]:hidden m-0"
                     anchorId={slugger.slug(post.title || "")}
                     // eslint-disable-next-line tailwindcss/no-custom-classname
                     className="changelog-title"
                     level={2}
                   >
                     <Link
                       className="!text-foreground font-semibold text-3xl md:text-4xl tracking-tight hover:underline !leading-tight"
                       href={`/changelog/${post.slug}`}
                     >
                       {post.title}
                     </Link>
                   </Heading>
                 </div>
+                {post.published_at && (
+                  <div className="xl:hidden inline-flex rounded-full border px-3 py-2 mb-4 text-muted-foreground text-xs bg-card">
+                    <RenderDate iso={post.published_at} />
+                  </div>
+                )}

Also applies to: 65-80

@vercel vercel bot temporarily deployed to Preview – nebula September 25, 2025 07:51 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 25, 2025 07:51 Inactive
@joaquim-verges joaquim-verges added the merge-queue Adds the pull request to Graphite's merge queue. label Sep 25, 2025
Copy link
Member

joaquim-verges commented Sep 25, 2025

Merge activity

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/portal/src/components/others/Subscribe.tsx (1)

42-55: Restore responsive width for the email input

Hard-coding w-64 forces the input to 16 rem. Paired with the adjacent button, the flex row now exceeds ~320 px viewports (mobile breakpoints), introducing horizontal overflow and truncation on phones. Please keep the field fluid on small screens and only clamp it at wider breakpoints.

-        <Input
-          className="rounded-r-none border-r-0 w-64"
+        <Input
+          className="w-full rounded-r-none border-r-0 md:w-64"
apps/portal/src/components/others/Sidebar.tsx (1)

106-133: Add rel="noopener noreferrer" for external links

Both anchor variants here open external URLs in a new tab without rel="noopener noreferrer", leaving the page vulnerable to reverse tabnabbing. Please add the rel attribute alongside target="_blank".

-        target={link.href.startsWith("http") ? "_blank" : undefined}
+        target={link.href.startsWith("http") ? "_blank" : undefined}
+        rel={link.href.startsWith("http") ? "noreferrer noopener" : undefined}

Apply the same adjustment to the non-icon branch below.

apps/portal/src/app/Header.tsx (1)

520-531: Allow NavLink font overrides to work

Because NavLink still hard-codes font-medium, the font-normal you pass from the desktop menu never takes effect—Tailwind’s utility order keeps the links at medium weight. Let’s only apply the default weight when no custom font class is supplied.

 function NavLink(props: {
   href: string;
   name: string;
   onClick?: () => void;
   icon?: React.FC<{ className?: string }>;
   className?: string;
 }) {
   const pathname = usePathname();
+  const hasCustomFontWeight =
+    typeof props.className === "string" &&
+    /(^|\s)(!?)font-/.test(props.className);
   return (
     <Link
       className={clsx(
-        "font-medium text-base transition-colors hover:text-foreground xl:text-sm",
+        "text-base transition-colors hover:text-foreground xl:text-sm",
         pathname?.startsWith(props.href)
           ? "text-foreground"
           : "text-muted-foreground",
         props.icon ? "flex flex-row gap-3" : "",
-        props.className,
+        props.className,
+        !hasCustomFontWeight && "font-medium",
       )}
       href={props.href}
       onClick={props.onClick}
       target={props.href.startsWith("http") ? "_blank" : ""}
     >
🧹 Nitpick comments (2)
apps/portal/src/components/others/Feedback.tsx (1)

7-16: Adopt the alias import for Textarea.

Everything else in this component pulls UI primitives from the @/components/ui/* barrel. Please mirror that for Textarea to avoid fragile relative paths if this file moves.

apps/portal/src/components/Document/AuthMethodsTabs.tsx (1)

853-862: Add aria-pressed so the selected method is conveyed accessibly

These buttons behave like a toggle group but don’t currently expose their pressed state to assistive tech. Please wire up aria-pressed to keep the selection discoverable for screen-reader users.

aria-pressed only needs to reflect the existing selectedAuth value:

             <Button
               type="button"
               variant="outline"
               key={method.id}
               onClick={() => setSelectedAuth(method.id)}
+              aria-pressed={selectedAuth === method.id}
               className={cn(
                 "overflow-hidden text-ellipsis text-sm rounded-lg hover:bg-accent justify-start gap-3 h-auto py-3 rounded-xl",
                 selectedAuth === method.id &&
                   "font-medium text-foreground bg-accent",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 746afa3 and e0df84a.

📒 Files selected for processing (19)
  • apps/portal/src/app/Header.tsx (7 hunks)
  • apps/portal/src/app/transactions/page.mdx (2 hunks)
  • apps/portal/src/app/transactions/sponsor/page.mdx (1 hunks)
  • apps/portal/src/components/AI/chat-button.tsx (1 hunks)
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx (2 hunks)
  • apps/portal/src/components/Document/Code.tsx (1 hunks)
  • apps/portal/src/components/Document/DocLink.tsx (1 hunks)
  • apps/portal/src/components/Document/Grid.tsx (1 hunks)
  • apps/portal/src/components/Document/InlineCode.tsx (1 hunks)
  • apps/portal/src/components/Document/PageFooter.tsx (3 hunks)
  • apps/portal/src/components/Document/SDKCard.tsx (1 hunks)
  • apps/portal/src/components/Layouts/DocLayout.tsx (2 hunks)
  • apps/portal/src/components/others/DocSearch.tsx (1 hunks)
  • apps/portal/src/components/others/Feedback.tsx (3 hunks)
  • apps/portal/src/components/others/Sidebar.tsx (7 hunks)
  • apps/portal/src/components/others/Subscribe.tsx (2 hunks)
  • apps/portal/src/components/others/TableOfContents.tsx (1 hunks)
  • apps/portal/src/components/ui/tabs.tsx (2 hunks)
  • packages/ui/src/components/code/CodeBlockContainer.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/portal/src/app/transactions/sponsor/page.mdx
🧰 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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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/components/Document/DocLink.tsx
  • apps/portal/src/components/Document/Grid.tsx
  • apps/portal/src/components/others/TableOfContents.tsx
  • apps/portal/src/components/Document/SDKCard.tsx
  • apps/portal/src/components/Document/PageFooter.tsx
  • apps/portal/src/components/Document/InlineCode.tsx
  • apps/portal/src/components/AI/chat-button.tsx
  • apps/portal/src/components/ui/tabs.tsx
  • apps/portal/src/components/others/DocSearch.tsx
  • packages/ui/src/components/code/CodeBlockContainer.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/components/Document/Code.tsx
  • apps/portal/src/components/Layouts/DocLayout.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Subscribe.tsx
  • apps/portal/src/components/others/Feedback.tsx
  • apps/portal/src/components/others/Sidebar.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/components/Document/DocLink.tsx
  • apps/portal/src/components/Document/Grid.tsx
  • apps/portal/src/components/others/TableOfContents.tsx
  • apps/portal/src/components/Document/SDKCard.tsx
  • apps/portal/src/components/Document/PageFooter.tsx
  • apps/portal/src/components/Document/InlineCode.tsx
  • apps/portal/src/components/AI/chat-button.tsx
  • apps/portal/src/components/ui/tabs.tsx
  • apps/portal/src/components/others/DocSearch.tsx
  • packages/ui/src/components/code/CodeBlockContainer.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/components/Document/Code.tsx
  • apps/portal/src/components/Layouts/DocLayout.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Subscribe.tsx
  • apps/portal/src/components/others/Feedback.tsx
  • apps/portal/src/components/others/Sidebar.tsx
🧠 Learnings (21)
📚 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} : Spacing utilities (`px-*`, `py-*`, `gap-*`) are preferred over custom margins.

Applied to files:

  • apps/portal/src/components/Document/Grid.tsx
📚 Learning: 2025-05-29T00:46:09.063Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Applied to files:

  • apps/portal/src/components/Document/Grid.tsx
  • apps/portal/src/components/Layouts/DocLayout.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} : Stick to design tokens (e.g., bg-card, border-border, text-muted-foreground)

Applied to files:

  • apps/portal/src/components/Document/SDKCard.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/components/Document/SDKCard.tsx
  • apps/portal/src/components/others/Sidebar.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/components/Document/SDKCard.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/components/Document/SDKCard.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Sidebar.tsx
📚 Learning: 2025-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.

Applied to files:

  • apps/portal/src/components/Document/PageFooter.tsx
  • apps/portal/src/components/Layouts/DocLayout.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} : Combine class names via `cn`, expose `className` prop if useful.

Applied to files:

  • apps/portal/src/components/Document/InlineCode.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} : Import UI primitives from `@/components/ui/_` (e.g., Button, Input, Tabs, Card)

Applied to files:

  • apps/portal/src/components/ui/tabs.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • apps/portal/src/components/ui/tabs.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.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 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/components/ui/tabs.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Sidebar.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} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/components/others/Feedback.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} : Layouts should reuse `SidebarLayout` / `FullWidthSidebarLayout` (`@/components/blocks/SidebarLayout`).

Applied to files:

  • apps/portal/src/components/Layouts/DocLayout.tsx
  • apps/portal/src/components/others/Sidebar.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/**/layout.tsx : Building layout shells (`layout.tsx`) and top-level pages that mainly assemble data.

Applied to files:

  • apps/portal/src/components/Layouts/DocLayout.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} : Responsive helpers follow mobile-first (`max-sm`, `md`, `lg`, `xl`).

Applied to files:

  • apps/portal/src/components/Layouts/DocLayout.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
  • apps/portal/src/components/others/Sidebar.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 apps/{dashboard,playground-web}/**/*.{tsx} : Expose `className` prop on root element of components for overrides

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} : Add `className` to the root element of every component for external overrides.

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/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • apps/portal/src/app/transactions/page.mdx
📚 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/**/api/**/*.{ts,tsx} : Always call `getAuthToken()` to get the JWT from cookies.

Applied to files:

  • apps/portal/src/app/transactions/page.mdx
📚 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} : Always call `getAuthToken()` to retrieve JWT from cookies on server side

Applied to files:

  • apps/portal/src/app/transactions/page.mdx
🧬 Code graph analysis (5)
apps/portal/src/components/Document/PageFooter.tsx (3)
apps/portal/src/components/Document/AutoNextPageButton.tsx (1)
  • AutoNextPageButton (8-27)
apps/portal/src/components/others/Feedback.tsx (1)
  • Feedback (17-89)
apps/portal/src/components/Document/DocLink.tsx (1)
  • DocLink (4-27)
apps/portal/src/components/Document/AuthMethodsTabs.tsx (1)
packages/ui/src/components/button.tsx (1)
  • Button (82-82)
apps/portal/src/app/Header.tsx (1)
apps/playground-web/src/components/ui/NavLink.tsx (1)
  • NavLink (14-34)
apps/portal/src/components/others/Feedback.tsx (1)
apps/playground-web/src/components/ui/dialog.tsx (5)
  • DialogTrigger (116-116)
  • DialogContent (117-117)
  • DialogHeader (118-118)
  • DialogTitle (120-120)
  • DialogDescription (121-121)
apps/portal/src/components/others/Sidebar.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Link (46-64)
🔇 Additional comments (11)
apps/portal/src/components/Document/InlineCode.tsx (1)

7-7: Inline code spacing update looks good

Sharper radius and the 3 px vertical padding match the refreshed visual spec without impacting behavior.

apps/portal/src/components/AI/chat-button.tsx (1)

23-32: Styling update aligns with the refreshed changelog visuals

Switching to variant="outline" with the muted icon treatment keeps the inline trigger consistent with the broader layout refinements in this PR. No issues spotted.

apps/portal/src/components/others/DocSearch.tsx (1)

358-362: LGTM – the widened padding and rounded outline button match the new changelog styling.
These adjustments integrate cleanly with the refreshed surface treatments elsewhere in the stack.

packages/ui/src/components/code/CodeBlockContainer.tsx (1)

34-34: Default shadow color aligns with card background.

Good call—this keeps the fade consistent with the containing surface and removes the muted tint.

apps/portal/src/components/Document/Code.tsx (1)

75-78: Explicit shadow color keeps legacy instances in sync.

Passing the new card-toned shadow makes the portal usage track the shared default—looks good.

apps/portal/src/app/transactions/page.mdx (2)

73-76: Spacing cleanup looks good

The component usage remains unchanged functionally; the tidy indentation keeps the MDX readable.


428-468: Unity tab markdown indentation LGTM

The adjusted indentation keeps the markdown headings and code block rendering as expected.

apps/portal/src/components/Document/Grid.tsx (1)

7-7: Spacing tweak aligns with refreshed card density.

The tighter gap plays nicely with the new changelog layout while keeping readability intact.

apps/portal/src/components/Layouts/DocLayout.tsx (2)

32-36: Middle column resize aligns with the updated changelog spec.

Bumping the xl middle column to 820px gives the content more breathing room without collapsing the sidebar or TOC. Nicely done.


61-63: Subheading styling now matches the refreshed typography system.

Switching to text-muted-foreground (and dropping the violet emphasis) keeps the section label consistent with the rest of the new layout palette.

apps/portal/src/components/Document/PageFooter.tsx (1)

19-33: Footer restructuring cleanly separates navigation, edit CTA, and engagement blocks.

The dashed separators, reordered next/edit buttons, and Links/Subscribe grouping read much closer to the shared design direction—looks great.

Comment on lines +13 to 14
"text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 decoration-dotted transition-colors ",
props.className,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reintroduce the underline so dotted decoration actually renders.

Tailwind’s preflight resets a { text-decoration: inherit; }, so without the underline utility this change strips the link decoration entirely and the dotted styling never appears. That regresses our affordance/UX cue for document links. Please keep the underline while applying the new color palette.

-        "text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 decoration-dotted transition-colors ",
+        "text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 underline decoration-dotted transition-colors",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 decoration-dotted transition-colors ",
props.className,
"text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 underline decoration-dotted transition-colors",
props.className,
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/DocLink.tsx around lines 13 to 14, the
link class list removed the Tailwind underline utility which causes the dotted
text-decoration to not render due to Preflight resetting text-decoration; re-add
the "underline" utility to the class list (e.g., include "underline
decoration-dotted" alongside the color classes) so the dotted decoration
displays while keeping the new color palette.

Comment on lines 12 to 16
<Link
className="flex items-center gap-2 rounded-lg border bg-card p-2 px-4 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
className="flex items-center gap-3 rounded-xl border bg-card px-4 py-3.5 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
href={props.href}
target={props.isExternal ? "_blank" : undefined}
>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add rel attribute when using target="_blank"

Opening external links in a new tab without rel="noopener noreferrer" exposes us to reverse-tabnabbing. Please add the rel guard alongside the target toggle.

     <Link
       className="flex items-center gap-3 rounded-xl border bg-card px-4 py-3.5 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
       href={props.href}
       target={props.isExternal ? "_blank" : undefined}
+      rel={props.isExternal ? "noopener noreferrer" : undefined}
     >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Link
className="flex items-center gap-2 rounded-lg border bg-card p-2 px-4 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
className="flex items-center gap-3 rounded-xl border bg-card px-4 py-3.5 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
href={props.href}
target={props.isExternal ? "_blank" : undefined}
>
<Link
className="flex items-center gap-3 rounded-xl border bg-card px-4 py-3.5 transition-colors hover:border-active-border text-foreground/80 hover:text-foreground shadow-sm"
href={props.href}
target={props.isExternal ? "_blank" : undefined}
rel={props.isExternal ? "noopener noreferrer" : undefined}
>
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/SDKCard.tsx around lines 12 to 16, the
Link opens external targets with target="_blank" but omits rel="noopener
noreferrer"; update the Link props so that when props.isExternal is true you
also add rel="noopener noreferrer" (keep rel undefined or omit when internal) to
prevent reverse-tabnabbing and preserve existing behavior.

Comment on lines +206 to 215
<div className="flex gap-2 py-1.5 px-3" ref={triggerRef}>
{icon && <SidebarIcon icon={icon} />}
{name}
</div>
</div>
);

const triggerEl = href ? (
<Link
className={cn("w-full py-1.5 px-3 text-left font-medium")}
href={href}
>
<Link className={cn("w-full py-1.5 px-3 text-left")} href={href}>
{triggerElContent}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove duplicate padding on grouped links

When a category has an href, the outer <Link> adds py-1.5 px-3 and the inner wrapper does the same, resulting in doubled vertical and horizontal padding compared to non-linked headers. This leaves the title visibly misaligned with adjacent entries. Please keep the padding in a single place—dropping it from the <Link> is enough:

-    <Link className={cn("w-full py-1.5 px-3 text-left")} href={href}>
+    <Link className={cn("w-full text-left")} href={href}>
🤖 Prompt for AI Agents
In apps/portal/src/components/others/Sidebar.tsx around lines 206 to 215, the
Link wrapper and the inner div both apply "py-1.5 px-3", causing doubled padding
on linked category headers; remove the padding classes from the Link (keep
"w-full" and "text-left" or similar) and leave the padding on the inner wrapper
(the element with ref={triggerRef}) so spacing matches non-linked entries and
alignment is preserved.

Comment on lines +116 to +118
if (nodes.length === 0) {
return null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Clear TOC nodes when no headings so the sidebar truly disappears.

With the new early-return guard, navigating from a page that has headings to one that doesn’t (e.g. doc ➜ changelog) leaves the previous nodes array populated because the effect bails out before setNodes(...). The component therefore renders the (now hidden) sidebar, which still reserves the third grid column on XL screens and prevents the main content from expanding—failing the “remove On this page section” objective on client transitions.

Set nodes to an empty array before returning so the guard can unmount the <nav> entirely.

-    if (anchors.length === 0) {
-      setHideNav(true);
-      return;
-    }
+    if (anchors.length === 0) {
+      setHideNav(true);
+      setNodes([]);
+      return;
+    }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/portal/src/components/others/TableOfContents.tsx around lines 116 to
118, the early return when nodes.length === 0 leaves the prior nodes state
populated during client-side navigation; before returning null call setNodes([])
to clear the state so the nav unmounts and the layout column is freed—update the
guard to invoke setNodes([]) then return null.

Comment on lines +31 to 36
"mb-1 flex items-center whitespace-nowrap px-3 h-10 text-sm font-medium rounded-lg relative",
"border-transparent border-b text-muted-foreground ring-offset-700 transition-all",
"hover:text-foreground hover:bg-accent data-[state=active]:text-foreground",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
className,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restore the active tab underline

Line 35 defines a ::before underline, but without before:content-[''] (and ideally before:block) the pseudo-element never renders, so the active tab loses all visual affordance—especially now that the bottom border is transparent. Please add the missing content so the indicator shows up again.

-      "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
+      "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:content-[''] before:block before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"mb-1 flex items-center whitespace-nowrap px-3 h-10 text-sm font-medium rounded-lg relative",
"border-transparent border-b text-muted-foreground ring-offset-700 transition-all",
"hover:text-foreground hover:bg-accent data-[state=active]:text-foreground",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
className,
"mb-1 flex items-center whitespace-nowrap px-3 h-10 text-sm font-medium rounded-lg relative",
"border-transparent border-b text-muted-foreground ring-offset-700 transition-all",
"hover:text-foreground hover:bg-accent data-[state=active]:text-foreground",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:content-[''] before:block before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
className,
🤖 Prompt for AI Agents
In apps/portal/src/components/ui/tabs.tsx around lines 31 to 36 the tab styles
define a ::before underline but don’t set its content or display, so the
pseudo-element never renders; update the class list to include a
before:content-[''] (and preferably before:block) so the ::before pseudo-element
is created and visible for the active tab underline, ensuring the indicator
appears as intended.

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on UI improvements and code refactoring across various components in the application, enhancing styling consistency, accessibility, and overall user experience.

### Detailed summary
- Updated grid spacing in `Grid.tsx`.
- Increased max-width in `layout.tsx`.
- Modified border styles in multiple components.
- Enhanced button styles and variants in `chat-button.tsx` and `Subscribe.tsx`.
- Improved text styles for better readability.
- Refactored `AuthMethodsTabs.tsx` to use `Button` component.
- Adjusted `DocLayout.tsx` for more responsive design.
- Improved date formatting in `RenderData.tsx`.
- Added animations to `TableOfContents.tsx`.
- Updated feedback dialog in `Feedback.tsx` for better UX.
- General styling updates for consistency across components.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- Style
  - Widespread visual refinements: typography, spacing, tighter headings, dashed borders for dividers/images/code, smaller author avatar, absolute dates, wider content container, updated buttons (ghost/outline), adjusted icons and shadows, updated link/inline-code/grid/card styles, tabs and header/menu visual updates.
  - Footer, sidebar, docs search, subscribe, feedback, and table-of-contents presentational tweaks (including fade-in and conditional hiding).

- Refactor
  - Simplified changelog and post layout to a single-column header-first structure; removed changelog index TOC.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@vercel vercel bot temporarily deployed to Preview – wallet-ui September 25, 2025 08:00 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula September 25, 2025 08:00 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (3)
apps/portal/src/components/others/Subscribe.tsx (1)

41-58: Avoid fixed-width input to prevent mobile overflow

Locking the email field to w-64 forces the flex row to exceed narrow viewports (e.g., 320 px), so the button/input pair now overflows and introduces horizontal scrolling. Keep the input fluid on small screens and only clamp the width at larger breakpoints.

-        <Input
-          className="rounded-r-none border-r-0 w-64"
+        <Input
+          className="w-full rounded-r-none border-r-0 md:w-64"
apps/portal/src/components/others/Feedback.tsx (1)

47-63: Wire accessible names to the textarea

The new dialog text/description doesn’t associate the textarea with an accessible name. Screen readers announce an unlabeled field, which is an accessibility blocker. Tie the textarea to the dialog copy (or add a dedicated <label>), e.g.:

-              <DialogHeader className="mb-5">
-                <DialogTitle>Apologies for any confusion.</DialogTitle>
-                <DialogDescription>
+              <DialogHeader className="mb-5">
+                <DialogTitle id="feedback-dialog-title">
+                  Apologies for any confusion.
+                </DialogTitle>
+                <DialogDescription id="feedback-dialog-description">
                   Please provide details about the issue you encountered to help
                   us improve our documentation.
                 </DialogDescription>
               </DialogHeader>

-              <Textarea
-                className="mb-2 h-32 w-full bg-card"
+              <Textarea
+                aria-labelledby="feedback-dialog-title"
+                aria-describedby="feedback-dialog-description"
+                className="mb-2 h-32 w-full bg-card"
apps/portal/src/app/Header.tsx (1)

235-241: Add rel="noopener noreferrer" when using target="_blank".

Prevents reverse‑tabnabbing; also prefer undefined over empty string when not external.

Apply these diffs:

           <Link
             className="text-foreground"
             href="https://github.com/thirdweb-dev"
             target="_blank"
+            rel="noopener noreferrer"
           >
                     <Link
-                      className="before:absolute before:inset-0"
+                      className="before:absolute before:inset-0"
                       href={info.href}
                       prefetch={false}
-                      target={info.href.startsWith("http") ? "_blank" : ""}
+                      target={info.href.startsWith("http") ? "_blank" : undefined}
+                      rel={info.href.startsWith("http") ? "noopener noreferrer" : undefined}
                     >
       href={props.href}
       onClick={props.onClick}
-      target={props.href.startsWith("http") ? "_blank" : ""}
+      target={props.href.startsWith("http") ? "_blank" : undefined}
+      rel={props.href.startsWith("http") ? "noopener noreferrer" : undefined}
     >

Also applies to: 469-476, 532-535

🧹 Nitpick comments (3)
apps/portal/src/app/Header.tsx (3)

459-477: Make the DropdownMenuItem’s child the actual Link for better a11y (no nested interactive elements).

Remove the extra div/overlay and pass Link asChild.

Apply this diff:

-                <DropdownMenuItem asChild key={info.name}>
-                  <div
-                    className={clsx(
-                      "relative flex cursor-pointer gap-3 font-medium text-foreground !rounded-lg px-3 py-2",
-                      "hover:bg-accent",
-                    )}
-                  >
-                    {info.icon && (
-                      <info.icon className="size-5 text-muted-foreground" />
-                    )}
-                    <Link
-                      className="before:absolute before:inset-0"
-                      href={info.href}
-                      prefetch={false}
-                      target={info.href.startsWith("http") ? "_blank" : ""}
-                    >
-                      {info.name}
-                    </Link>
-                  </div>
-                </DropdownMenuItem>
+                <DropdownMenuItem asChild key={info.name}>
+                  <Link
+                    className={clsx(
+                      "relative flex gap-3 font-medium text-foreground !rounded-lg px-3 py-2 hover:bg-accent",
+                    )}
+                    href={info.href}
+                    prefetch={false}
+                    target={info.href.startsWith("http") ? "_blank" : undefined}
+                    rel={info.href.startsWith("http") ? "noopener noreferrer" : undefined}
+                  >
+                    {info.icon && (
+                      <info.icon className="size-5 text-muted-foreground" />
+                    )}
+                    {info.name}
+                  </Link>
+                </DropdownMenuItem>

260-266: Add accessibility attributes to the burger button and label the mobile menu.

Expose state via aria-expanded and connect with aria-controls; label the target container.

Apply these diffs:

             <Button
               className="p-2"
-              onClick={() => setShowBurgerMenu(!showBurgerMenu)}
+              onClick={() => setShowBurgerMenu((v) => !v)}
               variant="ghost"
+              aria-expanded={showBurgerMenu}
+              aria-controls="mobile-nav"
             >
-        <div className="fixed inset-0 top-sticky-top-height z-50 overflow-auto bg-card p-6 xl:hidden">
+        <div id="mobile-nav" className="fixed inset-0 top-sticky-top-height z-50 overflow-auto bg-card p-6 xl:hidden">

Also applies to: 342-343


211-215: Add explicit return types to exported components.

Matches TS guidelines and improves API clarity.

Apply these diffs:

-export function Header() {
+export function Header(): JSX.Element {
-function DropdownLinks(props: {
+function DropdownLinks(props: {
   onLinkClick?: () => void;
   category: string;
   links: readonly {
     name: string;
     href: string;
     icon?: React.FC<{ className?: string }>;
   }[];
-}) {
+}): JSX.Element {
-function NavLink(props: {
+function NavLink(props: {
   href: string;
   name: string;
   onClick?: () => void;
   icon?: React.FC<{ className?: string }>;
   className?: string;
-}) {
+}): JSX.Element {

Also applies to: 429-437, 514-520

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e0df84a and 7bc513c.

📒 Files selected for processing (28)
  • apps/portal/src/app/Header.tsx (7 hunks)
  • apps/portal/src/app/changelog/[slug]/layout.tsx (1 hunks)
  • apps/portal/src/app/changelog/[slug]/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/components/Author.tsx (1 hunks)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx (0 hunks)
  • apps/portal/src/app/changelog/components/RenderData.tsx (1 hunks)
  • apps/portal/src/app/changelog/page.tsx (2 hunks)
  • apps/portal/src/app/changelog/utils/transform.tsx (3 hunks)
  • apps/portal/src/app/transactions/page.mdx (2 hunks)
  • apps/portal/src/app/transactions/sponsor/page.mdx (1 hunks)
  • apps/portal/src/components/AI/chat-button.tsx (1 hunks)
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx (2 hunks)
  • apps/portal/src/components/Document/Code.tsx (1 hunks)
  • apps/portal/src/components/Document/DocImage.tsx (1 hunks)
  • apps/portal/src/components/Document/DocLink.tsx (1 hunks)
  • apps/portal/src/components/Document/Grid.tsx (1 hunks)
  • apps/portal/src/components/Document/Heading.tsx (3 hunks)
  • apps/portal/src/components/Document/InlineCode.tsx (1 hunks)
  • apps/portal/src/components/Document/PageFooter.tsx (3 hunks)
  • apps/portal/src/components/Document/SDKCard.tsx (1 hunks)
  • apps/portal/src/components/Layouts/DocLayout.tsx (2 hunks)
  • apps/portal/src/components/others/DocSearch.tsx (1 hunks)
  • apps/portal/src/components/others/Feedback.tsx (3 hunks)
  • apps/portal/src/components/others/Sidebar.tsx (7 hunks)
  • apps/portal/src/components/others/Subscribe.tsx (2 hunks)
  • apps/portal/src/components/others/TableOfContents.tsx (1 hunks)
  • apps/portal/src/components/ui/tabs.tsx (2 hunks)
  • packages/ui/src/components/code/CodeBlockContainer.tsx (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/portal/src/app/changelog/components/ChangeLogIndexTOC.tsx
🚧 Files skipped from review as they are similar to previous changes (20)
  • apps/portal/src/app/changelog/utils/transform.tsx
  • apps/portal/src/app/changelog/[slug]/layout.tsx
  • apps/portal/src/app/transactions/sponsor/page.mdx
  • apps/portal/src/components/others/DocSearch.tsx
  • apps/portal/src/components/Document/Grid.tsx
  • apps/portal/src/components/Document/Heading.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/app/changelog/page.tsx
  • apps/portal/src/components/AI/chat-button.tsx
  • apps/portal/src/components/others/Sidebar.tsx
  • apps/portal/src/app/changelog/components/Author.tsx
  • apps/portal/src/components/Layouts/DocLayout.tsx
  • apps/portal/src/components/Document/Code.tsx
  • apps/portal/src/components/others/TableOfContents.tsx
  • apps/portal/src/app/changelog/components/RenderData.tsx
  • apps/portal/src/components/Document/SDKCard.tsx
  • apps/portal/src/components/Document/InlineCode.tsx
  • apps/portal/src/app/changelog/[slug]/page.tsx
  • apps/portal/src/app/transactions/page.mdx
  • apps/portal/src/components/Document/DocImage.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 @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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 @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless 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/components/ui/tabs.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Feedback.tsx
  • apps/portal/src/components/Document/PageFooter.tsx
  • apps/portal/src/components/Document/DocLink.tsx
  • apps/portal/src/components/others/Subscribe.tsx
  • packages/ui/src/components/code/CodeBlockContainer.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/components/ui/tabs.tsx
  • apps/portal/src/app/Header.tsx
  • apps/portal/src/components/others/Feedback.tsx
  • apps/portal/src/components/Document/PageFooter.tsx
  • apps/portal/src/components/Document/DocLink.tsx
  • apps/portal/src/components/others/Subscribe.tsx
  • packages/ui/src/components/code/CodeBlockContainer.tsx
🧠 Learnings (7)
📚 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} : Import UI primitives from `@/components/ui/_` (e.g., Button, Input, Tabs, Card)

Applied to files:

  • apps/portal/src/components/ui/tabs.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • apps/portal/src/components/ui/tabs.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} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.

Applied to files:

  • apps/portal/src/components/ui/tabs.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 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/components/ui/tabs.tsx
  • 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-08-29T23:44:47.512Z
Learnt from: MananTank
PR: thirdweb-dev/js#7951
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx:38-38
Timestamp: 2025-08-29T23:44:47.512Z
Learning: The ContractPageLayout component in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_layout/contract-page-layout.tsx is not the root layout - it's nested within the dashboard layout which already handles footer positioning with min-h-dvh and AppFooter placement. The ContractPageLayout needs flex flex-col grow to properly participate in the parent's flex layout.

Applied to files:

  • apps/portal/src/components/Document/PageFooter.tsx
🧬 Code graph analysis (2)
apps/portal/src/components/others/Feedback.tsx (3)
packages/nebula/src/client/sdk.gen.ts (1)
  • feedback (377-398)
apps/playground-web/src/components/ui/dialog.tsx (5)
  • DialogTrigger (116-116)
  • DialogContent (117-117)
  • DialogHeader (118-118)
  • DialogTitle (120-120)
  • DialogDescription (121-121)
apps/portal/src/components/ui/textarea.tsx (1)
  • Textarea (24-24)
apps/portal/src/components/Document/PageFooter.tsx (3)
apps/portal/src/components/Document/AutoNextPageButton.tsx (1)
  • AutoNextPageButton (8-27)
apps/portal/src/components/others/Feedback.tsx (1)
  • Feedback (17-89)
apps/portal/src/components/Document/DocLink.tsx (1)
  • DocLink (4-27)
⏰ 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). (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (6)
packages/ui/src/components/code/CodeBlockContainer.tsx (1)

34-34: Consistent ScrollShadow palette

Aligning the fallback to hsl(var(--card)) keeps the code block shadow in step with the rest of the updated portal styling. Looks good.

apps/portal/src/components/ui/tabs.tsx (1)

31-36: Restore the active tab underline indicator

The ::before underline still never renders because we don’t create the pseudo-element. Add both before:content-[''] and before:block so the active-state indicator comes back.

-      "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
+      "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:content-[''] before:block before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
apps/portal/src/components/Document/DocLink.tsx (1)

13-15: Bring back the underline so the dotted decoration actually shows up

Tailwind’s preflight resets link text-decoration, so dropping the underline utility means the dotted style never renders and the links lose their visual affordance. Please restore the underline while keeping the new colour palette.

-        "text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 decoration-dotted transition-colors ",
+        "text-blue-600 hover:text-blue-700 dark:text-blue-500 dark:hover:text-blue-400 underline decoration-dotted transition-colors",
apps/portal/src/app/Header.tsx (3)

287-292: Nice: NavLink-level className enables per-item styling without forking the component.

This simplifies styling overrides and keeps the API small.


445-456: Dropdown trigger styling and spacing changes look good.

Clearer hit target and consistent text sizing.


163-194: Validate React/React Native sdkLinks hrefs
React and React Native entries currently point to /references/typescript/v5 and no /app/references/react or /app/references/react-native routes exist—confirm intended paths or add/update pages. (apps/portal/src/app/Header.tsx:163-194)

Comment on lines 292 to 294
{pathname?.startsWith(link.href) && (
<div className="bg-violet-700 h-[2px] inset-x-0 rounded-full absolute -bottom-1" />
<div className="bg-foreground h-[2px] inset-x-0 rounded-full absolute -bottom-1.5" />
)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix active-state matching to avoid false positives (e.g., "/reference" vs "/references").

Current startsWith checks will incorrectly mark parent routes active. Use exact or segment-aware matching.

Apply these diffs:

-                  {pathname?.startsWith(link.href) && (
+                  {(pathname === link.href || pathname?.startsWith(`${link.href}/`)) && (
                     <div className="bg-foreground h-[2px] inset-x-0 rounded-full absolute -bottom-1.5" />
                   )}
-        pathname?.startsWith(props.href)
-          ? "text-foreground"
-          : "text-muted-foreground",
+        pathname === props.href || pathname?.startsWith(`${props.href}/`)
+          ? "text-foreground"
+          : "text-muted-foreground",

Also applies to: 525-531

🤖 Prompt for AI Agents
In apps/portal/src/app/Header.tsx around lines 292-294 (and similarly lines
525-531), the current active-state uses pathname?.startsWith(link.href) which
creates false positives like "/reference" matching "/references"; change the
condition to a segment-aware check such as normalizing trailing slashes and
using (pathname === link.href || pathname.startsWith(link.href + '/')) so the
link is only active for exact match or deeper nested routes, and apply the same
change to the other occurrence.

Comment on lines +20 to +24
<div className="flex gap-4 justify-end items-center py-6">
{props.sidebarLinks && (
<AutoNextPageButton sidebarLinks={props.sidebarLinks} />
)}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid rendering an empty spacer when there’s no sidebar

With the current structure, pages that don’t pass sidebarLinks still render a full-height row with py-6, leaving a conspicuous blank band above the rest of the footer. Gate the entire row on sidebarLinks so we only reserve space when a next-page button can actually render.

-      <div className="flex gap-4 justify-end items-center py-6">
-        {props.sidebarLinks && (
-          <AutoNextPageButton sidebarLinks={props.sidebarLinks} />
-        )}
-      </div>
+      {props.sidebarLinks ? (
+        <div className="flex gap-4 justify-end items-center py-6">
+          <AutoNextPageButton sidebarLinks={props.sidebarLinks} />
+        </div>
+      ) : null}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className="flex gap-4 justify-end items-center py-6">
{props.sidebarLinks && (
<AutoNextPageButton sidebarLinks={props.sidebarLinks} />
)}
</div>
{props.sidebarLinks ? (
<div className="flex gap-4 justify-end items-center py-6">
<AutoNextPageButton sidebarLinks={props.sidebarLinks} />
</div>
) : null}
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/PageFooter.tsx around lines 20 to 24, the
outer div with padding (py-6) is always rendered even when props.sidebarLinks is
falsy, producing an unwanted blank spacer; change the JSX so the entire row is
conditionally rendered only when props.sidebarLinks is present (i.e., move the
{props.sidebarLinks && ...} check to wrap the div itself) so the padding and
layout are omitted when there are no sidebar links.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages Portal Involves changes to the Portal (docs) codebase.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants