diff --git a/apps/website/src/components/landing/RecentArticles.tsx b/apps/website/src/components/landing/RecentArticles.tsx index e0694d91..fca9b3ab 100644 --- a/apps/website/src/components/landing/RecentArticles.tsx +++ b/apps/website/src/components/landing/RecentArticles.tsx @@ -4,15 +4,15 @@ import { Section } from '../ui/Section'; import { Container } from '../ui/Container'; import { Eyebrow } from '../ui/Eyebrow'; import { PostCard } from '../blog/PostCard'; -import { getRecentNonFeatured } from '../../lib/blog'; +import { getRecentPosts } from '../../lib/blog'; /** - * Marketing-home strip showing the three most recent non-featured posts. - * Renders nothing when no eligible posts exist, so the home page stays clean - * while the blog catalog is small. + * Marketing-home strip showing the most recent posts (including any flagged + * `featured`). Renders nothing when no posts exist, so the home page stays + * clean while the blog catalog is small. */ export function RecentArticles() { - const posts = getRecentNonFeatured(3); + const posts = getRecentPosts(3); if (posts.length === 0) return null; return ( diff --git a/apps/website/src/lib/blog.spec.ts b/apps/website/src/lib/blog.spec.ts index 620020a3..b3e9e365 100644 --- a/apps/website/src/lib/blog.spec.ts +++ b/apps/website/src/lib/blog.spec.ts @@ -146,17 +146,17 @@ describe('blog.ts', () => { expect(getAllPosts().map((p) => p.slug)).toEqual(['first-post']); }); - it('getRecentNonFeatured excludes the featured post', async () => { + it('getRecentPosts returns newest-first, including featured', async () => { setupFs({ '2026-05-01-first-post.mdx': post1, '2026-05-10-second-post.mdx': post2, }); - const { getRecentNonFeatured } = await import('./blog'); - // post2 is featured (see fixture at top of file). Expect only post1. - expect(getRecentNonFeatured().map((p) => p.slug)).toEqual(['first-post']); + const { getRecentPosts } = await import('./blog'); + // post2 is featured; it should still appear (sorted first by date). + expect(getRecentPosts().map((p) => p.slug)).toEqual(['second-post', 'first-post']); }); - it('getRecentNonFeatured caps at the limit', async () => { + it('getRecentPosts caps at the limit', async () => { setupFs({ '2026-05-01-first-post.mdx': post1, '2026-05-05-extra-a.mdx': post1.replace('First Post', 'Extra A'), @@ -164,18 +164,16 @@ describe('blog.ts', () => { '2026-05-07-extra-c.mdx': post1.replace('First Post', 'Extra C'), '2026-05-10-second-post.mdx': post2, }); - const { getRecentNonFeatured } = await import('./blog'); - // post2 is featured and filtered out; remaining 4 should be capped to 3. - const result = getRecentNonFeatured(3); + const { getRecentPosts } = await import('./blog'); + const result = getRecentPosts(3); expect(result).toHaveLength(3); - expect(result.map((p) => p.slug)).not.toContain('second-post'); + // Should be the three newest by date. + expect(result.map((p) => p.slug)).toEqual(['second-post', 'extra-c', 'extra-b']); }); - it('getRecentNonFeatured returns [] when only the featured post exists', async () => { - setupFs({ - '2026-05-10-second-post.mdx': post2, - }); - const { getRecentNonFeatured } = await import('./blog'); - expect(getRecentNonFeatured()).toEqual([]); + it('getRecentPosts returns [] when no posts exist', async () => { + setupFs({}); + const { getRecentPosts } = await import('./blog'); + expect(getRecentPosts()).toEqual([]); }); }); diff --git a/apps/website/src/lib/blog.ts b/apps/website/src/lib/blog.ts index 5e5039f2..7c090e85 100644 --- a/apps/website/src/lib/blog.ts +++ b/apps/website/src/lib/blog.ts @@ -151,18 +151,13 @@ export function readingTimeMin(markdown: string): number { } /** - * Recent posts excluding the one currently surfaced as featured on /blog. + * Most recent posts, including any flagged `featured`. * - * Used by the home page "Recent articles" section so visitors don't see the - * same headline post twice (once in the featured slot at /blog and again on - * the home page). `getAllPosts()` already sorts newest-first and excludes - * drafts, so this is a thin filter on top. + * Used by the home page "Recent articles" section. `getAllPosts()` already + * sorts newest-first and excludes drafts, so this is just a slice on top. * * @param limit Maximum number of posts to return. Defaults to 3. */ -export function getRecentNonFeatured(limit = 3): Post[] { - const featured = getFeaturedPost(); - return getAllPosts() - .filter((p) => p.slug !== featured?.slug) - .slice(0, limit); +export function getRecentPosts(limit = 3): Post[] { + return getAllPosts().slice(0, limit); }