Skip to content

chore: Proxy content - #122

Merged
perkinsjr merged 8 commits into
mainfrom
proxy-content
Apr 10, 2026
Merged

perkinsjr merged 8 commits into
mainfrom
proxy-content

Conversation

@perkinsjr

@perkinsjr perkinsjr commented Apr 10, 2026 •

Copy link
Copy Markdown
Member

What does this PR do?

Fixes # (issue)

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Blog post
  • Changelog
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR

Summary by CodeRabbit

  • New Features

    • GitHub-backed product changelog ingestion (remote entries now appear alongside local entries).
    • New styled callout variants (Note, Info, Tip, Check, Warning, Danger) for richer changelog content.
    • Expanded MDX component set and wrappers enabling cards, tabs, steps, columns, and mermaid/embedded content.
    • New revalidation API to refresh the changelog listing.
  • Improvements

    • Changelog aggregation merges local and GitHub entries with unified date sorting.
    • Changelog rendering updated for more flexible MDX-driven content and consistent link/frame handling.

@vercel

vercel Bot commented Apr 10, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
ratelimit Ready Ready Preview, Comment Apr 10, 2026 4:18pm
www Ready Ready Preview, Comment Apr 10, 2026 4:18pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
play Skipped Skipped Apr 10, 2026 4:18pm

Request Review

@perkinsjr
perkinsjr requested a review from MichaelUnkey as a code owner April 10, 2026 14:01
@vercel
vercel Bot temporarily deployed to Preview – play April 10, 2026 14:01 Inactive
@coderabbitai

coderabbitai Bot commented Apr 10, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Added GitHub-backed changelog ingestion, merged GitHub entries with local collection entries, refactored changelog rendering to support both local MDX and GitHub-sourced MDXRemote, introduced callout variants and Mintlify MDX support, and moved MDX component mappings into dedicated modules.

Changes

Cohort / File(s) Summary
Changelog GitHub Integration
apps/www/app/changelog/page.tsx, apps/www/content-collections.ts
Added fetchProductChangelogs() and parseFrontmatter() to list and fetch .mdx from GitHub, create _kind: "github" entries, and merge them with local _kind: "collection" entries; combined list is sorted by date. Adjusted TOC header extraction and changelog.tags default.
Changelog UI & Rendering
apps/www/components/changelog/changelog-grid-item.tsx, apps/www/components/changelog/changelog-mdx-components.tsx, apps/www/components/changelog/callouts.tsx, apps/www/components/changelog/mintlify-wrappers.tsx
Added typed Callout variants and convenience components (Note, Info, Tip, Check, Warning, Danger); refactored ChangelogGridItem to accept ChangelogMeta and children (sync component) and render either local MDX or GitHub MDXRemote; introduced changelogMdxComponents and Mintlify re-exports.
MDX Component Infrastructure
apps/www/components/mdx-components.tsx, apps/www/components/mdx-content.tsx
Extracted MDX mappings into mdx-components.tsx exporting MdxComponents; updated mdx-content.tsx to re-export/import MdxComponents and merge with Mermaid.
Configuration & Dependencies
apps/www/next.config.js, apps/www/package.json
Added dependency @mintlify/components@^1.0.14 and configured Next.js transpilePackages: ["@mintlify/components"].
API: Revalidation Route
apps/www/app/api/revalidate/route.ts
Added POST route that validates Bearer token against process.env.REVALIDATION_TOKEN and calls revalidatePath("/changelog") on success, returning JSON responses for authorized/unauthorized requests.
Type & Form Typing Updates
apps/www/components/frame.tsx, apps/www/app/templates/client.tsx
Used type-only ReactNode import in Frame props; cast zodResolver(schema) to Resolver<TemplatesFormValues> in TemplatesClient form setup.

Sequence Diagram(s)

