wpheadless-lib 1.1.16 → 1.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/utils/seo.d.ts +3 -0
- package/dist/utils/seo.js +183 -17
- package/dist/views/CategoryListView/index.d.ts +3 -1
- package/dist/views/CategoryListView/index.js +8 -3
- package/dist/views/LegalPageView/index.d.ts +5 -1
- package/dist/views/LegalPageView/index.js +11 -3
- package/dist/views/PostView/index.d.ts +2 -1
- package/dist/views/PostView/index.js +11 -3
- package/package.json +1 -1
package/dist/utils/seo.d.ts
CHANGED
|
@@ -32,6 +32,9 @@ export declare function getOgImageUrl(entity?: OgLike, featuredMedia?: FeaturedM
|
|
|
32
32
|
type RewriteOpts = {
|
|
33
33
|
siteUrl?: string;
|
|
34
34
|
wpApiUrl?: string;
|
|
35
|
+
basePath?: string;
|
|
36
|
+
inLanguage?: string;
|
|
37
|
+
canonicalUrl?: string;
|
|
35
38
|
};
|
|
36
39
|
/**
|
|
37
40
|
* Replace Yoast URLs so they match the frontend domain instead of the WP API domain.
|
package/dist/utils/seo.js
CHANGED
|
@@ -19,13 +19,22 @@ const normalizeWpApiOrigin = (wpApiUrl) => {
|
|
|
19
19
|
const cleaned = wpApiUrl.replace(/\/wp-json\/?$/, "");
|
|
20
20
|
return getOrigin(cleaned);
|
|
21
21
|
};
|
|
22
|
+
const normalizeBasePath = (basePath) => {
|
|
23
|
+
if (!basePath || basePath === "/")
|
|
24
|
+
return "";
|
|
25
|
+
return `/${basePath.replace(/^\/+|\/+$/g, "")}`;
|
|
26
|
+
};
|
|
22
27
|
const resolveRewriteOrigins = (opts, canonical) => {
|
|
23
28
|
const targetOrigin = getOrigin(opts.siteUrl);
|
|
24
29
|
const sourceOrigin = normalizeWpApiOrigin(opts.wpApiUrl) || getOrigin(canonical);
|
|
25
|
-
|
|
30
|
+
const basePath = normalizeBasePath(opts.basePath);
|
|
31
|
+
if (!targetOrigin || !sourceOrigin) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (targetOrigin === sourceOrigin && !basePath) {
|
|
26
35
|
return null;
|
|
27
36
|
}
|
|
28
|
-
return { targetOrigin, sourceOrigin };
|
|
37
|
+
return { targetOrigin, sourceOrigin, basePath };
|
|
29
38
|
};
|
|
30
39
|
const IMAGE_EXTENSIONS = [
|
|
31
40
|
".jpg",
|
|
@@ -43,15 +52,35 @@ const isImageUrl = (url) => {
|
|
|
43
52
|
return (pathname.includes("/wp-content/uploads/") ||
|
|
44
53
|
IMAGE_EXTENSIONS.some((ext) => pathname.endsWith(ext)));
|
|
45
54
|
};
|
|
46
|
-
const
|
|
55
|
+
const addBasePath = (url, basePath) => {
|
|
56
|
+
if (!basePath)
|
|
57
|
+
return;
|
|
58
|
+
if (url.hash.startsWith("#/schema/person/"))
|
|
59
|
+
return;
|
|
60
|
+
if (url.pathname === basePath || url.pathname.startsWith(`${basePath}/`)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
url.pathname = `${basePath}${url.pathname === "/" ? "/" : url.pathname}`;
|
|
64
|
+
};
|
|
65
|
+
const nodeHasType = (node, expected) => {
|
|
66
|
+
const type = node["@type"];
|
|
67
|
+
if (Array.isArray(type))
|
|
68
|
+
return type.includes(expected);
|
|
69
|
+
return type === expected;
|
|
70
|
+
};
|
|
71
|
+
const rewriteSchemaValue = (value, { targetOrigin, sourceOrigin, basePath }) => {
|
|
47
72
|
if (Array.isArray(value)) {
|
|
48
|
-
return value.map((item) => rewriteSchemaValue(item, { targetOrigin, sourceOrigin }));
|
|
73
|
+
return value.map((item) => rewriteSchemaValue(item, { targetOrigin, sourceOrigin, basePath }));
|
|
49
74
|
}
|
|
50
75
|
if (value && typeof value === "object") {
|
|
51
76
|
const obj = value;
|
|
52
77
|
const rewritten = {};
|
|
53
78
|
for (const [key, val] of Object.entries(obj)) {
|
|
54
|
-
rewritten[key] = rewriteSchemaValue(val, {
|
|
79
|
+
rewritten[key] = rewriteSchemaValue(val, {
|
|
80
|
+
targetOrigin,
|
|
81
|
+
sourceOrigin,
|
|
82
|
+
basePath,
|
|
83
|
+
});
|
|
55
84
|
}
|
|
56
85
|
return rewritten;
|
|
57
86
|
}
|
|
@@ -63,11 +92,15 @@ const rewriteSchemaValue = (value, { targetOrigin, sourceOrigin }) => {
|
|
|
63
92
|
catch {
|
|
64
93
|
return value;
|
|
65
94
|
}
|
|
66
|
-
if (parsed.origin !== sourceOrigin)
|
|
67
|
-
return value;
|
|
68
95
|
if (isImageUrl(parsed))
|
|
69
96
|
return value;
|
|
70
|
-
|
|
97
|
+
if (parsed.origin !== sourceOrigin && parsed.origin !== targetOrigin) {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
parsed.protocol = new URL(targetOrigin).protocol;
|
|
101
|
+
parsed.host = new URL(targetOrigin).host;
|
|
102
|
+
addBasePath(parsed, basePath);
|
|
103
|
+
return parsed.toString();
|
|
71
104
|
}
|
|
72
105
|
return value;
|
|
73
106
|
};
|
|
@@ -77,6 +110,95 @@ const rewriteYoastSchemaUrls = (schema, opts, canonical) => {
|
|
|
77
110
|
return schema;
|
|
78
111
|
return rewriteSchemaValue(schema, origins);
|
|
79
112
|
};
|
|
113
|
+
const applyCanonicalUrlOverride = (schema, canonicalUrl) => {
|
|
114
|
+
if (!canonicalUrl || !schema || typeof schema !== "object")
|
|
115
|
+
return schema;
|
|
116
|
+
const graph = schema["@graph"];
|
|
117
|
+
if (!Array.isArray(graph))
|
|
118
|
+
return schema;
|
|
119
|
+
const pageUrls = new Set();
|
|
120
|
+
for (const node of graph) {
|
|
121
|
+
if (!nodeHasType(node, "WebPage"))
|
|
122
|
+
continue;
|
|
123
|
+
if (typeof node["@id"] === "string")
|
|
124
|
+
pageUrls.add(node["@id"]);
|
|
125
|
+
if (typeof node.url === "string")
|
|
126
|
+
pageUrls.add(node.url);
|
|
127
|
+
}
|
|
128
|
+
if (!pageUrls.size)
|
|
129
|
+
return schema;
|
|
130
|
+
const replacePageReferences = (value) => {
|
|
131
|
+
if (typeof value === "string") {
|
|
132
|
+
return pageUrls.has(value) ? canonicalUrl : value;
|
|
133
|
+
}
|
|
134
|
+
if (Array.isArray(value))
|
|
135
|
+
return value.map(replacePageReferences);
|
|
136
|
+
if (value && typeof value === "object") {
|
|
137
|
+
return Object.fromEntries(Object.entries(value).map(([key, val]) => [
|
|
138
|
+
key,
|
|
139
|
+
replacePageReferences(val),
|
|
140
|
+
]));
|
|
141
|
+
}
|
|
142
|
+
return value;
|
|
143
|
+
};
|
|
144
|
+
const normalizedGraph = graph.map((node) => {
|
|
145
|
+
const next = replacePageReferences(node);
|
|
146
|
+
if (nodeHasType(next, "WebPage")) {
|
|
147
|
+
next["@id"] = canonicalUrl;
|
|
148
|
+
next.url = canonicalUrl;
|
|
149
|
+
}
|
|
150
|
+
return next;
|
|
151
|
+
});
|
|
152
|
+
return { ...schema, "@graph": normalizedGraph };
|
|
153
|
+
};
|
|
154
|
+
const getYoastDescription = (yoast) => {
|
|
155
|
+
const description = yoast?.description || yoast?.og_description;
|
|
156
|
+
return typeof description === "string" && description.trim()
|
|
157
|
+
? description.trim()
|
|
158
|
+
: undefined;
|
|
159
|
+
};
|
|
160
|
+
const toIsoDateTime = (date) => {
|
|
161
|
+
if (typeof date !== "string" || !date.trim())
|
|
162
|
+
return undefined;
|
|
163
|
+
const trimmed = date.trim();
|
|
164
|
+
if (/[zZ]$|[+-]\d{2}:?\d{2}$/.test(trimmed))
|
|
165
|
+
return trimmed;
|
|
166
|
+
return `${trimmed}+00:00`;
|
|
167
|
+
};
|
|
168
|
+
const getModifiedDate = (entity, yoast) => {
|
|
169
|
+
const dates = entity;
|
|
170
|
+
return (toIsoDateTime(dates?.modified_gmt) ||
|
|
171
|
+
toIsoDateTime(yoast?.article_modified_time) ||
|
|
172
|
+
toIsoDateTime(dates?.modified));
|
|
173
|
+
};
|
|
174
|
+
const enrichYoastSchema = (schema, entity, yoast, opts) => {
|
|
175
|
+
if (!schema || typeof schema !== "object")
|
|
176
|
+
return schema;
|
|
177
|
+
const graph = schema["@graph"];
|
|
178
|
+
if (!Array.isArray(graph))
|
|
179
|
+
return schema;
|
|
180
|
+
const description = getYoastDescription(yoast);
|
|
181
|
+
const dateModified = getModifiedDate(entity, yoast);
|
|
182
|
+
const enriched = graph.map((node) => {
|
|
183
|
+
const next = { ...node };
|
|
184
|
+
if (opts.inLanguage && "inLanguage" in next) {
|
|
185
|
+
next.inLanguage = opts.inLanguage;
|
|
186
|
+
}
|
|
187
|
+
if (typeof next.description === "string" && !next.description.trim()) {
|
|
188
|
+
delete next.description;
|
|
189
|
+
}
|
|
190
|
+
if (description &&
|
|
191
|
+
(nodeHasType(next, "Article") || nodeHasType(next, "WebPage"))) {
|
|
192
|
+
next.description = description;
|
|
193
|
+
}
|
|
194
|
+
if (dateModified &&
|
|
195
|
+
(nodeHasType(next, "Article") || nodeHasType(next, "WebPage"))) {
|
|
196
|
+
next.dateModified = dateModified;
|
|
197
|
+
}
|
|
198
|
+
return next;
|
|
199
|
+
});
|
|
200
|
+
return { ...schema, "@graph": enriched };
|
|
201
|
+
};
|
|
80
202
|
/**
|
|
81
203
|
* Replace Yoast URLs so they match the frontend domain instead of the WP API domain.
|
|
82
204
|
* It stringifies the object to replace origins and keeps structure intact.
|
|
@@ -173,7 +295,10 @@ export function getYoastSchema(entity, opts) {
|
|
|
173
295
|
const yoast = entity?.yoast_head_json;
|
|
174
296
|
if (!yoast?.schema)
|
|
175
297
|
return null;
|
|
176
|
-
|
|
298
|
+
const options = opts ?? {};
|
|
299
|
+
const enriched = enrichYoastSchema(yoast.schema, entity, yoast, options);
|
|
300
|
+
const rewritten = rewriteYoastSchemaUrls(enriched, options, yoast.canonical);
|
|
301
|
+
return applyCanonicalUrlOverride(rewritten, options.canonicalUrl) || null;
|
|
177
302
|
}
|
|
178
303
|
export function stripBreadcrumbsFromSchema(schema) {
|
|
179
304
|
if (!schema || typeof schema !== "object")
|
|
@@ -181,15 +306,56 @@ export function stripBreadcrumbsFromSchema(schema) {
|
|
|
181
306
|
const graph = schema["@graph"];
|
|
182
307
|
if (!Array.isArray(graph))
|
|
183
308
|
return schema;
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
309
|
+
const containsGravatarUrl = (value) => {
|
|
310
|
+
if (typeof value === "string") {
|
|
311
|
+
try {
|
|
312
|
+
return new URL(value).hostname.endsWith("gravatar.com");
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
190
317
|
}
|
|
191
|
-
|
|
192
|
-
|
|
318
|
+
if (Array.isArray(value))
|
|
319
|
+
return value.some(containsGravatarUrl);
|
|
320
|
+
if (value && typeof value === "object") {
|
|
321
|
+
return Object.values(value).some(containsGravatarUrl);
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
};
|
|
325
|
+
const stripSchemaReferences = (node) => {
|
|
326
|
+
const rest = { ...node };
|
|
327
|
+
delete rest.breadcrumb;
|
|
328
|
+
if (nodeHasType(rest, "Article")) {
|
|
329
|
+
delete rest.commentCount;
|
|
330
|
+
if (Array.isArray(rest.potentialAction)) {
|
|
331
|
+
const actions = rest.potentialAction.filter((action) => {
|
|
332
|
+
if (!action || typeof action !== "object")
|
|
333
|
+
return true;
|
|
334
|
+
return !nodeHasType(action, "CommentAction");
|
|
335
|
+
});
|
|
336
|
+
if (actions.length) {
|
|
337
|
+
rest.potentialAction = actions;
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
delete rest.potentialAction;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (nodeHasType(rest, "WebSite")) {
|
|
345
|
+
delete rest.potentialAction;
|
|
346
|
+
}
|
|
347
|
+
if (nodeHasType(rest, "Person")) {
|
|
348
|
+
delete rest.sameAs;
|
|
349
|
+
delete rest.url;
|
|
350
|
+
if (containsGravatarUrl(rest.image)) {
|
|
351
|
+
delete rest.image;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return rest;
|
|
355
|
+
};
|
|
356
|
+
const filtered = graph.filter((node) => {
|
|
357
|
+
return !nodeHasType(node, "BreadcrumbList");
|
|
358
|
+
}).map(stripSchemaReferences);
|
|
193
359
|
return { ...schema, "@graph": filtered };
|
|
194
360
|
}
|
|
195
361
|
export function getFeaturedMedia(entity) {
|
|
@@ -11,6 +11,8 @@ type CategoryListViewProps = {
|
|
|
11
11
|
locale?: Locale;
|
|
12
12
|
dateLocale?: string;
|
|
13
13
|
languageLinks?: LanguageLink[];
|
|
14
|
+
siteUrl?: string;
|
|
15
|
+
wpApiUrl?: string;
|
|
14
16
|
};
|
|
15
|
-
export declare function CategoryListView({ category, posts, totalPages, baseUrl, homeHref, linkBasePath, locale, dateLocale, languageLinks, }: CategoryListViewProps): import("react").JSX.Element;
|
|
17
|
+
export declare function CategoryListView({ category, posts, totalPages, baseUrl, homeHref, linkBasePath, locale, dateLocale, languageLinks, siteUrl, wpApiUrl, }: CategoryListViewProps): import("react").JSX.Element;
|
|
16
18
|
export {};
|
|
@@ -4,13 +4,18 @@ import PostCard from "../../components/PostCard/index.js";
|
|
|
4
4
|
import styles from "./index.module.css";
|
|
5
5
|
import { getCountLabel, getEmptyLabel, getPaginatorBase } from "./index.utils.js";
|
|
6
6
|
import { Breadcrumbs, JsonLd, LanguageLinks } from "../../components/index.js";
|
|
7
|
-
import { getTranslator, getYoastSchema } from "../../utils/index.js";
|
|
8
|
-
export function CategoryListView({ category, posts, totalPages, baseUrl, homeHref = "/", linkBasePath, locale, dateLocale = "en-US", languageLinks, }) {
|
|
7
|
+
import { getTranslator, getYoastSchema, stripBreadcrumbsFromSchema, } from "../../utils/index.js";
|
|
8
|
+
export function CategoryListView({ category, posts, totalPages, baseUrl, homeHref = "/", linkBasePath, locale, dateLocale = "en-US", languageLinks, siteUrl, wpApiUrl, }) {
|
|
9
9
|
const paginatorBase = getPaginatorBase(category, baseUrl);
|
|
10
10
|
const countLabel = getCountLabel(category, locale);
|
|
11
11
|
const emptyLabel = getEmptyLabel(locale);
|
|
12
12
|
const t = getTranslator(locale);
|
|
13
|
-
return (_jsxs("div", { className: styles.container, children: [_jsx(JsonLd, { data: getYoastSchema(category
|
|
13
|
+
return (_jsxs("div", { className: styles.container, children: [_jsx(JsonLd, { data: stripBreadcrumbsFromSchema(getYoastSchema(category, {
|
|
14
|
+
siteUrl,
|
|
15
|
+
wpApiUrl,
|
|
16
|
+
basePath: linkBasePath,
|
|
17
|
+
inLanguage: dateLocale,
|
|
18
|
+
})) }), _jsxs("header", { className: styles.header, children: [_jsx(Breadcrumbs, { items: [
|
|
14
19
|
{ label: "Home", href: homeHref },
|
|
15
20
|
{ label: category.name },
|
|
16
21
|
] }), _jsx("h1", { className: styles.title, children: category.name }), category.description && (_jsx("div", { className: styles.description, dangerouslySetInnerHTML: { __html: category.description } })), countLabel && _jsx("p", { className: styles.count, children: countLabel })] }), posts.length === 0 ? (_jsx("p", { className: styles.empty, children: emptyLabel })) : (_jsxs("section", { "aria-label": t("home.title"), className: styles.gridSection, children: [_jsx("div", { className: styles.grid, children: posts.map((post) => (_jsx(PostCard, { post: post, categorySlug: category.slug, basePath: linkBasePath, locale: locale, dateLocale: dateLocale }, post.id))) }), _jsx(Paginator, { currentPage: 1, totalPages: totalPages, baseUrl: paginatorBase, locale: locale }), _jsx(LanguageLinks, { links: languageLinks, locale: locale })] }))] }));
|
|
@@ -8,6 +8,10 @@ type LegalPageViewProps = {
|
|
|
8
8
|
locale?: Locale;
|
|
9
9
|
priorityImage?: boolean;
|
|
10
10
|
languageLinks?: LanguageLink[];
|
|
11
|
+
siteUrl?: string;
|
|
12
|
+
wpApiUrl?: string;
|
|
13
|
+
basePath?: string;
|
|
14
|
+
renderYoastSchema?: boolean;
|
|
11
15
|
};
|
|
12
|
-
export declare function LegalPageView({ page, homeHref, locale, priorityImage, languageLinks, }: LegalPageViewProps): import("react").JSX.Element;
|
|
16
|
+
export declare function LegalPageView({ page, dateLocale, homeHref, locale, priorityImage, languageLinks, siteUrl, wpApiUrl, basePath, renderYoastSchema, }: LegalPageViewProps): import("react").JSX.Element;
|
|
13
17
|
export {};
|
|
@@ -3,10 +3,18 @@ import Image from "next/image";
|
|
|
3
3
|
import styles from "./index.module.css";
|
|
4
4
|
import { getLegalContent, getLegalImage } from "./index.utils.js";
|
|
5
5
|
import { Breadcrumbs, JsonLd, LanguageLinks } from "../../components/index.js";
|
|
6
|
-
import { getYoastSchema, stripTags } from "../../utils/index.js";
|
|
7
|
-
export function LegalPageView({ page, homeHref, locale, priorityImage = true, languageLinks, }) {
|
|
6
|
+
import { getYoastSchema, stripBreadcrumbsFromSchema, stripTags, } from "../../utils/index.js";
|
|
7
|
+
export function LegalPageView({ page, dateLocale = "en-US", homeHref, locale, priorityImage = true, languageLinks, siteUrl, wpApiUrl, basePath, renderYoastSchema = true, }) {
|
|
8
8
|
const featuredImage = getLegalImage(page);
|
|
9
9
|
const { titleHtml, contentHtml } = getLegalContent(page);
|
|
10
10
|
const titleText = stripTags(titleHtml) || titleHtml;
|
|
11
|
-
|
|
11
|
+
const yoastSchema = renderYoastSchema
|
|
12
|
+
? stripBreadcrumbsFromSchema(getYoastSchema(page, {
|
|
13
|
+
siteUrl,
|
|
14
|
+
wpApiUrl,
|
|
15
|
+
basePath,
|
|
16
|
+
inLanguage: dateLocale,
|
|
17
|
+
}))
|
|
18
|
+
: null;
|
|
19
|
+
return (_jsxs("article", { className: styles.article, children: [_jsx(JsonLd, { data: yoastSchema }), _jsx(Breadcrumbs, { items: [{ label: "Home", href: homeHref }, { label: titleText }] }), featuredImage && (_jsx("div", { className: styles.imageWrapper, children: _jsx(Image, { src: featuredImage.src, alt: featuredImage.alt, width: featuredImage.width, height: featuredImage.height, className: styles.image, priority: priorityImage }) })), _jsx("h1", { dangerouslySetInnerHTML: { __html: titleHtml }, className: styles.title }), _jsx(LanguageLinks, { links: languageLinks, locale: locale }), _jsx("div", { dangerouslySetInnerHTML: { __html: contentHtml }, className: `post-content ${styles.content}` })] }));
|
|
12
20
|
}
|
|
@@ -12,6 +12,7 @@ type PostViewProps = {
|
|
|
12
12
|
siteUrl?: string;
|
|
13
13
|
wpApiUrl?: string;
|
|
14
14
|
languageLinks?: LanguageLink[];
|
|
15
|
+
renderYoastSchema?: boolean;
|
|
15
16
|
};
|
|
16
|
-
export declare function PostView({ post, dateLocale, categoryBasePath, locale, authorDescription, disclaimer, priorityImage, siteUrl, wpApiUrl, languageLinks, }: PostViewProps): import("react").JSX.Element;
|
|
17
|
+
export declare function PostView({ post, dateLocale, categoryBasePath, locale, authorDescription, disclaimer, priorityImage, siteUrl, wpApiUrl, languageLinks, renderYoastSchema, }: PostViewProps): import("react").JSX.Element;
|
|
17
18
|
export {};
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import Image from "next/image";
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import styles from "./index.module.css";
|
|
5
|
-
import { getTranslator, getYoastSchema, rewritePostContentLinks, } from "../../utils/index.js";
|
|
5
|
+
import { getTranslator, getYoastSchema, rewritePostContentLinks, stripBreadcrumbsFromSchema, } from "../../utils/index.js";
|
|
6
6
|
import { Breadcrumbs, JsonLd, LanguageLinks } from "../../components/index.js";
|
|
7
7
|
import { buildCategoryUrl, formatPublishedDate, getAuthor, getFeaturedImage, getPrimaryCategory, } from "./index.utils.js";
|
|
8
8
|
import { stripTags } from "../../utils/index.js";
|
|
@@ -11,7 +11,7 @@ function truncateLabel(label, max = 20) {
|
|
|
11
11
|
const trimmed = label.trim();
|
|
12
12
|
return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;
|
|
13
13
|
}
|
|
14
|
-
export function PostView({ post, dateLocale = "en-US", categoryBasePath = "/", locale, authorDescription, disclaimer, priorityImage = true, siteUrl, wpApiUrl, languageLinks, }) {
|
|
14
|
+
export function PostView({ post, dateLocale = "en-US", categoryBasePath = "/", locale, authorDescription, disclaimer, priorityImage = true, siteUrl, wpApiUrl, languageLinks, renderYoastSchema = true, }) {
|
|
15
15
|
const t = getTranslator(locale);
|
|
16
16
|
const author = getAuthor(post);
|
|
17
17
|
const authorBio = authorDescription ?? author?.description;
|
|
@@ -34,5 +34,13 @@ export function PostView({ post, dateLocale = "en-US", categoryBasePath = "/", l
|
|
|
34
34
|
{ label: "Home", href: categoryBasePath },
|
|
35
35
|
{ label: stripTags(post.title.rendered) || post.title.rendered },
|
|
36
36
|
];
|
|
37
|
-
|
|
37
|
+
const yoastSchema = renderYoastSchema
|
|
38
|
+
? stripBreadcrumbsFromSchema(getYoastSchema(post, {
|
|
39
|
+
siteUrl,
|
|
40
|
+
wpApiUrl,
|
|
41
|
+
basePath: categoryBasePath,
|
|
42
|
+
inLanguage: dateLocale,
|
|
43
|
+
}))
|
|
44
|
+
: null;
|
|
45
|
+
return (_jsxs("div", { className: styles.container, children: [_jsx(JsonLd, { data: yoastSchema }), _jsxs("article", { className: styles.article, children: [_jsx(Breadcrumbs, { items: breadcrumbs }), featuredImage && (_jsxs("figure", { className: styles.figure, children: [_jsx(Image, { src: featuredImage.src, alt: featuredImage.alt, fill: true, className: styles.image, priority: priorityImage, sizes: "(max-width: 1200px) 100vw, 1200px" }), _jsx("div", { className: styles.heroOverlay, "aria-hidden": "true" }), primaryCategory && (_jsx("div", { className: styles.badgeOverlay, children: categoryUrl ? (_jsx(Link, { href: categoryUrl, className: badgeClassName(), title: primaryCategory.name, children: truncateLabel(primaryCategory.name, 20) })) : (_jsx("span", { className: badgeClassName(), title: primaryCategory.name, children: truncateLabel(primaryCategory.name, 20) })) })), _jsx("h1", { dangerouslySetInnerHTML: { __html: post.title.rendered }, className: `${styles.title} ${styles.heroTitle}` })] })), !featuredImage && (_jsx("header", { className: styles.postHeader, children: _jsx("h1", { dangerouslySetInnerHTML: { __html: post.title.rendered }, className: styles.title }) })), _jsxs("div", { className: styles.meta, children: [author && (_jsx("span", { className: styles.authorLabel, children: t("post.authorPrefix", { name: author.name }) })), _jsx("span", { children: "\u2022" }), _jsx("time", { dateTime: post.date, children: publishedDate })] }), _jsx("div", { dangerouslySetInnerHTML: { __html: contentHtml }, className: `post-content ${styles.content}` }), disclaimer && (_jsx(Alert, { className: styles.disclaimer, role: "note", children: disclaimer })), _jsx(LanguageLinks, { links: languageLinks, locale: locale }), author && (_jsx(Card, { as: "aside", className: styles.authorCard, size: "sm", children: _jsx(CardContent, { children: _jsxs("address", { className: styles.authorAddress, children: [_jsx("strong", { className: styles.authorName, children: author.name }), authorBio && _jsx("p", { className: styles.authorBio, children: authorBio })] }) }) }))] })] }));
|
|
38
46
|
}
|