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).
24 lines
1.2 KiB
TypeScript
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)
|
|
})
|
|
}
|