Skip to content

Commit 4182dd5

Browse files
committed
fix(landing): match CollectionPage ItemList order and url to the visible filtered/paginated variant
Address round-2 Cursor Bugbot findings on PR #5638: - buildCollectionPageJsonLd no longer re-sorts the given posts by date - ordering is now solely owned by the caller (selectVisiblePosts), so featured-row-first render order matches ItemList position order - buildCollectionPageJsonLd now takes an optional {tag, page} filter descriptor and reflects it in the emitted url, instead of always pointing at the bare section index regardless of which filtered/ paginated variant's posts are actually listed in mainEntity
1 parent 5a70bea commit 4182dd5

5 files changed

Lines changed: 39 additions & 16 deletions

File tree

apps/sim/app/(landing)/blog/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export default async function BlogIndex({
3737
page={pageNum}
3838
tag={tag}
3939
collectionJsonLd={buildCollectionPageJsonLd(
40-
selectVisiblePosts(posts, { tag, page: pageNum })
40+
selectVisiblePosts(posts, { tag, page: pageNum }),
41+
{ tag, page: pageNum }
4142
)}
4243
/>
4344
)

apps/sim/app/(landing)/library/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ export default async function LibraryIndex({
3737
page={pageNum}
3838
tag={tag}
3939
collectionJsonLd={buildCollectionPageJsonLd(
40-
selectVisiblePosts(posts, { tag, page: pageNum })
40+
selectVisiblePosts(posts, { tag, page: pageNum }),
41+
{ tag, page: pageNum }
4142
)}
4243
/>
4344
)

apps/sim/lib/blog/seo.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ export function buildPostGraphJsonLd(post: ContentMeta) {
2525
return buildPostGraphJsonLdGeneric(post, BLOG_SECTION)
2626
}
2727

28-
export function buildCollectionPageJsonLd(posts: ContentMeta[]) {
29-
return buildCollectionPageJsonLdGeneric(BLOG_SECTION, posts)
28+
export function buildCollectionPageJsonLd(
29+
posts: ContentMeta[],
30+
filter?: { tag?: string; page?: number }
31+
) {
32+
return buildCollectionPageJsonLdGeneric(BLOG_SECTION, posts, filter)
3033
}
3134

3235
export function buildIndexMetadata(input: { tag?: string; pageNum: number }) {

apps/sim/lib/content/seo.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,21 +350,36 @@ export function buildAuthorGraphJsonLd(section: ContentSection, author: Author)
350350
}
351351

352352
/**
353-
* `mainEntity` lists the section's real, currently-published posts (sourced
354-
* from the same `getAllPostMeta()` list the index page renders from — never
355-
* a hardcoded list) so the collection's JSON-LD stays in sync with what's
356-
* actually on the page.
353+
* `mainEntity` lists exactly the posts passed in, in the given order - the
354+
* caller (currently `selectVisiblePosts`) is responsible for sourcing them
355+
* from the same `getAllPostMeta()` list the index page renders from and for
356+
* ordering them to match the visible layout (e.g. featured-row-first), so
357+
* this function never re-sorts and can't diverge from what's on the page.
358+
*
359+
* `tag`/`page` describe which filtered/paginated variant `posts` came from,
360+
* so `url` reflects the actual page these `posts` are visible on rather than
361+
* always the bare section index - the same variant is `noindex`ed (see
362+
* `buildIndexMetadata`), but the graph still shouldn't attribute a partial
363+
* list to the unfiltered collection URL.
357364
*/
358-
export function buildCollectionPageJsonLd(section: ContentSection, posts: ContentMeta[]) {
359-
const dateSorted = [...posts].sort(
360-
(a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
361-
)
365+
export function buildCollectionPageJsonLd(
366+
section: ContentSection,
367+
posts: ContentMeta[],
368+
{ tag, page }: { tag?: string; page?: number } = {}
369+
) {
370+
const params = [
371+
page && page > 1 ? `page=${page}` : null,
372+
tag ? `tag=${encodeURIComponent(tag)}` : null,
373+
]
374+
.filter(Boolean)
375+
.join('&')
376+
const url = `${SITE_URL}${section.basePath}${params ? `?${params}` : ''}`
362377

363378
return {
364379
'@context': 'https://schema.org',
365380
'@type': 'CollectionPage',
366381
name: `Sim ${section.name}`,
367-
url: `${SITE_URL}${section.basePath}`,
382+
url,
368383
description: section.description,
369384
publisher: {
370385
'@type': 'Organization',
@@ -383,7 +398,7 @@ export function buildCollectionPageJsonLd(section: ContentSection, posts: Conten
383398
},
384399
mainEntity: {
385400
'@type': 'ItemList',
386-
itemListElement: dateSorted.map((post, index) => ({
401+
itemListElement: posts.map((post, index) => ({
387402
'@type': 'ListItem',
388403
position: index + 1,
389404
url: post.canonical,

apps/sim/lib/library/seo.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ export function buildPostGraphJsonLd(post: ContentMeta) {
2626
return buildPostGraphJsonLdGeneric(post, LIBRARY_SECTION)
2727
}
2828

29-
export function buildCollectionPageJsonLd(posts: ContentMeta[]) {
30-
return buildCollectionPageJsonLdGeneric(LIBRARY_SECTION, posts)
29+
export function buildCollectionPageJsonLd(
30+
posts: ContentMeta[],
31+
filter?: { tag?: string; page?: number }
32+
) {
33+
return buildCollectionPageJsonLdGeneric(LIBRARY_SECTION, posts, filter)
3134
}
3235

3336
export function buildIndexMetadata(input: { tag?: string; pageNum: number }) {

0 commit comments

Comments
 (0)