sequenceDiagram
    participant Page as Changelog Page
    participant GitHub as GitHub API
    participant Local as Local Collection Loader
    participant Parser as Frontmatter Parser
    participant Aggregator as Aggregator/Sorter
    participant Renderer as Page Renderer
    participant MDXRender as MDX / MDXRemote
    participant UI as UI Components

    Page->>GitHub: list repo contents & fetch raw .mdx
    GitHub-->>Parser: return raw file contents
    Parser->>Aggregator: emit parsed entries (_kind: "github")
    Page->>Local: load local collection entries (_kind: "collection")
    Local-->>Aggregator: provide local entries
    Aggregator->>Aggregator: concat & sort entries by date
    Aggregator->>Renderer: provide ordered entries
    Renderer->>MDXRender: render entry
    alt entry._kind == "collection"
        MDXRender->>UI: render local MDX with components
    else entry._kind == "github"
        MDXRender->>UI: render via MDXRemote with changelogMdxComponents
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 From burrows of code I fetched a stream,
GitHub threads and local notes now team,
Callouts blossom, Mintlify joins the show,
MDX maps tidy, changelogs come and go,
A hopping rabbit stamps: "Deploy—let's gleam!"

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description uses only template placeholder text with no issue number, concrete testing instructions, or implementation details provided. Fill in the description with: issue number, summary of changes (GitHub changelog ingestion, new callout/MDX components, revalidation endpoint), type of change selection, actual test steps, and confirmation of checklist items completed.
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is vague and does not clearly convey the main changes in the changeset. Replace with a more specific title that describes the key change, such as 'feat: Add GitHub-backed changelog ingestion with on-demand revalidation' or 'chore: Integrate GitHub changelog sources with callout components'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

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

⚠️ Outside diff range comments (1)
apps/www/app/globals.css (1)

1-1005: ⚠️ Potential issue | 🟡 Minor

File exceeds 300-line guideline.

This file is 1005 lines, significantly exceeding the 300-line limit specified in the coding guidelines. Consider splitting this global stylesheet into smaller, more focused modules (e.g., separate files for gradients, animations, color variables, and utility classes) to improve maintainability.

As per coding guidelines: Enforce 300-line file limit where applicable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/globals.css` around lines 1 - 1005, The globals.css file is over
the 300-line limit; split it into focused modules by extracting related blocks
(e.g., gradient rules like .bg-yt-button-gradient,
.section-title-heading-gradient, .analytics-background-gradient and their
::before/::after rules into a gradients.css; animations and keyframes like
`@keyframes` slideGradient, stroke, fill, flickerAnimation plus .flicker,
.checkmark, .checkmark__circle into animations.css; utility/layout classes like
.feature-grid, .grid__item, .no-scrollbar, .scrollbar-hidden into utilities.css;
and the color tokens under `@layer` base :root and .dark into variables.css),
update imports to include these new CSS modules where globals.css was
referenced, and ensure unique selectors such as .hero-hiring-gradient,
.analytics-dashboard-gradient, and :root remain unchanged when moved so
selectors and pseudo-elements keep exact names and behavior.
🧹 Nitpick comments (5)
apps/www/app/globals.css (1)

6-10: Gradient reformatting improves readability but appears unrelated to PR objectives.

The multi-line gradient formatting makes color stops and positions easier to read and maintain. However, these formatting changes don't appear connected to the PR's stated purpose of "Proxy content" and changelog integration mentioned in the AI summary.

Consider moving purely cosmetic refactors to separate PRs to keep changes focused and reviewable.

Also applies to: 15-19, 26-30, 35-49, 55-59, 66-73, 77-82, 86-90, 102-106, 137-142, 149-154, 161-167, 205-207, 216-220, 239-243, 264-270, 279-283, 302-304, 330-337, 398-402, 421-427, 433-437, 441-445, 458-462, 470-474

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/globals.css` around lines 6 - 10, This PR includes purely
cosmetic reformatting of CSS gradient declarations (instances of the property
"background: linear-gradient(" in apps/www/app/globals.css) that are unrelated
to the "Proxy content" and changelog work; either revert those gradient
formatting changes in this PR (restore the prior single-line gradient
declarations) or move only the reformatting into a separate cleanup PR/branch so
this PR contains only behavioral/content changes. Locate every occurrence of
"background: linear-gradient(" in globals.css and remove the multiline
reformatting from this branch, committing either the reverted lines here or
creating a separate PR with the cosmetic edits.
apps/www/app/templates/client.tsx (1)

40-46: This file is already past the repo’s 300-line limit.

