@actuate-media/cms-core 0.65.0 → 0.67.0

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.
Files changed (155) hide show
  1. package/CHANGELOG.md +143 -0
  2. package/dist/__tests__/api/ai-quality.test.js +73 -0
  3. package/dist/__tests__/api/ai-quality.test.js.map +1 -1
  4. package/dist/__tests__/api/llms-txt.test.js +59 -0
  5. package/dist/__tests__/api/llms-txt.test.js.map +1 -1
  6. package/dist/__tests__/api/public-seo.test.js +402 -4
  7. package/dist/__tests__/api/public-seo.test.js.map +1 -1
  8. package/dist/__tests__/api/route-contracts.test.js +7 -0
  9. package/dist/__tests__/api/route-contracts.test.js.map +1 -1
  10. package/dist/__tests__/content/slug.test.d.ts +2 -0
  11. package/dist/__tests__/content/slug.test.d.ts.map +1 -0
  12. package/dist/__tests__/content/slug.test.js +68 -0
  13. package/dist/__tests__/content/slug.test.js.map +1 -0
  14. package/dist/__tests__/middleware.test.js +47 -0
  15. package/dist/__tests__/middleware.test.js.map +1 -1
  16. package/dist/__tests__/redirects/auto-301.test.d.ts +2 -0
  17. package/dist/__tests__/redirects/auto-301.test.d.ts.map +1 -0
  18. package/dist/__tests__/redirects/auto-301.test.js +172 -0
  19. package/dist/__tests__/redirects/auto-301.test.js.map +1 -0
  20. package/dist/__tests__/seo/ai-bots.test.d.ts +2 -0
  21. package/dist/__tests__/seo/ai-bots.test.d.ts.map +1 -0
  22. package/dist/__tests__/seo/ai-bots.test.js +53 -0
  23. package/dist/__tests__/seo/ai-bots.test.js.map +1 -0
  24. package/dist/__tests__/seo/alt-text.test.d.ts +2 -0
  25. package/dist/__tests__/seo/alt-text.test.d.ts.map +1 -0
  26. package/dist/__tests__/seo/alt-text.test.js +47 -0
  27. package/dist/__tests__/seo/alt-text.test.js.map +1 -0
  28. package/dist/__tests__/seo/feeds.test.d.ts +2 -0
  29. package/dist/__tests__/seo/feeds.test.d.ts.map +1 -0
  30. package/dist/__tests__/seo/feeds.test.js +61 -0
  31. package/dist/__tests__/seo/feeds.test.js.map +1 -0
  32. package/dist/__tests__/seo/freshness.test.d.ts +2 -0
  33. package/dist/__tests__/seo/freshness.test.d.ts.map +1 -0
  34. package/dist/__tests__/seo/freshness.test.js +89 -0
  35. package/dist/__tests__/seo/freshness.test.js.map +1 -0
  36. package/dist/__tests__/seo/meta-tags-alternates.test.d.ts +2 -0
  37. package/dist/__tests__/seo/meta-tags-alternates.test.d.ts.map +1 -0
  38. package/dist/__tests__/seo/meta-tags-alternates.test.js +52 -0
  39. package/dist/__tests__/seo/meta-tags-alternates.test.js.map +1 -0
  40. package/dist/__tests__/seo/page-meta.test.js +230 -14
  41. package/dist/__tests__/seo/page-meta.test.js.map +1 -1
  42. package/dist/__tests__/seo/sitemap-notify.test.js +77 -1
  43. package/dist/__tests__/seo/sitemap-notify.test.js.map +1 -1
  44. package/dist/__tests__/validation/publish.test.d.ts +2 -0
  45. package/dist/__tests__/validation/publish.test.d.ts.map +1 -0
  46. package/dist/__tests__/validation/publish.test.js +164 -0
  47. package/dist/__tests__/validation/publish.test.js.map +1 -0
  48. package/dist/actions.d.ts.map +1 -1
  49. package/dist/actions.js +172 -8
  50. package/dist/actions.js.map +1 -1
  51. package/dist/api/route-helpers.d.ts +8 -0
  52. package/dist/api/route-helpers.d.ts.map +1 -1
  53. package/dist/api/route-helpers.js +20 -0
  54. package/dist/api/route-helpers.js.map +1 -1
  55. package/dist/api/routes/ai-seo.d.ts.map +1 -1
  56. package/dist/api/routes/ai-seo.js +32 -1
  57. package/dist/api/routes/ai-seo.js.map +1 -1
  58. package/dist/api/routes/auth.d.ts.map +1 -1
  59. package/dist/api/routes/auth.js +2 -1
  60. package/dist/api/routes/auth.js.map +1 -1
  61. package/dist/api/routes/documents.d.ts.map +1 -1
  62. package/dist/api/routes/documents.js +3 -3
  63. package/dist/api/routes/documents.js.map +1 -1
  64. package/dist/api/routes/seo-public.d.ts.map +1 -1
  65. package/dist/api/routes/seo-public.js +371 -62
  66. package/dist/api/routes/seo-public.js.map +1 -1
  67. package/dist/api/routes/seo.d.ts.map +1 -1
  68. package/dist/api/routes/seo.js +21 -10
  69. package/dist/api/routes/seo.js.map +1 -1
  70. package/dist/api/routes/url-resolution.d.ts.map +1 -1
  71. package/dist/api/routes/url-resolution.js +40 -1
  72. package/dist/api/routes/url-resolution.js.map +1 -1
  73. package/dist/api/routes/users.d.ts.map +1 -1
  74. package/dist/api/routes/users.js +6 -3
  75. package/dist/api/routes/users.js.map +1 -1
  76. package/dist/client.d.ts +1 -0
  77. package/dist/client.d.ts.map +1 -1
  78. package/dist/client.js +3 -0
  79. package/dist/client.js.map +1 -1
  80. package/dist/config/types.d.ts +35 -1
  81. package/dist/config/types.d.ts.map +1 -1
  82. package/dist/content/index.d.ts +1 -0
  83. package/dist/content/index.d.ts.map +1 -1
  84. package/dist/content/index.js +1 -0
  85. package/dist/content/index.js.map +1 -1
  86. package/dist/content/slug.d.ts +40 -0
  87. package/dist/content/slug.d.ts.map +1 -0
  88. package/dist/content/slug.js +78 -0
  89. package/dist/content/slug.js.map +1 -0
  90. package/dist/content/structured-data.d.ts +6 -0
  91. package/dist/content/structured-data.d.ts.map +1 -1
  92. package/dist/content/structured-data.js +6 -0
  93. package/dist/content/structured-data.js.map +1 -1
  94. package/dist/content-health/scanner.d.ts +4 -3
  95. package/dist/content-health/scanner.d.ts.map +1 -1
  96. package/dist/content-health/scanner.js +6 -12
  97. package/dist/content-health/scanner.js.map +1 -1
  98. package/dist/middleware.d.ts +1 -0
  99. package/dist/middleware.d.ts.map +1 -1
  100. package/dist/middleware.js +11 -2
  101. package/dist/middleware.js.map +1 -1
  102. package/dist/redirects/auto.d.ts +45 -0
  103. package/dist/redirects/auto.d.ts.map +1 -0
  104. package/dist/redirects/auto.js +55 -0
  105. package/dist/redirects/auto.js.map +1 -0
  106. package/dist/redirects/index.d.ts +2 -0
  107. package/dist/redirects/index.d.ts.map +1 -1
  108. package/dist/redirects/index.js +1 -0
  109. package/dist/redirects/index.js.map +1 -1
  110. package/dist/seo/ai-bots.d.ts +42 -0
  111. package/dist/seo/ai-bots.d.ts.map +1 -0
  112. package/dist/seo/ai-bots.js +104 -0
  113. package/dist/seo/ai-bots.js.map +1 -0
  114. package/dist/seo/alt-text.d.ts +39 -0
  115. package/dist/seo/alt-text.d.ts.map +1 -0
  116. package/dist/seo/alt-text.js +67 -0
  117. package/dist/seo/alt-text.js.map +1 -0
  118. package/dist/seo/analysis.d.ts.map +1 -1
  119. package/dist/seo/analysis.js +7 -11
  120. package/dist/seo/analysis.js.map +1 -1
  121. package/dist/seo/audit-engine.d.ts +1 -0
  122. package/dist/seo/audit-engine.d.ts.map +1 -1
  123. package/dist/seo/audit-engine.js +4 -4
  124. package/dist/seo/audit-engine.js.map +1 -1
  125. package/dist/seo/audit-runner.d.ts.map +1 -1
  126. package/dist/seo/audit-runner.js +1 -0
  127. package/dist/seo/audit-runner.js.map +1 -1
  128. package/dist/seo/feeds.d.ts +36 -0
  129. package/dist/seo/feeds.d.ts.map +1 -0
  130. package/dist/seo/feeds.js +71 -0
  131. package/dist/seo/feeds.js.map +1 -0
  132. package/dist/seo/index.d.ts +9 -3
  133. package/dist/seo/index.d.ts.map +1 -1
  134. package/dist/seo/index.js +5 -2
  135. package/dist/seo/index.js.map +1 -1
  136. package/dist/seo/llms-txt.d.ts.map +1 -1
  137. package/dist/seo/llms-txt.js +13 -2
  138. package/dist/seo/llms-txt.js.map +1 -1
  139. package/dist/seo/meta-tags.d.ts +14 -0
  140. package/dist/seo/meta-tags.d.ts.map +1 -1
  141. package/dist/seo/meta-tags.js +21 -2
  142. package/dist/seo/meta-tags.js.map +1 -1
  143. package/dist/seo/page-meta.d.ts +47 -0
  144. package/dist/seo/page-meta.d.ts.map +1 -1
  145. package/dist/seo/page-meta.js +280 -70
  146. package/dist/seo/page-meta.js.map +1 -1
  147. package/dist/seo/sitemap-notify.d.ts +30 -0
  148. package/dist/seo/sitemap-notify.d.ts.map +1 -1
  149. package/dist/seo/sitemap-notify.js +87 -0
  150. package/dist/seo/sitemap-notify.js.map +1 -1
  151. package/dist/validation/publish.d.ts +53 -0
  152. package/dist/validation/publish.d.ts.map +1 -0
  153. package/dist/validation/publish.js +75 -0
  154. package/dist/validation/publish.js.map +1 -0
  155. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"meta-tags.d.ts","sourceRoot":"","sources":["../../src/seo/meta-tags.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;IACxC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,SAAS,GAAG,qBAAqB,CAAA;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAcD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgD5E;AAQD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA0B9D;AAUD,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,cAAc,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC5F;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB;AAeD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAAG,IAAI,GAC/C,qBAAqB,EAAE,CAkBzB;AAED,kEAAkE;AAClE,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAAG,IAAI,GAC/C,MAAM,CAQR;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAAG,IAAI,GAC/C;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,SAAS,CAyBlF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA4DhE"}
