Files
vue-journal-layer/app/composables/useJournalItemList.ts
Jakub Zych 642c25a0d0 feat: ItemList nodes on listing pages
The index, category, tag and author pages add an ItemList node
(@id <page URL>#itemlist, a ListItem with the absolute URL of each post
shown, positions continuing across pages) through vue-seo-layer's
useSchemaNode, so the page keeps one JSON-LD script with one @graph
(useJournalItemList, journalItemList).
2026-11-04 13:55:55 +01:00

24 lines
1.2 KiB
TypeScript

// The ItemList node of a listing page (index, category, tag, author; D-43):
// the posts shown, added to the page's one JSON-LD @graph through
// vue-seo-layer's useSchemaNode, so the page still has one JSON-LD script.
// The URLs are absolute on the CMS's site URL when the page has a resolve
// answer, else on the request's origin.
import type { JournalPageMeta, JournalPost } from '../utils/types.ts'
import { journalItemList, journalSiteOrigin } from '../utils/seo.ts'
export function useJournalItemList(posts: () => readonly JournalPost[] | null | undefined, meta: () => JournalPageMeta | null | undefined): void {
const answer = useSeoAnswer()
const route = useRoute()
const links = useJournalLinks()
const request = useRequestURL()
useSchemaNode(() => {
const a = answer.value?.action === 'ok' ? answer.value : null
const origin = journalSiteOrigin(a?.url, request.origin)
const pageUrl = a?.url && /^https?:\/\//i.test(a.url) ? a.url : `${origin}${route.fullPath}`
const m = meta()
const first = m ? (Math.max(1, m.current_page) - 1) * Math.max(1, m.per_page) + 1 : 1
return journalItemList(pageUrl, origin, (posts() ?? []).map((p) => links.postLink(p.slug)), first)
})
}