Skip to content

feat: updated design for blog and blog details page w dynamic og generation#3625

Open
adithyaakrishna wants to merge 32 commits intosimstudioai:stagingfrom
adithyaakrishna:feat/studio-pages
Open

feat: updated design for blog and blog details page w dynamic og generation#3625
adithyaakrishna wants to merge 32 commits intosimstudioai:stagingfrom
adithyaakrishna:feat/studio-pages

Conversation

@adithyaakrishna
Copy link

@adithyaakrishna adithyaakrishna commented Mar 17, 2026

Summary

Complete redesign of the blog (/studio) pages with 2 column sidebar layout, redesigned post cards, a 3 column blog detail page and added feature for dynamic og image generation

Fixes #(issue)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: Design overhaul / UX improvement

Testing

  • Check the Layout of /studio
  • Check the Layout of /studio/
  • Check the OG img generation by /studio/og?slug=<slug>

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

OG Image:

image

How it looks:

screen-capture.13.webm

@cursor
Copy link

cursor bot commented Mar 17, 2026

PR Summary

Medium Risk
Moderate risk: large UI/UX refactor across blog, author, and changelog pages plus a new server OG image route and GitHub API proxy that could affect caching, client-side navigation state, and rate-limited API behavior.

Overview
Redesigns the Blog ("Studio") index and post pages into a two-column layout with a sticky category/search sidebar, animated hero/cards, tag-based category coloring, and client-side filtering/search that syncs to ?tag=/?q=.

Overhauls blog post detail pages with a motion header, new ShareButtons, author cards, related-article cards, and an interactive table-of-contents rail (TableOfContents) driven by parsed h2/h3 headings; adds new prose-studio.css for article typography and code styling.

Adds dynamic social previews via GET /blog/og?slug=... using next/og, plus SEO updates so OpenGraph/Twitter images point to the generated route.

