Skip to content

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

Open
adithyaakrishna wants to merge 20 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 20 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
Medium risk due to a large UI overhaul plus new dynamic OG image and GitHub-release fetching endpoints that could affect SEO metadata, rendering, and rate-limited external API behavior.

Overview
Redesigns the /blog (Studio) experience into a two-column layout with a sticky sidebar (categories + search), animated hero, new featured/feed grids, and client-side filtering/search/pagination that keeps the URL in sync.

Overhauls the blog post detail page with a new header animation, tag/category styling, share buttons, a right sidebar (authors, table of contents from headings, and recent posts), and updated prose/code styling.

Adds dynamic social sharing + rich content support by introducing a GET /blog/og?slug=... Open Graph image route and updating blog SEO metadata to use it; replaces MDX code rendering with Prism highlighting + copy, adds Mermaid diagram rendering for mermaid code fences, and updates slug generation to use github-slugger.

Refreshes the changelog with a new GET /api/changelog/releases proxy to GitHub (optional token), a redesigned changelog page/hero, and an updated timeline renderer with cleaned markdown and improved visuals/animations.

Minor: updates the collaboration section CTA link to point to the new blog post (/blog/multiplayer) and tweaks the multiplayer MDX outro formatting.

Written by Cursor Bugbot for commit 07da8fd. 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

})}
</ul>
)
}
Copy link

Choose a reason for hiding this comment

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

Duplicated highlight animation between CategoryList and SidebarCategories

Low Severity

SidebarCategories in studio-content.tsx and CategoryList in category-list.tsx implement nearly identical animated highlight logic — same ref-based position tracking, same getBoundingClientRect measurement in a useEffect, same motion.div with spring transition, and same visual styling. The only material difference is the navigation mechanism (button with onClick vs Link). Extracting the shared highlight behavior into a common component or hook would reduce maintenance burden and risk of the two implementations drifting apart.

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.

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