1
+ {"version":3,"file":"meta-tags.d.ts","sourceRoot":"","sources":["../../src/seo/meta-tags.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,9 @@ export function renderMetaTagsHtml(input) {
74
74
  if (input.canonical) {
75
75
  lines.push(`<link rel="canonical" href="${escapeHtml(input.canonical)}" />`);
76
76
  }
77
+ for (const alt of input.alternates ?? []) {
78
+ lines.push(`<link rel="alternate" hreflang="${escapeHtml(alt.hreflang)}" href="${escapeHtml(alt.href)}" />`);
79
+ }
77
80
  for (const [key, value] of Object.entries(tags)) {
78
81
  const escaped = escapeHtml(value);
79
82
  if (isPropertyTag(key)) {
@@ -182,8 +185,24 @@ export function generateNextMetadata(input) {
182
185
  };
183
186
  if (input.description)
184
187
  metadata.description = input.description;
185
- if (input.canonical) {
186
- metadata.alternates = { canonical: input.canonical };
188
+ if (input.metadataBase) {
189
+ try {
190
+ metadata.metadataBase = new URL(input.metadataBase);
191
+ }
192
+ catch {
193
+ // Ignore an unparseable base — Next.js falls back to the deploy origin.
194
+ }
195
+ }
196
+ const languages = {};
197
+ for (const alt of input.alternates ?? []) {
198
+ if (alt.hreflang && alt.href)
199
+ languages[alt.hreflang] = alt.href;
200
+ }
201
+ if (input.canonical || Object.keys(languages).length > 0) {
202
+ metadata.alternates = {
203
+ ...(input.canonical ? { canonical: input.canonical } : {}),
204
+ ...(Object.keys(languages).length > 0 ? { languages } : {}),
205
+ };
187
206
  }
188
207
  metadata.robots = {
189
208
  index: !input.noIndex,
@@ -1 +1 @@
1
- {"version":3,"file":"meta-tags.js","sourceRoot":"","sources":["../../src/seo/meta-tags.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"meta-tags.js","sourceRoot":"","sources":["../../src/seo/meta-tags.ts"],"names":[],"mappings":"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"}
@@ -54,6 +54,16 @@ export interface ComposePageMetaInput {
54
54
  * when `seo.robots.noIndexNonProduction` is set.
55
55
  */
56
56
  environment?: string;
57
+ /**
58
+ * hreflang alternates for this document's translations, emitted in `<head>`
59
+ * (and `alternates.languages` in the Next metadata). The caller (e.g.
60
+ * `/resolve`) supplies these since they require knowing sibling documents.
61
+ * Include an `x-default` entry where appropriate.
62
+ */
63
+ alternates?: Array<{
64
+ hreflang: string;
65
+ href: string;
66
+ }>;
57
67
  }
58
68
  export interface ComposedPageMeta {
59
69
  /** Canonical URL for the document. */
@@ -76,6 +86,43 @@ export interface ComposedPageMeta {
76
86
  metadata: object;
77
87
  }
78
88
  declare function detectSchemaType(collectionSlug: string): string;
89
+ /**
90
+ * Resolve the canonical public URL for a document. This is the SINGLE source of
91
+ * truth shared by the public meta composer (`composePageMeta`, which renders the
92
+ * `<link rel="canonical">` / `og:url`) and the XML sitemap, so the two can never
93
+ * disagree and send conflicting signals to crawlers.
94
+ *
95
+ * Precedence mirrors the rest of the platform (`pages-service`,
96
+ * `page-editor-service`, `/resolve`):
97
+ * 1. An explicit `data.path` (the full URL path an editor set, e.g. `/` for
98
+ * the homepage or `/about/story`) always wins.
99
+ * 2. A `home`/`index`/empty slug maps to the site root.
100
+ * 3. Otherwise `<urlPrefix>/<slug>`.
101
+ */
102
+ export declare function resolveDocumentUrl(params: {
103
+ siteUrl: string;
104
+ urlPrefix?: string | null;
105
+ slug?: string | null;
106
+ data?: Record<string, unknown> | null;
107
+ }): string;
108
+ /**
109
+ * Resolve the canonical freshness dates for a document so every public surface
110
+ * (JSON-LD, Open Graph, etc.) reports the same recency. `datePublished` prefers
111
+ * the DB `publishedAt` (set on first publish) but falls back to editorial date
112
+ * fields authors set in the body (`publishedAt`/`publishedDate`/`publishDate`/
113
+ * `date`). `dateModified` prefers `updatedAt` and never predates publication.
114
+ */
115
+ export declare function resolveContentDates(params: {
116
+ doc: {
117
+ publishedAt?: unknown;
118
+ updatedAt?: unknown;
119
+ };
120
+ data?: Record<string, unknown> | null;
121
+ page?: Record<string, unknown> | null;
122
+ }): {
123
+ datePublished?: string;
124
+ dateModified?: string;
125
+ };
79
126
  /**
80
127
  * Compose page meta + JSON-LD from a CMS document + collection config.
81
128
  * Pure function — safe to call in any runtime (Edge, Node, browser).
@@ -1 +1 @@
1
- {"version":3,"file":"page-meta.d.ts","sourceRoot":"","sources":["../../src/seo/page-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAiB,MAAM,oBAAoB,CAAA;AAa/F;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACrC,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;IAClC,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,GAAG,EAAE,oBAAoB,CAAA;IACzB,kFAAkF;IAClF,UAAU,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAA;IACxC,6FAA6F;IAC7F,MAAM,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAA;IACtD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACtC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAA;IAChB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAA;CACjB;AA0CD,iBAAS,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAQxD;AAsHD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,gBAAgB,CAsI7E;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"page-meta.d.ts","sourceRoot":"","sources":["../../src/seo/page-meta.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { buildSchemaGraph } from '../content/structured-data.js';
1
2
  import { buildNextVerification, buildVerificationMetaEntries, generateMetaTags, generateNextMetadata, renderMetaTagsHtml, renderVerificationMetaHtml, } from './meta-tags.js';
2
3
  import { resolveRobotsDirectives, resolveSeoEnvironment } from './robots.js';
3
4
  import { applySiteTitleTemplate } from './title-templates.js';
@@ -54,14 +55,32 @@ function detectSchemaType(collectionSlug) {
54
55
  function trimTrailingSlash(s) {
55
56
  return s.replace(/\/+$/, '');
56
57
  }
57
- function buildDocUrl(baseUrl, urlPrefix, slug, isHome) {
58
- const base = trimTrailingSlash(baseUrl);
59
- if (isHome)
58
+ /**
59
+ * Resolve the canonical public URL for a document. This is the SINGLE source of
60
+ * truth shared by the public meta composer (`composePageMeta`, which renders the
61
+ * `<link rel="canonical">` / `og:url`) and the XML sitemap, so the two can never
62
+ * disagree and send conflicting signals to crawlers.
63
+ *
64
+ * Precedence mirrors the rest of the platform (`pages-service`,
65
+ * `page-editor-service`, `/resolve`):
66
+ * 1. An explicit `data.path` (the full URL path an editor set, e.g. `/` for
67
+ * the homepage or `/about/story`) always wins.
68
+ * 2. A `home`/`index`/empty slug maps to the site root.
69
+ * 3. Otherwise `<urlPrefix>/<slug>`.
70
+ */
71
+ export function resolveDocumentUrl(params) {
72
+ const base = trimTrailingSlash(params.siteUrl);
73
+ const data = params.data ?? {};
74
+ const explicitPath = typeof data.path === 'string' ? data.path.trim() : '';
75
+ if (explicitPath) {
76
+ const normalized = `/${explicitPath.replace(/^\/+|\/+$/g, '')}`;
77
+ return normalized === '/' ? base || '/' : `${base}${normalized}`;
78
+ }
79
+ const slug = (params.slug ?? data.slug ?? '') || '';
80
+ if (slug === 'home' || slug === 'index' || slug === '')
60
81
  return base || '/';
61
- const prefix = (urlPrefix ?? '').replace(/^\/|\/$/g, '');
62
- if (prefix)
63
- return `${base}/${prefix}/${slug}`;
64
- return `${base}/${slug}`;
82
+ const prefix = (params.urlPrefix ?? '').replace(/^\/|\/$/g, '');
83
+ return prefix ? `${base}/${prefix}/${slug}` : `${base}/${slug}`;
65
84
  }
66
85
  function pickString(...candidates) {
67
86
  for (const c of candidates) {
@@ -70,6 +89,38 @@ function pickString(...candidates) {
70
89
  }
71
90
  return undefined;
72
91
  }
92
+ /**
93
+ * Return the first candidate that is a real boolean (coercing the common
94
+ * string forms `"true"`/`"false"` that some field editors persist). Used to
95
+ * unify the several robots field-name spellings without letting an explicit
96
+ * `false` be skipped the way `??` over mixed types would.
97
+ */
98
+ function firstDefinedBool(...candidates) {
99
+ for (const c of candidates) {
100
+ if (typeof c === 'boolean')
101
+ return c;
102
+ if (c === 'true')
103
+ return true;
104
+ if (c === 'false')
105
+ return false;
106
+ }
107
+ return undefined;
108
+ }
109
+ /**
110
+ * Coerce a media-ish value to a URL string. Accepts a bare URL string or a
111
+ * media object (`{ url }` / `{ src }`); returns undefined otherwise.
112
+ */
113
+ function asImageUrl(value) {
114
+ if (typeof value === 'string' && value.trim().length > 0)
115
+ return value;
116
+ if (value && typeof value === 'object') {
117
+ const obj = value;
118
+ const url = obj.url ?? obj.src;
119
+ if (typeof url === 'string' && url.trim().length > 0)
120
+ return url;
121
+ }
122
+ return undefined;
123
+ }
73
124
  function asIsoDate(v) {
74
125
  if (!v)
75
126
  return undefined;
@@ -82,76 +133,212 @@ function asIsoDate(v) {
82
133
  return undefined;
83
134
  }
84
135
  /**
85
- * Compose Schema.org / JSON-LD for a document. Heuristic mapping from common
86
- * field names schema fields, so default site content (title, description,
87
- * author, etc.) "just works" without per-collection wiring.
136
+ * Resolve the canonical freshness dates for a document so every public surface
137
+ * (JSON-LD, Open Graph, etc.) reports the same recency. `datePublished` prefers
138
+ * the DB `publishedAt` (set on first publish) but falls back to editorial date
139
+ * fields authors set in the body (`publishedAt`/`publishedDate`/`publishDate`/
140
+ * `date`). `dateModified` prefers `updatedAt` and never predates publication.
141
+ */
142
+ export function resolveContentDates(params) {
143
+ const data = params.data ?? {};
144
+ const page = params.page ?? {};
145
+ const datePublished = asIsoDate(params.doc.publishedAt ??
146
+ data.publishedAt ??
147
+ page.publishedAt ??
148
+ data.publishedDate ??
149
+ data.publishDate ??
150
+ data.date);
151
+ const dateModified = asIsoDate(params.doc.updatedAt ?? data.updatedAt ?? page.updatedAt) ?? datePublished;
152
+ return {
153
+ ...(datePublished ? { datePublished } : {}),
154
+ ...(dateModified ? { dateModified } : {}),
155
+ };
156
+ }
157
+ /** Schema.org types that the rich graph foundation already models as nodes. */
158
+ const FOUNDATION_TYPES = new Set(['WebPage', 'Article', 'BlogPosting', 'NewsArticle', 'FAQPage']);
159
+ /** Map a Schema.org type to the page-input content type the graph builder uses. */
160
+ function schemaTypeToPageType(type) {
161
+ switch (type) {
162
+ case 'BlogPosting':
163
+ return 'blog';
164
+ case 'Article':
165
+ case 'NewsArticle':
166
+ return 'article';
167
+ case 'FAQPage':
168
+ return 'faq';
169
+ default:
170
+ return 'page';
171
+ }
172
+ }
173
+ /** Title-case a URL slug segment for a readable breadcrumb name. */
174
+ function humanizeSegment(segment) {
175
+ const decoded = decodeURIComponent(segment).replace(/[-_]+/g, ' ').trim();
176
+ return decoded.replace(/\b\w/g, (c) => c.toUpperCase());
177
+ }
178
+ /**
179
+ * Derive a BreadcrumbList trail from the page URL: Home → each path segment →
180
+ * the current page (named with its real title). Returns an empty array for the
181
+ * homepage so we never emit a single-item or self-referential breadcrumb.
182
+ */
183
+ function deriveBreadcrumbs(siteUrl, url, title) {
184
+ const base = trimTrailingSlash(siteUrl);
185
+ if (!url || url === base || url === `${base}/`)
186
+ return [];
187
+ const path = base && url.startsWith(base) ? url.slice(base.length) : url;
188
+ const segments = path
189
+ .replace(/^\/+|\/+$/g, '')
190
+ .split('/')
191
+ .filter(Boolean);
192
+ if (segments.length === 0)
193
+ return [];
194
+ const crumbs = [{ name: 'Home', url: base || '/' }];
195
+ let acc = base;
196
+ segments.forEach((seg, i) => {
197
+ acc = `${acc}/${seg}`;
198
+ const isLast = i === segments.length - 1;
199
+ crumbs.push({ name: isLast ? title : humanizeSegment(seg), url: acc });
200
+ });
201
+ return crumbs;
202
+ }
203
+ /** Extract FAQ pairs from common document shapes (faqItems / faqs / questions). */
204
+ function extractFaqItems(data, page) {
205
+ const raw = data.faqItems ?? data.faqs ?? data.questions ?? page.faqItems;
206
+ if (!Array.isArray(raw))
207
+ return [];
208
+ const items = [];
209
+ for (const entry of raw) {
210
+ if (!entry || typeof entry !== 'object')
211
+ continue;
212
+ const e = entry;
213
+ const question = pickString(e.question, e.q, e.title);
214
+ const answer = pickString(e.answer, e.a, e.body, e.text);
215
+ if (question && answer)
216
+ items.push({ question, answer });
217
+ }
218
+ return items;
219
+ }
220
+ function asStringArray(...candidates) {
221
+ for (const c of candidates) {
222
+ if (Array.isArray(c)) {
223
+ const strings = c.filter((x) => typeof x === 'string' && x.trim().length > 0);
224
+ if (strings.length > 0)
225
+ return strings;
226
+ }
227
+ if (typeof c === 'string' && c.trim().length > 0)
228
+ return [c];
229
+ }
230
+ return undefined;
231
+ }
232
+ /**
233
+ * Build the additional entity node for Schema.org types the graph foundation
234
+ * doesn't model directly (LocalBusiness, Service, Product, Event, Person, …),
235
+ * linked to the page's WebPage node via `mainEntityOfPage`. Returns null for
236
+ * foundation types (already represented as WebPage/Article nodes).
88
237
  */
89
- function composeJsonLd(type, doc, meta, site) {
238
+ function buildSpecializedEntity(type, doc, meta, site) {
239
+ if (FOUNDATION_TYPES.has(type))
240
+ return null;
90
241
  const data = (doc.data ?? {});
91
242
  const page = (doc.pageSettings ?? {});
92
- // Doc-level override: if structuredData is already populated, use it verbatim
93
- // (the editor knows best). We still add @context if it's missing.
94
- if (doc.structuredData &&
95
- typeof doc.structuredData === 'object' &&
96
- Object.keys(doc.structuredData).length > 0) {
97
- const sd = doc.structuredData;
98
- return {
99
- '@context': sd['@context'] ?? 'https://schema.org',
100
- ...sd,
101
- };
102
- }
103
- const schema = {
104
- '@context': 'https://schema.org',
243
+ const siteUrl = trimTrailingSlash(site?.siteUrl ?? '');
244
+ const node = {
105
245
  '@type': type,
246
+ '@id': `${meta.url}#entity`,
106
247
  name: meta.title,
107
- headline: meta.title,
108
- description: meta.description,
109
248
  url: meta.url,
249
+ mainEntityOfPage: { '@id': meta.url },
110
250
  };
251
+ if (meta.description)
252
+ node.description = meta.description;
111
253
  if (meta.image)
112
- schema.image = meta.image;
113
- // Article-family types.
114
- if (type === 'Article' || type === 'BlogPosting' || type === 'NewsArticle') {
115
- const datePublished = asIsoDate(doc.publishedAt ?? data.publishedAt ?? page.publishedAt);
116
- const dateModified = asIsoDate(doc.updatedAt ?? data.updatedAt ?? page.updatedAt) ?? datePublished;
117
- if (datePublished)
118
- schema.datePublished = datePublished;
119
- if (dateModified)
120
- schema.dateModified = dateModified;
121
- const authorName = pickString(data.authorName, data.author, data.author?.name);
122
- if (authorName) {
123
- schema.author = { '@type': 'Person', name: authorName };
124
- }
125
- const orgName = site?.organization?.name ?? site?.siteName;
126
- if (orgName) {
127
- schema.publisher = {
128
- '@type': 'Organization',
129
- name: orgName,
130
- ...(site?.organization?.logo
131
- ? { logo: { '@type': 'ImageObject', url: site.organization.logo } }
132
- : {}),
133
- };
134
- }
135
- }
136
- // LocalBusiness / Service.
254
+ node.image = { '@id': meta.image };
137
255
  if (type === 'LocalBusiness' || type === 'Service') {
138
256
  const address = data.address ?? page.address;
139
257
  if (address && typeof address === 'object') {
140
- schema.address = { '@type': 'PostalAddress', ...address };
258
+ node.address = { '@type': 'PostalAddress', ...address };
141
259
  }
142
260
  const phone = pickString(data.phone, data.telephone, page.phone);
143
261
  if (phone)
144
- schema.telephone = phone;
262
+ node.telephone = phone;
145
263
  const priceRange = pickString(data.priceRange, page.priceRange);
146
264
  if (priceRange)
147
- schema.priceRange = priceRange;
265
+ node.priceRange = priceRange;
266
+ if (siteUrl)
267
+ node.provider = { '@id': `${siteUrl}/#organization` };
268
+ }
269
+ return node;
270
+ }
271
+ /**
272
+ * Compose a connected Schema.org `@graph` for a document. Stacks the WebSite +
273
+ * Organization (+ sameAs / SearchAction) site nodes, the page node (WebPage or
274
+ * Article/BlogPosting), a derived BreadcrumbList, FAQ `mainEntity`, and an
275
+ * optional specialized entity node (LocalBusiness, Service, …) — so every page
276
+ * ships a single graph that search engines and AI crawlers can traverse,
277
+ * rather than an isolated flat object.
278
+ *
279
+ * Heuristic field mapping keeps default content working without per-collection
280
+ * wiring. A doc-level `structuredData` override is honored verbatim (the editor
281
+ * knows best).
282
+ */
283
+ function composeJsonLd(type, doc, meta, site, config) {
284
+ const data = (doc.data ?? {});
285
+ const page = (doc.pageSettings ?? {});
286
+ // Doc-level override: if structuredData is already populated, use it verbatim.
287
+ if (doc.structuredData &&
288
+ typeof doc.structuredData === 'object' &&
289
+ Object.keys(doc.structuredData).length > 0) {
290
+ const sd = doc.structuredData;
291
+ return {
292
+ '@context': sd['@context'] ?? 'https://schema.org',
293
+ ...sd,
294
+ };
148
295
  }
149
- // Strip undefined to keep JSON clean.
150
- for (const k of Object.keys(schema)) {
151
- if (schema[k] === undefined)
152
- delete schema[k];
296
+ const siteUrl = trimTrailingSlash(site?.siteUrl ?? '');
297
+ const defaultLanguage = config?.i18n?.defaultLocale;
298
+ const siteSchema = {
299
+ siteName: site?.siteName ?? 'Site',
300
+ siteUrl,
301
+ siteDescription: site?.defaultMetaDescription,
302
+ organizationName: site?.organization?.name ?? site?.siteName,
303
+ organizationLogo: site?.organization?.logo,
304
+ organizationSameAs: site?.organization?.sameAs,
305
+ defaultLanguage,
306
+ };
307
+ const { datePublished, dateModified } = resolveContentDates({ doc, data, page });
308
+ const authorName = pickString(data.authorName, data.author, data.author?.name);
309
+ const faqItems = extractFaqItems(data, page);
310
+ // GEO key takeaway → Schema.org `abstract` (a citable summary for AI engines).
311
+ const keyTakeaway = pickString(page.keyTakeaway, data.keyTakeaway);
312
+ const pageInput = {
313
+ url: meta.url,
314
+ title: meta.title,
315
+ description: meta.description,
316
+ type: schemaTypeToPageType(type),
317
+ ...(datePublished ? { datePublished } : {}),
318
+ ...(dateModified ? { dateModified } : {}),
319
+ ...(authorName ? { author: { name: authorName } } : {}),
320
+ ...(meta.image ? { featuredImage: { url: meta.image } } : {}),
321
+ ...(faqItems.length > 0 ? { faqItems } : {}),
322
+ ...(keyTakeaway ? { abstract: keyTakeaway } : {}),
323
+ breadcrumbs: deriveBreadcrumbs(siteUrl, meta.url, meta.title),
324
+ keywords: asStringArray(data.keywords, data.tags),
325
+ articleSection: asStringArray(data.category, data.categories),
326
+ language: defaultLanguage,
327
+ };
328
+ const graphObj = buildSchemaGraph(siteSchema, pageInput);
329
+ const graph = [...graphObj['@graph']];
330
+ const entity = buildSpecializedEntity(type, doc, meta, site);
331
+ if (entity) {
332
+ graph.push(entity);
333
+ // Cross-link the WebPage node to its primary entity for traversal.
334
+ const webPage = graph.find((n) => {
335
+ const t = n['@type'];
336
+ return t === 'WebPage' || (Array.isArray(t) && t.includes('WebPage'));
337
+ });
338
+ if (webPage)
339
+ webPage.mainEntity = { '@id': entity['@id'] };
153
340
  }
154
- return schema;
341
+ return { '@context': 'https://schema.org', '@graph': graph };
155
342
  }
156
343
  /**
157
344
  * Compose page meta + JSON-LD from a CMS document + collection config.
@@ -163,11 +350,16 @@ export function composePageMeta(input) {
163
350
  const collectionSeo = collection?.seo;
164
351
  const data = (doc.data ?? {});
165
352
  const page = (doc.pageSettings ?? {});
353
+ const contentDates = resolveContentDates({ doc, data, page });
166
354
  const siteUrl = input.siteUrl?.replace(/\/+$/, '') ?? site?.siteUrl?.replace(/\/+$/, '') ?? '';
167
355
  const siteName = site?.siteName ?? 'Site';
168
356
  const slug = (doc.slug ?? data.slug ?? '') || '';
169
- const isHome = slug === 'home' || slug === 'index' || slug === '';
170
- const url = buildDocUrl(siteUrl, collection?.urlPrefix, slug, isHome);
357
+ const url = resolveDocumentUrl({
358
+ siteUrl,
359
+ urlPrefix: collection?.urlPrefix,
360
+ slug,
361
+ data,
362
+ });
171
363
  const schemaType = pickString(page.schemaType, data.schemaType, collectionSeo?.defaultSchemaType) ??
172
364
  input.defaultSchemaType ??
173
365
  (collection?.slug ? detectSchemaType(collection.slug) : 'WebPage');
@@ -192,9 +384,13 @@ export function composePageMeta(input) {
192
384
  tag: pickString(data.tags?.[0], data.tag),
193
385
  })
194
386
  : rawTitle;
195
- // Description: per-document value wins, then the site-wide default.
196
- const description = pickString(page.metaDescription, data.metaDescription, data.excerpt, data.description, site?.defaultMetaDescription);
197
- const canonical = pickString(page.canonical, data.canonical) ?? url;
387
+ // Description: per-document value wins, then the GEO key takeaway (a concise
388
+ // citable summary), then other summaries, then the site-wide default.
389
+ const description = pickString(page.metaDescription, data.metaDescription, page.keyTakeaway, data.keyTakeaway, data.excerpt, data.description, site?.defaultMetaDescription);
390
+ // Canonical: accept both the cms-core (`canonical`) and plugin-seo / SEO
391
+ // workspace (`canonicalUrl`) field names so a URL set in either surface is
392
+ // honored on the public page.
393
+ const canonical = pickString(page.canonical, data.canonical, page.canonicalUrl, data.canonicalUrl) ?? url;
198
394
  // Single source of truth for robots resolution (shared with the /seo/meta
199
395
  // render path). Honors the `robotsPolicy` select field, explicit
200
396
  // noindex/nofollow booleans, per-collection + site defaults, and the
@@ -202,8 +398,13 @@ export function composePageMeta(input) {
202
398
  const robots = resolveRobotsDirectives({
203
399
  pageData: {
204
400
  robotsPolicy: page.robotsPolicy ?? data.robotsPolicy,
205
- noIndex: page.noIndex ?? data.noIndex ?? collectionSeo?.defaultRobots?.noIndex,
206
- noFollow: page.noFollow ?? data.noFollow ?? collectionSeo?.defaultRobots?.noFollow,
401
+ // Accept the cms-core (`noIndex`/`noFollow`), lowercase SEO-workspace
402
+ // (`noindex`/`nofollow`), and plugin-seo (`robotsNoindex`/`robotsNofollow`)
403
+ // field names so a directive set in any surface is respected.
404
+ noIndex: firstDefinedBool(page.noIndex, data.noIndex, data.noindex, data.robotsNoindex) ??
405
+ collectionSeo?.defaultRobots?.noIndex,
406
+ noFollow: firstDefinedBool(page.noFollow, data.noFollow, data.nofollow, data.robotsNofollow) ??
407
+ collectionSeo?.defaultRobots?.noFollow,
207
408
  },
208
409
  settings: {
209
410
  defaultNoIndex: site?.robots?.defaultNoIndex,
@@ -212,7 +413,12 @@ export function composePageMeta(input) {
212
413
  },
213
414
  environment: resolveSeoEnvironment(input.environment),
214
415
  });
215
- const ogImageUrl = pickString(page.ogImage, data.ogImage, site?.defaultOgImage) ??
416
+ // A real, author-supplied image (used for the JSON-LD ImageObject — we don't
417
+ // want the dynamic OG generator URL polluting structured data). Falls back to
418
+ // the page's hero / featured / cover image (string or `{ url }`) before the
419
+ // site default, so social cards use the page's own visual when set.
420
+ const realImageUrl = pickString(page.ogImage, data.ogImage, asImageUrl(data.featuredImage), asImageUrl(data.heroImage), asImageUrl(data.coverImage), asImageUrl(data.image), site?.defaultOgImage) ?? undefined;
421
+ const ogImageUrl = realImageUrl ??
216
422
  // The dynamic OG endpoint is served by the CMS API router, which is mounted
217
423
  // under /api/cms — not the site root — so the default must include it or it
218
424
  // 404s for social crawlers.
@@ -230,10 +436,14 @@ export function composePageMeta(input) {
230
436
  : 'website',
231
437
  ogImage: ogImageUrl ? { url: ogImageUrl } : undefined,
232
438
  twitterSite: site?.twitterHandle,
233
- publishedTime: asIsoDate(doc.publishedAt),
234
- modifiedTime: asIsoDate(doc.updatedAt),
439
+ // Same resolved freshness dates the JSON-LD uses, so OG article times and
440
+ // structured data never disagree (and editorial dates are honored).
441
+ publishedTime: contentDates.datePublished,
442
+ modifiedTime: contentDates.dateModified,
235
443
  author: pickString(data.authorName, data.author),
236
444
  locale: config?.i18n?.defaultLocale,
445
+ metadataBase: siteUrl || undefined,
446
+ alternates: input.alternates,
237
447
  };
238
448
  const meta = generateMetaTags(metaInput);
239
449
  let metaHtml = renderMetaTagsHtml(metaInput);
@@ -255,7 +465,7 @@ export function composePageMeta(input) {
255
465
  if (nextVerification)
256
466
  metadata = { ...metadata, verification: nextVerification };
257
467
  }
258
- const jsonLd = composeJsonLd(schemaType, doc, { title, description, url, image: ogImageUrl }, site);
468
+ const jsonLd = composeJsonLd(schemaType, doc, { title, description, url, image: realImageUrl }, site, config);
259
469
  const jsonLdHtml = jsonLd
260
470
  ? `<script type="application/ld+json">${JSON.stringify(jsonLd).replace(/</g, '\\u003c')}</script>`
261
471
  : '';