Updates content tooling and supporting pages: adds Mermaid diagram rendering for ```mermaid``` blocks, replaces the blogCodeBlockwith Prism-based highlighting + copy button, introduces category mapping intag-colors.ts, refreshes author pages to include co-authors and sidebar filtering, and updates the changelog to use a new /api/changelog/releasesGitHub proxy (with optionalGITHUB_TOKEN`) and a redesigned, animated release list/hero.

Small landing tweaks include linking the collaboration CTA to /blog/multiplayer, improving feature-tab/preview transitions, and centralizing hexToRgba into utils/formatting.

Written by Cursor Bugbot for commit b14eccb. This will update automatically on new commits. Configure here.

@vercel
Copy link

vercel bot commented Mar 17, 2026

@adithyaakrishna is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR is a comprehensive visual redesign of the Sim blog (/studio) — introducing a persistent two-column sidebar layout, redesigned post cards with category badges, a three-column article detail page (TOC + article + author sidebar), and dynamic per-post OG image generation via a new /studio/og route.

Key concerns identified:

  • Sidebar active state is never wired up (layout.tsx line 49): StudioSidebar is rendered without its activeTag prop, and Next.js layouts do not receive searchParams, so category highlights in the sidebar will never reflect the current filter.
  • Unhandled font-load errors in OG route (og/route.tsx lines 44–47): The fs.readFile calls for font assets are not inside a try-catch; a missing font file will produce an unhandled 500 error for all OG image requests.
  • Non-functional search input (sidebar.tsx lines 32–43): The search field renders and focuses but has no onChange, state, or search logic — it is purely decorative and may confuse users.
  • Tag filter URL semantics changed (page.tsx line 22): ?tag= now expects category IDs (e.g. announcements) rather than raw tag strings (e.g. Announcement). Existing bookmarks or sitemap entries using old tag URLs will silently show all posts instead of the expected results.
  • Untracked setTimeout handles (animated-blocks.tsx lines 53–79): Timers created inside startCycle are not tracked for cleanup, so they continue firing after unmount; a minor performance concern.

Confidence Score: 3/5

  • Merging is safe for the visual redesign, but two functional regressions (sidebar active state, OG font error handling) should be fixed before this ships to production.
  • The overall design work is solid and the new components are well-structured. However, the sidebar active-state feature is completely non-functional due to how Next.js layouts work (a logic issue, not a style one), and the OG image route will crash with 500 errors if the font files are missing. The tag URL schema change also silently breaks any existing filtered links without a migration path.
  • Pay close attention to apps/sim/app/(landing)/studio/layout.tsx (sidebar wiring), apps/sim/app/(landing)/studio/og/route.tsx (font error handling), and apps/sim/app/(landing)/studio/sidebar.tsx (search input placeholder UX).

Important Files Changed

Filename Overview
apps/sim/app/(landing)/studio/layout.tsx Adds StudioSidebar to a two-column layout and a metadata template; activeTag is never passed to the sidebar so category active-state highlighting is always broken.
apps/sim/app/(landing)/studio/og/route.tsx New dynamic OG image route using next/og and custom fonts; font file loading is not wrapped in error handling, so any filesystem issue returns an unhandled 500 to social crawlers.
apps/sim/app/(landing)/studio/[slug]/animated-blocks.tsx New decorative animation component; uses mounted guard correctly but creates untracked setTimeout handles inside startCycle that cannot be cancelled on unmount.
apps/sim/app/(landing)/studio/sidebar.tsx New left-rail sidebar with category counts and a search input; the search input is a non-functional placeholder and the activeTag prop it relies on is never supplied by the layout.
apps/sim/app/(landing)/studio/page.tsx Blog index page redesigned with hero, featured grid and category filtering; tag filter query param semantics changed from raw tag strings to category IDs, which breaks existing tag-based URLs.
apps/sim/app/(landing)/studio/post-grid.tsx Post grid refactored with new PostCard, FeaturedLeadCard, and FeaturedGrid components; category color badges and reading-time display added cleanly.
apps/sim/app/(landing)/studio/tag-colors.ts New config module mapping raw blog tags to five curated categories with colors; clean and well-organized with correct fallback to the "insights" category.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User visits /studio] --> B[StudioLayout]
    B --> C[StudioSidebar\nserver component]
    B --> D[main - children]
    
    C --> C1[getAllPostMeta]
    C1 --> C2[Count posts per category\nvia getPrimaryCategory]
    C2 --> C3[Render category links\nactiveTag always undefined ⚠️]

    D --> E{Route}
    E -->|/studio| F[StudioIndex page]
    E -->|/studio/slug| G[Article page]
    E -->|/studio/og?slug=| H[OG Image route]

    F --> F1[StudioHero]
    F --> F2[FeaturedGrid\nfeatured posts]
    F --> F3[PostGrid\nregular posts]
    F2 --> F4[FeaturedLeadCard]
    F2 --> F5[PostCard]

    G --> G1[AnimatedColorBlocks\nclient animation]
    G --> G2[Article MDX content\n+ prose-studio.css]
    G --> G3[ArticleSidebar\nauthor / TOC / tags / related]
    G --> G4[ShareButtons\nclient component]

    H --> H1{slug param?}
    H1 -->|No| H2[400 Bad Request]
    H1 -->|Yes| H3[getPostBySlug]
    H3 -->|Not found| H4[404]
    H3 -->|Found| H5[Read font files\nfs.readFile ⚠️ unguarded]
    H5 --> H6[ImageResponse\n1200x630 PNG]

    G3 --> G3a[TableOfContents\nclient - IntersectionObserver]
Loading

Last reviewed commit: 34d3d78

</div>
)}

<ArticleSidebar headings={post.headings ?? []} />
Copy link

Choose a reason for hiding this comment

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

Sidebar renders after main content instead of beside

Medium Severity

The ArticleSidebar is placed after the main content div in the flex container, but the parent uses xl:flex-row. The sidebar has xl:sticky xl:top-[76px] but on XL screens it will appear to the right of the article. Combined with the main content having mx-auto centering and max-w-5xl, the sidebar may be pushed off-screen or misaligned on certain viewport sizes because the main content's flex-grow and mx-auto conflict with the sidebar's expected positioning in a two-column layout.

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

const cycleDuration =
exitTotalMs + 200 + COLORS.length * ENTER_STAGGER_MS + ENTER_DURATION_MS + HOLD_MS
schedule(() => startCycle(), cycleDuration)
}
Copy link

Choose a reason for hiding this comment

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

Unbounded timer array growth in animation cycle

Low Severity

The schedule function in AnimatedColorBlocks pushes every setTimeout ID into timers.current, but already-fired timer IDs are never removed. The recursive startCycle keeps scheduling new timers every cycle, causing timers.current to grow unboundedly for the lifetime of the component. While each individual entry is small, this constitutes a memory leak that grows over time.

Fix in Cursor Fix in Web

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