From 261388f17a82db2b759987b0419c4bf6fae57d7f Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Mon, 2 Feb 2026 12:48:10 -0800 Subject: [PATCH] feat(marketing): add related posts section to blog post pages Add a "Related Posts" section above the footer on blog post pages. Posts can specify related posts via `relatedSlugs` frontmatter field, falling back to the 3 most recent other posts when not specified. --- .../blog/git-worktrees-history-deep-dive.mdx | 3 +++ .../marketing/content/blog/how-to-get-hit.mdx | 5 +++- .../blog/terminal-daemon-deep-dive.mdx | 3 +++ .../BlogPostLayout/BlogPostLayout.tsx | 24 ++++++++++++++++++- apps/marketing/src/app/blog/[slug]/page.tsx | 13 ++++++++-- .../app/blog/components/BlogCard/BlogCard.tsx | 8 +++---- apps/marketing/src/lib/blog-utils.ts | 1 + apps/marketing/src/lib/blog.ts | 21 ++++++++++++++++ 8 files changed, 70 insertions(+), 8 deletions(-) diff --git a/apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx b/apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx index 469560f9903..01ab7473d41 100644 --- a/apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx +++ b/apps/marketing/content/blog/git-worktrees-history-deep-dive.mdx @@ -4,6 +4,9 @@ description: "Git worktrees have been around since 2015. For most of that time, author: avi date: 2026-01-27 category: Engineering +relatedSlugs: + - terminal-daemon-deep-dive + - how-to-get-hit --- Git worktrees have been around since 2015. For most of that time, they were a curiosity — something kernel developers used, something that showed up in obscure Stack Overflow answers, something most developers had never heard of. diff --git a/apps/marketing/content/blog/how-to-get-hit.mdx b/apps/marketing/content/blog/how-to-get-hit.mdx index 2825581e264..ef53fa29082 100644 --- a/apps/marketing/content/blog/how-to-get-hit.mdx +++ b/apps/marketing/content/blog/how-to-get-hit.mdx @@ -1,9 +1,12 @@ --- title: How to get hit (probably in the face but anywhere else works too) -description: I ran out of technical content to write for the blog so here is something I am interested in instead. +description: I ran out of technical content to write for the blog so here is something I am interested in instead. author: Kiet Ho date: 2026-01-28 category: Company +relatedSlugs: + - terminal-daemon-deep-dive + - git-worktrees-history-deep-dive --- I like fighting in most forms. I like to watch fights, train fighting, compete, and watch breakdowns. Here's something I learned in training and sparring that I feel is applicable to my own life, perhaps in startups and competition. diff --git a/apps/marketing/content/blog/terminal-daemon-deep-dive.mdx b/apps/marketing/content/blog/terminal-daemon-deep-dive.mdx index a9d16452dd9..9248b9c1cbc 100644 --- a/apps/marketing/content/blog/terminal-daemon-deep-dive.mdx +++ b/apps/marketing/content/blog/terminal-daemon-deep-dive.mdx @@ -4,6 +4,9 @@ description: "How we built a process-isolated terminal host that survives app re author: Avi Peltz date: 2026-01-26 category: Engineering +relatedSlugs: + - git-worktrees-history-deep-dive + - how-to-get-hit --- One of the slickest features of Superset is how our terminal survives app restarts. This is a deep dive on how we built it. Huge credits to [Andreas Asprou](https://x.com/andyasprou) who spearheaded this entire effort. diff --git a/apps/marketing/src/app/blog/[slug]/components/BlogPostLayout/BlogPostLayout.tsx b/apps/marketing/src/app/blog/[slug]/components/BlogPostLayout/BlogPostLayout.tsx index f45c7a94709..d4f7ec7ba1b 100644 --- a/apps/marketing/src/app/blog/[slug]/components/BlogPostLayout/BlogPostLayout.tsx +++ b/apps/marketing/src/app/blog/[slug]/components/BlogPostLayout/BlogPostLayout.tsx @@ -4,16 +4,22 @@ import { ArrowLeft } from "lucide-react"; import Link from "next/link"; import type { ReactNode } from "react"; import { AuthorAvatar } from "@/app/blog/components/AuthorAvatar"; +import { BlogCard } from "@/app/blog/components/BlogCard"; import { GridCross } from "@/app/blog/components/GridCross"; import { type BlogPost, formatBlogDate, type TocItem } from "@/lib/blog-utils"; interface BlogPostLayoutProps { post: BlogPost; toc: TocItem[]; + relatedPosts: BlogPost[]; children: ReactNode; } -export function BlogPostLayout({ post, children }: BlogPostLayoutProps) { +export function BlogPostLayout({ + post, + relatedPosts, + children, +}: BlogPostLayoutProps) { const formattedDate = formatBlogDate(post.date); return ( @@ -88,6 +94,22 @@ export function BlogPostLayout({ post, children }: BlogPostLayoutProps) {
{children}
+ {/* Related Posts */} + {relatedPosts.length > 0 && ( +
+
+

+ Related Posts +

+
+ {relatedPosts.map((relatedPost) => ( + + ))} +
+
+
+ )} + {/* Footer */}