Since this change touches TemplatesClient, please split the filter sidebar or the template grid into smaller components instead of growing the 428-line component further. As per coding guidelines, **/*: Enforce 300-line file limit where applicable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/templates/client.tsx` around lines 40 - 46, The TemplatesClient
component has grown too large (over the 300-line file limit); split its internal
UI into at least two child components — for example extract the filter sidebar
into a new FilterSidebar component and the template listing/grid into a
TemplateGrid component — move related state handlers and prop types from
TemplatesClient into those components' props (or lift minimal shared state up to
TemplatesClient), update imports/exports and replace the large JSX blocks inside
TemplatesClient with <FilterSidebar .../> and <TemplateGrid .../> usages, and
ensure any hooks used there (e.g., useForm, schema,
getDefaulTemplatesFormValues) remain properly referenced or passed down as props
to preserve behavior.
apps/www/app/changelog/page.tsx (2)

59-69: Parallel fetching is efficient; consider handling partial failures.

Using Promise.all is efficient for fetching multiple files in parallel. Note that if any single file fetch fails, the entire operation returns an empty array. If partial results are desired, consider using Promise.allSettled instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/changelog/page.tsx` around lines 59 - 69, The current
Promise.all over mdxFiles inside the page data loader will abort all work if any
fetch fails; change it to Promise.allSettled so each file's fetch and processing
(the mdxFiles.map async callback that fetches file.download_url, reads source,
slices date, and calls parseFrontmatter) runs independently, then collect only
the settled results with status "fulfilled" into the returned array (preserving
slug/date/title/description/tags/source), log or capture any entries with status
"rejected" for debugging, and ensure the final return filters out failed entries
instead of failing the whole operation.

70-72: Consider logging errors for observability.

The catch block silently discards all errors, making it difficult to diagnose issues like rate limiting, authentication failures, or network problems. While graceful degradation is appropriate, adding a console.error would aid debugging without affecting user experience.

💡 Proposed improvement
-  } catch {
+  } catch (err) {
+    console.error("Failed to fetch product changelogs:", err);
     return [];
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/changelog/page.tsx` around lines 70 - 72, The catch block that
currently swallows errors and returns [] should log the error for observability;
update the catch in the changelog data loader (the async function that fetches
changelog entries / the catch that returns []) to call console.error (or the app
logger) with a descriptive message and the caught error before returning the
empty array so failures like auth, rate-limit, or network issues are visible in
logs.
apps/www/components/changelog/changelog-mdx-components.tsx (1)

68-70: Consider documenting or type-checking the Mintlify component pattern.

Lines 68–70 rely on as any to extract .Item subcomponents from Tabs and Steps, which depends on undocumented Mintlify internals. While the inline comment explains the intent, this pattern is fragile and could break with Mintlify updates. Consider adding TypeScript types or documenting the expected Mintlify structure if this pattern is critical to your MDX setup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/components/changelog/changelog-mdx-components.tsx` around lines 68 -
70, Replace the unsafe "as any" casts by defining a small Mintlify container
type and using it to type-check Tabs and Steps, e.g., create an interface like
MintlifyContainer { Item: React.ComponentType<any> } and assert Tabs and Steps
to that type when extracting Tab and Step; also add a short runtime guard that
warns or throws if .Item is missing (to fail fast on Mintlify changes) and
include a brief code comment explaining the expected Mintlify structure for
future maintainers; update the assignments where Tab = (Tabs as any).Item and
Step = (Steps as any).Item to use the new typed assertion and guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/app/changelog/page.tsx`:
- Around line 43-47: The lint error is caused by the single-line early return
after the fetch response check; update the response guard in the async code that
fetches the changelog (the const res = await fetch(...) block that uses
GITHUB_REPO and CHANGELOG_PATH) to use a block statement: replace "if (!res.ok)
return [];" with a braced if that returns the empty array inside { ... } so the
early return is enclosed in a block.
- Around line 16-34: The early return in parseFrontmatter currently uses a
single-line return without a block; change the if (!match) return { title: "",
tags: ["product"] }; to use a block statement: if (!match) { return { title: "",
tags: ["product"] }; } so the lint rule is satisfied while leaving
parseFrontmatter, get, and tags logic unchanged.

In `@apps/www/app/templates/client.tsx`:
- Around line 42-43: Remove the `as any` cast on the resolver and give it the
correct resolver type: change the `resolver` usage so it is typed as
`Resolver<TemplatesFormValues>` (import `Resolver` from react-hook-form) and
assign `zodResolver(schema)` to that typed variable or annotate inline; ensure
`TemplatesFormValues` is the same `z.infer<typeof schema>` used with
`useForm<TemplatesFormValues>` so the types line up without `any`.

In `@apps/www/components/changelog/changelog-grid-item.tsx`:
- Around line 9-20: The component's ChangelogMeta type marks description as
optional/nullable but the JSX always renders the paragraph, causing empty
spacing for null descriptions; update the component (the function that uses
Props and the changelog prop) to conditionally render the <p> that displays
changelog.description only when changelog.description is non-null/non-empty
(e.g., guard with a truthy check around changelog.description) so the my-8
spacer is only output when there's actual content.

In `@apps/www/components/changelog/changelog-mdx-components.tsx`:
- Around line 37-51: Replace the truthy check with optional chaining and
simplify the props type import: change the conditional to use
href?.startsWith("/") when computing resolvedHref, and ensure you import the
type directly (import type { AnchorHTMLAttributes } from 'react') and keep the
function signature as ChangelogAnchor({ href, ...props }:
AnchorHTMLAttributes<HTMLAnchorElement>) (or destructure into { href, ...rest }
and use rest for spreading) so linting passes.

In `@apps/www/components/mdx-components.tsx`:
- Around line 28-30: The custom MDX image renderer currently discards incoming
attributes and forces alt to the src; update the img entry (the renderer
function for img) to spread and preserve all incoming props and use the original
alt when provided (e.g., render <img {...props} alt={props.alt ?? props.src} />)
so author-specified sizing/classes and descriptive alt text are preserved while
still falling back to src if alt is missing.
- Around line 41-46: The MDX link component (the "a" renderer in
mdx-components.tsx) sets a hardcoded aria-label="Link", which overrides the
accessible name; remove that fixed attribute so the anchor's visible children
become the accessible name (or alternatively only set aria-label when one is
explicitly passed in props, e.g., use props['aria-label'] if present). Update
the a component to stop injecting aria-label="Link" and rely on passed
props/children for accessibility.

---

Outside diff comments:
In `@apps/www/app/globals.css`:
- Around line 1-1005: The globals.css file is over the 300-line limit; split it
into focused modules by extracting related blocks (e.g., gradient rules like
.bg-yt-button-gradient, .section-title-heading-gradient,
.analytics-background-gradient and their ::before/::after rules into a
gradients.css; animations and keyframes like `@keyframes` slideGradient, stroke,
fill, flickerAnimation plus .flicker, .checkmark, .checkmark__circle into
animations.css; utility/layout classes like .feature-grid, .grid__item,
.no-scrollbar, .scrollbar-hidden into utilities.css; and the color tokens under
`@layer` base :root and .dark into variables.css), update imports to include these
new CSS modules where globals.css was referenced, and ensure unique selectors
such as .hero-hiring-gradient, .analytics-dashboard-gradient, and :root remain
unchanged when moved so selectors and pseudo-elements keep exact names and
behavior.

---

Nitpick comments:
In `@apps/www/app/changelog/page.tsx`:
- Around line 59-69: The current Promise.all over mdxFiles inside the page data
loader will abort all work if any fetch fails; change it to Promise.allSettled
so each file's fetch and processing (the mdxFiles.map async callback that
fetches file.download_url, reads source, slices date, and calls
parseFrontmatter) runs independently, then collect only the settled results with
status "fulfilled" into the returned array (preserving
slug/date/title/description/tags/source), log or capture any entries with status
"rejected" for debugging, and ensure the final return filters out failed entries
instead of failing the whole operation.
- Around line 70-72: The catch block that currently swallows errors and returns
[] should log the error for observability; update the catch in the changelog
data loader (the async function that fetches changelog entries / the catch that
returns []) to call console.error (or the app logger) with a descriptive message
and the caught error before returning the empty array so failures like auth,
rate-limit, or network issues are visible in logs.

In `@apps/www/app/globals.css`:
- Around line 6-10: This PR includes purely cosmetic reformatting of CSS
gradient declarations (instances of the property "background: linear-gradient("
in apps/www/app/globals.css) that are unrelated to the "Proxy content" and
changelog work; either revert those gradient formatting changes in this PR
(restore the prior single-line gradient declarations) or move only the
reformatting into a separate cleanup PR/branch so this PR contains only
behavioral/content changes. Locate every occurrence of "background:
linear-gradient(" in globals.css and remove the multiline reformatting from this
branch, committing either the reverted lines here or creating a separate PR with
the cosmetic edits.

In `@apps/www/app/templates/client.tsx`:
- Around line 40-46: The TemplatesClient component has grown too large (over the
300-line file limit); split its internal UI into at least two child components —
for example extract the filter sidebar into a new FilterSidebar component and
the template listing/grid into a TemplateGrid component — move related state
handlers and prop types from TemplatesClient into those components' props (or
lift minimal shared state up to TemplatesClient), update imports/exports and
replace the large JSX blocks inside TemplatesClient with <FilterSidebar .../>
and <TemplateGrid .../> usages, and ensure any hooks used there (e.g., useForm,
schema, getDefaulTemplatesFormValues) remain properly referenced or passed down
as props to preserve behavior.

In `@apps/www/components/changelog/changelog-mdx-components.tsx`:
- Around line 68-70: Replace the unsafe "as any" casts by defining a small
Mintlify container type and using it to type-check Tabs and Steps, e.g., create
an interface like MintlifyContainer { Item: React.ComponentType<any> } and
assert Tabs and Steps to that type when extracting Tab and Step; also add a
short runtime guard that warns or throws if .Item is missing (to fail fast on
Mintlify changes) and include a brief code comment explaining the expected
Mintlify structure for future maintainers; update the assignments where Tab =
(Tabs as any).Item and Step = (Steps as any).Item to use the new typed assertion
and guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 652243f6-b9b1-4f59-9daf-d16a44714c58

📥 Commits

Reviewing files that changed from the base of the PR and between 412b791 and 28424d3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • apps/www/app/changelog/page.tsx
  • apps/www/app/globals.css
  • apps/www/app/templates/client.tsx
  • apps/www/components/changelog/callouts.tsx
  • apps/www/components/changelog/changelog-grid-item.tsx
  • apps/www/components/changelog/changelog-mdx-components.tsx
  • apps/www/components/changelog/mintlify-wrappers.tsx
  • apps/www/components/mdx-components.tsx
  • apps/www/components/mdx-content.tsx
  • apps/www/content-collections.ts
  • apps/www/next.config.js
  • apps/www/package.json

Comment thread apps/www/app/changelog/page.tsx Outdated
Comment thread apps/www/app/changelog/page.tsx Outdated
Comment thread apps/www/app/templates/client.tsx Outdated
Comment thread apps/www/components/changelog/changelog-grid-item.tsx
Comment thread apps/www/components/changelog/changelog-mdx-components.tsx Outdated
Comment thread apps/www/components/mdx-components.tsx
Comment thread apps/www/components/mdx-components.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
apps/www/app/changelog/page.tsx (2)

72-74: Silent error handling may obscure issues.

The catch block returns an empty array without logging. Consider adding logging to help diagnose fetch failures in production.

🔧 Proposed fix
-  } catch {
+  } catch (error) {
+    console.error("Failed to fetch product changelogs:", error);
     return [];
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/changelog/page.tsx` around lines 72 - 74, The catch block in
apps/www/app/changelog/page.tsx currently swallows errors by returning an empty
array; change it to capture the error (e.g., catch (err)) and log a descriptive
message with the error details before returning [], using the app's logger (or
console.error) so failures in the changelog fetch are visible; update the catch
around the changelog fetch function (the async function that returns the
changelog array) to include this logging and preserve the existing return
behavior.

63-65: Missing authentication headers for individual file fetches.

The initial directory listing uses the GITHUB_TOKEN but the subsequent file content fetches via download_url do not include the auth headers. For private repos or rate-limited scenarios, this could cause failures.

🔧 Proposed fix
+    const fileHeaders: HeadersInit = {};
+    if (process.env.GITHUB_TOKEN) {
+      fileHeaders.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
+    }
+
     return Promise.all(
       mdxFiles.map(async (file) => {
         const raw = await fetch(file.download_url, {
+          headers: fileHeaders,
           next: { revalidate: 86400 },
         });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/changelog/page.tsx` around lines 63 - 65, The individual file
fetch using fetch(file.download_url, { next: { revalidate: 86400 } }) omits the
GitHub auth header; update that call in apps/www/app/changelog/page.tsx to
include the same Authorization header (e.g., Authorization: `Bearer
${process.env.GITHUB_TOKEN}` or `token ${process.env.GITHUB_TOKEN}`) and any
other headers used for the initial directory listing, preserving the next: {
revalidate: 86400 } option so private repos and rate-limited requests succeed.
apps/www/components/changelog/callouts.tsx (1)

8-139: Consider extracting inline SVG icons to reduce verbosity.

The inline SVG definitions work correctly but add significant bulk to the file. For maintainability, consider extracting these icons to a separate file or using an icon library.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/components/changelog/callouts.tsx` around lines 8 - 139, The
variants object currently in callouts.tsx has large inline SVGs for keys info,
success, warning, and error which increases file verbosity; extract each SVG
into separate React components (e.g., InfoIcon, SuccessIcon, WarningIcon,
ErrorIcon) in a new icons file and export them, then replace the icon JSX in the
variants object with the imported component references (e.g., icon: <InfoIcon
/>) so callouts.tsx only references the icons and the SVG markup lives in a
dedicated module for maintainability and reuse.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/www/app/changelog/page.tsx`:
- Around line 72-74: The catch block in apps/www/app/changelog/page.tsx
currently swallows errors by returning an empty array; change it to capture the
error (e.g., catch (err)) and log a descriptive message with the error details
before returning [], using the app's logger (or console.error) so failures in
the changelog fetch are visible; update the catch around the changelog fetch
function (the async function that returns the changelog array) to include this
logging and preserve the existing return behavior.
- Around line 63-65: The individual file fetch using fetch(file.download_url, {
next: { revalidate: 86400 } }) omits the GitHub auth header; update that call in
apps/www/app/changelog/page.tsx to include the same Authorization header (e.g.,
Authorization: `Bearer ${process.env.GITHUB_TOKEN}` or `token
${process.env.GITHUB_TOKEN}`) and any other headers used for the initial
directory listing, preserving the next: { revalidate: 86400 } option so private
repos and rate-limited requests succeed.

In `@apps/www/components/changelog/callouts.tsx`:
- Around line 8-139: The variants object currently in callouts.tsx has large
inline SVGs for keys info, success, warning, and error which increases file
verbosity; extract each SVG into separate React components (e.g., InfoIcon,
SuccessIcon, WarningIcon, ErrorIcon) in a new icons file and export them, then
replace the icon JSX in the variants object with the imported component
references (e.g., icon: <InfoIcon />) so callouts.tsx only references the icons
and the SVG markup lives in a dedicated module for maintainability and reuse.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9db372b-76c9-4a72-9577-bc623e042638

📥 Commits

Reviewing files that changed from the base of the PR and between 8e56ba2 and b1dcae6.

📒 Files selected for processing (7)
  • apps/www/app/changelog/page.tsx
  • apps/www/app/templates/client.tsx
  • apps/www/components/changelog/callouts.tsx
  • apps/www/components/changelog/changelog-grid-item.tsx
  • apps/www/components/changelog/changelog-mdx-components.tsx
  • apps/www/components/mdx-components.tsx
  • apps/www/content-collections.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/www/app/templates/client.tsx
  • apps/www/components/changelog/changelog-mdx-components.tsx
  • apps/www/components/changelog/changelog-grid-item.tsx
  • apps/www/components/mdx-components.tsx
  • apps/www/content-collections.ts

@vercel
vercel Bot temporarily deployed to Preview – play April 10, 2026 15:25 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/www/app/changelog/page.tsx (1)

21-35: This frontmatter parser is too brittle for external MDX.

The regex path only handles LF line endings and simple single-line key: value pairs, so CRLF files, multiline descriptions, or YAML list tags will come through with incomplete metadata. Since this content is coming from another repo, I’d switch this to a real frontmatter parser (or a shared parser used by the render path) instead of regexes here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/www/app/changelog/page.tsx` around lines 21 - 35, The current
regex-based frontmatter extraction (the const match = source.match(...) block
and the get(key) helper that reads fm) is brittle for CRLF, multiline values,
and YAML lists; replace this manual parsing with a proper frontmatter/YAML
parser (e.g., gray-matter or the project's shared frontmatter parser) to parse
the frontmatter into an object, then read title, description, and tags from that
object (falling back to ["product"] when tags are missing), ensuring multiline
descriptions and YAML list tags are handled correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/app/changelog/page.tsx`:
- Around line 40-70: The code reuses the API request headers (headers) when
fetching file.download_url, leaking GITHUB_TOKEN to the raw file host and not
checking the raw response; fix by creating a separate headers object for the
raw-content fetch that omits Authorization (e.g., rawHeaders = { Accept:
"application/vnd.github.v3+json" } or simply {}) and use that in the fetch for
file.download_url inside the mdxFiles.map async callback, and immediately check
raw.ok after fetching (if (!raw.ok) throw or return null/skip) before calling
raw.text() and parseFrontmatter, ensuring you handle/propagate failed downloads
instead of treating error bodies as MDX.

---

Nitpick comments:
In `@apps/www/app/changelog/page.tsx`:
- Around line 21-35: The current regex-based frontmatter extraction (the const
match = source.match(...) block and the get(key) helper that reads fm) is
brittle for CRLF, multiline values, and YAML lists; replace this manual parsing
with a proper frontmatter/YAML parser (e.g., gray-matter or the project's shared
frontmatter parser) to parse the frontmatter into an object, then read title,
description, and tags from that object (falling back to ["product"] when tags
are missing), ensuring multiline descriptions and YAML list tags are handled
correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8aec27db-c1e6-444d-8ff1-d4a2f877c653

📥 Commits

Reviewing files that changed from the base of the PR and between b1dcae6 and b82a17c.

📒 Files selected for processing (1)
  • apps/www/app/changelog/page.tsx

Comment thread apps/www/app/changelog/page.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/www/app/api/revalidate/route.ts`:
- Around line 5-8: Ensure the endpoint fails closed by first verifying the
configured secret: if process.env.REVALIDATION_TOKEN is missing return a 500
NextResponse.json with an explanatory error, then require a non-empty bearer
token (the token variable) before comparison and return 401 if the Authorization
header is absent/empty; only then compare token ===
process.env.REVALIDATION_TOKEN and proceed on match. Use the existing token
variable and NextResponse.json for the error responses in route.ts.

In `@apps/www/app/changelog/page.tsx`:
- Around line 85-98: The sitemap currently uses only allChangelogs while the
page builds a merged feed (productEntries from fetchProductChangelogs plus
collectionEntries and githubEntries into changelogs), so extract the
feed-creation logic into a shared helper (e.g., createChangelogFeed or
getAllChangelogs) that composes collectionEntries and githubEntries from
allChangelogs and productEntries and sorts by date, then import and use that
helper both in apps/www/app/changelog/page.tsx (replace local merge into
changelogs) and in apps/www/app/sitemap.ts (replace usage of allChangelogs) so
GitHub-backed entries are included and lastModified is accurate.
- Around line 61-80: The current Promise.all over mdxFiles.map lets any fetch()
or parseFrontmatter() throw reject the whole batch; update the mapper so each
file is isolated: inside the mdxFiles.map async callback wrap the fetch,
raw.text(), replace, parseFrontmatter, and result construction in a try/catch
that logs the file-specific error (include file.name) and returns null for that
entry, or alternatively replace Promise.all(...) with Promise.allSettled(...)
and then only keep fulfilled results (mapping settled.value) while logging
rejected.reason per file; ensure you reference the existing mdxFiles.map, fetch,
parseFrontmatter, and the results.filter step so only the failing file is
skipped instead of rejecting the entire request.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 546d7dbc-2660-4314-9888-7017038e2d32

📥 Commits

Reviewing files that changed from the base of the PR and between b82a17c and 77c59d5.

📒 Files selected for processing (2)
  • apps/www/app/api/revalidate/route.ts
  • apps/www/app/changelog/page.tsx

Comment thread apps/www/app/api/revalidate/route.ts
Comment thread apps/www/app/changelog/page.tsx Outdated
Comment thread apps/www/app/changelog/page.tsx Outdated
@vercel
vercel Bot temporarily deployed to Preview – play April 10, 2026 16:17 Inactive
@perkinsjr
perkinsjr merged commit def2f2a into main Apr 10, 2026
6 checks passed
@perkinsjr
perkinsjr deleted the proxy-content branch April 10, 2026 16:23

This branch was successfully deployed

2 active and 1 inactive deployments
Preview – www — 2e3e7312 Deployed Apr 10, 2026 by vercel[bot]
Preview – ratelimit — 2e3e7312 Deployed Apr 10, 2026 by vercel[bot]
Preview – play — 2e3e7312 Deployed Apr 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant