- extend vue-seo-layer (link dependency during development) and drop
@nuxtjs/seo: the page head, canonical and the one JSON-LD graph come
from the CMS resolve answer; the post's own title, excerpt and image
apply only while there is no CMS answer
- remove the journal sitemap source and the copied shared purge route,
library and plugin (the SEO layer serves POST /api/__site__/cache/purge);
the deprecated POST /api/__journal__/cache/purge keeps working
- post title is h1 while the Journal API reports content_h1_to_h2 on
(or absent) and p.journal-post__title while off; journal.postTitleTag
('auto' | 'h1' | 'p') overrides it; body h1 headings are demoted to h2
while the setting is on (gateJournalHtml/sanitizeJournalHtml demoteH1)
- journal.breadcrumbs option and post-title CSS tokens
- smoke harness: count=, header=, noheader= and resolves lines; the
fixture API also answers the SEO resolve and site endpoints
BREAKING CHANGE: the layer no longer installs @nuxtjs/seo (no
nuxt-site-config, nuxt-schema-org, robots or sitemap module, no
/api/__sitemap__/journal source, no useSiteConfig()); apps take their
head, sitemaps and robots from the SEO plugin through vue-seo-layer.
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
// The post page's SSR payload: the post with its body sanitized (h1 demoted
|
|
// to h2 while the Journal H1 setting is on), without the raw `content`
|
|
// source or `translations`, and with related posts as list rows. Kept apart from view.ts because it loads the sanitizer, which list
|
|
// pages and cards do not need.
|
|
|
|
import { sanitizeJournalHtml } from './htmlGate.ts'
|
|
import type { JournalPostDetail } from './types.ts'
|
|
import { toListPost } from './view.ts'
|
|
|
|
/**
|
|
* True while the post's body h1 headings become h2 (the Journal API's
|
|
* content_h1_to_h2; absent on an older Journal, which counts as on).
|
|
*/
|
|
export function demotesH1(post: { content_h1_to_h2?: boolean | null } | null | undefined): boolean {
|
|
return post?.content_h1_to_h2 !== false
|
|
}
|
|
|
|
/** A post page's data: the post with its body sanitized and no source or translations. */
|
|
export type JournalPostView = JournalPostDetail
|
|
|
|
export function toPostView(post: JournalPostDetail): JournalPostView {
|
|
return {
|
|
...post,
|
|
content: null,
|
|
translations: null,
|
|
content_html: sanitizeJournalHtml(post.content_html, { demoteH1: demotesH1(post) }),
|
|
related_posts: (post.related_posts ?? []).map(toListPost),
|
|
}
|
|
}
|