@sonordev/site-kit 7.3.0 → 8.0.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 (239) hide show
  1. package/AGENTS.md +40 -12
  2. package/CHANGELOG.md +73 -0
  3. package/README.md +44 -18
  4. package/agent-manifest.json +111 -56
  5. package/dist/AnalyticsProvider-LYFDQRRJ.js +13 -0
  6. package/dist/{ArticleViewTracker-GFOAXFV7.js → ArticleViewTracker-HG7IIRJY.js} +6 -5
  7. package/dist/{BlocksPopup-AHDU34TL.js → BlocksPopup-GFX3GZIK.js} +6 -5
  8. package/dist/{ChatWidget-FHBAHFZX.js → ChatWidget-DVS7MLBN.js} +8 -5
  9. package/dist/{FileField-J5W5MIAZ.js → FileField-DVN7NUBI.js} +5 -5
  10. package/dist/{FormSpotlight-PE5YZBFZ.js → FormSpotlight-W4SXKKO6.js} +3 -3
  11. package/dist/{FormStage-OOPQC27J.js → FormStage-JTEE5MZD.js} +3 -3
  12. package/dist/ManagedForm-ZAUHIHGP.js +19 -0
  13. package/dist/{ManagedNewsletterForm-TC5542ZG.js → ManagedNewsletterForm-DQIB5Z4Y.js} +9 -6
  14. package/dist/{SignalCore-2YP5FCAS.js → SignalCore-W5PYYMGX.js} +7 -7
  15. package/dist/SiteChat-MY2GATWC.js +6 -0
  16. package/dist/SiteDesignReporter-ICZWEGCY.js +12 -0
  17. package/dist/SitePopups-TGULLAER.js +13 -0
  18. package/dist/SitemapSync-AN2OBJE6.js +9 -0
  19. package/dist/_client/booking-widget.js +6 -5
  20. package/dist/_client/testimonial-section.d.ts +1 -1
  21. package/dist/_client/testimonial-section.js +4 -2
  22. package/dist/affiliates/index.js +6 -6
  23. package/dist/analytics/index.js +73 -7
  24. package/dist/articles/index.js +2 -2
  25. package/dist/articles/server-ui.js +3 -3
  26. package/dist/articles/server.js +2 -2
  27. package/dist/brand.css +1 -1
  28. package/dist/chat/index.d.ts +1 -1
  29. package/dist/chat/index.js +39 -8
  30. package/dist/chunk-3G7YABRA.js +25 -0
  31. package/dist/{chunk-CGWUXUYZ.js → chunk-3RDJKIYO.js} +2 -2
  32. package/dist/{chunk-J4FSB4OG.js → chunk-3YKQLC7J.js} +5 -2
  33. package/dist/{chunk-BEBR4OJD.js → chunk-56VDS2RP.js} +2 -2
  34. package/dist/chunk-5ROTTMBL.js +19 -0
  35. package/dist/{chunk-56KNHB4U.js → chunk-5S2XDG5O.js} +1 -1
  36. package/dist/chunk-5TM3WPCI.js +7 -0
  37. package/dist/{chunk-BR4ZKUHH.js → chunk-6CJGZFOU.js} +18 -2
  38. package/dist/{chunk-RYVDGXC2.js → chunk-6KU7STM3.js} +3 -1
  39. package/dist/{chunk-XLSQTTUE.js → chunk-6QFINXLH.js} +3 -3
  40. package/dist/{chunk-CYUFBKJQ.js → chunk-6ZXJ3SXR.js} +1 -1
  41. package/dist/{chunk-NI2XNEMR.js → chunk-7YEEOIWI.js} +1 -1
  42. package/dist/{chunk-DNPNYWVL.js → chunk-BQ2CXKTQ.js} +5 -20
  43. package/dist/{chunk-X6F6SO4S.js → chunk-C7TLGL3R.js} +21 -1
  44. package/dist/{chunk-43OCZ3JA.js → chunk-CAH4Y4PY.js} +4 -2
  45. package/dist/chunk-CAT235HY.js +13 -0
  46. package/dist/{chunk-PXKIGZ2F.js → chunk-EATJPSTS.js} +1 -1
  47. package/dist/{chunk-O5RGXTWU.js → chunk-GNSXOTIK.js} +6 -4
  48. package/dist/{chunk-UPRSH6Q4.js → chunk-ICAVVF6D.js} +3 -3
  49. package/dist/{chunk-2ECWEUHP.js → chunk-IJQ767JS.js} +3 -5
  50. package/dist/{chunk-MKMD2HJW.js → chunk-J65N34YM.js} +3 -3
  51. package/dist/{chunk-6U3VLV2C.js → chunk-JIH32RH2.js} +4 -4
  52. package/dist/{chunk-T4DLETKR.js → chunk-K22OLAPC.js} +2 -2
  53. package/dist/{chunk-I2YX3HVD.js → chunk-KRBBH64S.js} +3 -3
  54. package/dist/{chunk-VF4F5WXZ.js → chunk-LBIQ5LTC.js} +1 -1
  55. package/dist/{chunk-WGIDC6QP.js → chunk-LKH44GI3.js} +5 -5
  56. package/dist/{chunk-ZTLMPUO6.js → chunk-LNSF6BJC.js} +1 -1
  57. package/dist/{chunk-WDQB4OXY.js → chunk-M62U7TJF.js} +1 -1
  58. package/dist/{chunk-EDYHROQ7.js → chunk-NFRJTOTB.js} +3 -3
  59. package/dist/chunk-OD2ULW5Z.js +57 -0
  60. package/dist/{chunk-Y6LP36UW.js → chunk-OE3NXEOF.js} +2 -2
  61. package/dist/{chunk-L7U23XI2.js → chunk-OGK7OL3T.js} +5 -4
  62. package/dist/{chunk-RDPW4D33.js → chunk-PD7K54EQ.js} +2 -2
  63. package/dist/{chunk-MVR4FY5R.js → chunk-PIX7FAMX.js} +2 -2
  64. package/dist/{chunk-2AD3CDRR.js → chunk-ROAOI6GG.js} +10 -10
  65. package/dist/{chunk-YJLS6JBI.js → chunk-S7SSYGUJ.js} +6 -5
  66. package/dist/{chunk-ZKHI4E2B.js → chunk-SBPAXWLF.js} +1 -1
  67. package/dist/{chunk-ZHS2XFLV.js → chunk-TOSZGJEQ.js} +1 -1
  68. package/dist/{chunk-4NTBQNHA.js → chunk-TYAVHRWH.js} +80 -81
  69. package/dist/{chunk-Z65DHMTW.js → chunk-TZ5RTANX.js} +3 -3
  70. package/dist/{chunk-VX5CMNMM.js → chunk-UAYAJPEP.js} +7 -1
  71. package/dist/{chunk-4YTYGG2C.js → chunk-URJN75ZG.js} +29 -16
  72. package/dist/{chunk-EPT6FJUY.js → chunk-UUWUAMUC.js} +13 -16
  73. package/dist/{chunk-PKGN32AU.js → chunk-XPTJRVL2.js} +1 -1
  74. package/dist/{chunk-662ILEZ6.js → chunk-Y35BWW2C.js} +3 -7
  75. package/dist/{chunk-MRQ2U4LZ.js → chunk-ZHNQFNO3.js} +2 -2
  76. package/dist/chunk-ZKADJNR2.js +52 -0
  77. package/dist/{chunk-WGG6GTKW.js → chunk-ZLFGXKLG.js} +1 -1
  78. package/dist/client/index.js +6 -5
  79. package/dist/contracts/entries.d.ts +1 -1
  80. package/dist/contracts/sentences.d.ts +46 -0
  81. package/dist/contracts/site-cache.d.ts +2 -0
  82. package/dist/cta-bar/index.js +1 -1
  83. package/dist/fleet/index.js +6 -5
  84. package/dist/forms/field-autocomplete.d.ts +16 -8
  85. package/dist/forms/index.d.ts +5 -0
  86. package/dist/forms/index.js +17 -17
  87. package/dist/forms/server.js +7 -7
  88. package/dist/forms/static.js +2 -2
  89. package/dist/forms/submitForm.d.ts +5 -0
  90. package/dist/images/index.js +4 -4
  91. package/dist/index.d.ts +3 -7
  92. package/dist/index.js +1 -1
  93. package/dist/layout/SiteKitLayout.d.ts +2 -1
  94. package/dist/layout/client.js +11 -9
  95. package/dist/layout/index.js +14 -12
  96. package/dist/llms/index.js +8 -7
  97. package/dist/maps/index.js +6 -6
  98. package/dist/mcp/sonor.d.ts +47 -3
  99. package/dist/mcp/sonor.js +31 -21
  100. package/dist/proxy/index.d.ts +3 -3
  101. package/dist/proxy/index.js +1 -1
  102. package/dist/reputation/TestimonialSection.d.ts +1 -1
  103. package/dist/reputation/VisualReviewCard.d.ts +6 -0
  104. package/dist/reputation/index.d.ts +2 -1
  105. package/dist/reputation/index.js +5 -2
  106. package/dist/reputation/review-photo.d.ts +2 -0
  107. package/dist/reputation/server.d.ts +3 -2
  108. package/dist/reputation/server.js +4 -1
  109. package/dist/reputation/types.d.ts +22 -0
  110. package/dist/revalidate/index.js +3 -3
  111. package/dist/robots/indexnow.js +2 -2
  112. package/dist/runtime/index.d.ts +32 -0
  113. package/dist/runtime/index.js +7 -0
  114. package/dist/seo/api.d.ts +0 -4
  115. package/dist/seo/client.js +6 -5
  116. package/dist/seo/getManagedMetadata.d.ts +24 -0
  117. package/dist/seo/index.d.ts +2 -3
  118. package/dist/seo/index.js +14 -132
  119. package/dist/seo/indexnow.js +2 -2
  120. package/dist/seo/llms.js +8 -7
  121. package/dist/seo/register-sitemap-cli.js +2 -2
  122. package/dist/seo/server-api.d.ts +0 -6
  123. package/dist/seo/server.d.ts +1 -1
  124. package/dist/seo/server.js +4 -4
  125. package/dist/seo/sitemap.js +5 -4
  126. package/dist/seo/types.d.ts +9 -30
  127. package/dist/server/index.d.ts +8 -1
  128. package/dist/server/index.js +5 -4
  129. package/dist/server/mint-site-token.d.ts +1 -13
  130. package/dist/server/server-fetch.d.ts +19 -0
  131. package/dist/server-api-EGOKC7Q3.js +9 -0
  132. package/dist/shared/build-entries.d.ts +21 -9
  133. package/dist/shared/clientApiConfig.d.ts +56 -0
  134. package/dist/shared/fresh-fetch.d.ts +9 -3
  135. package/dist/shared/identity-reader.d.ts +26 -0
  136. package/dist/shared/identity-storage.d.ts +30 -0
  137. package/dist/shared/identity.d.ts +13 -13
  138. package/dist/shared/import-specifiers.d.ts +26 -0
  139. package/dist/shared/sonorFetch.d.ts +4 -3
  140. package/dist/shared/version.d.ts +1 -1
  141. package/dist/signal/index.js +2 -2
  142. package/dist/sitemap/index.js +5 -4
  143. package/dist/slots/index.js +3 -3
  144. package/dist/sync/index.js +6 -5
  145. package/dist/types.d.ts +0 -1
  146. package/dist/website/cta-bar.js +1 -1
  147. package/dist/website/images.js +4 -4
  148. package/dist/website/index.js +7 -6
  149. package/dist/website/popups.js +10 -7
  150. package/dist/website/slots.js +3 -3
  151. package/dist/{writeLLMsTxt-2NQVDGYI.js → writeLLMsTxt-UZGN6IBU.js} +4 -3
  152. package/docs/MIGRATING-TO-7.md +5 -2
  153. package/docs/MIGRATING-TO-8.md +183 -0
  154. package/docs.json +4 -8
  155. package/package.json +15 -44
  156. package/skills/site-kit/SKILL.md +41 -11
  157. package/src/analytics/README.md +14 -14
  158. package/src/chat/README.md +7 -7
  159. package/src/forms/README.md +61 -6
  160. package/src/mcp/README.md +61 -20
  161. package/src/proxy/README.md +5 -4
  162. package/src/reputation/README.md +25 -0
  163. package/src/revalidate/README.md +2 -2
  164. package/src/runtime/README.md +51 -0
  165. package/src/seo/README.md +24 -8
  166. package/src/sync/README.md +2 -2
  167. package/src/website/README.md +3 -2
  168. package/dist/AnalyticsProvider-DJQA66AG.js +0 -11
  169. package/dist/ManagedForm-JRZAJ7SZ.js +0 -16
  170. package/dist/SiteChat-EGEZJJVV.js +0 -5
  171. package/dist/SiteDesignReporter-YEEWJKWN.js +0 -11
  172. package/dist/SitePopups-LQBIXIFV.js +0 -10
  173. package/dist/SitemapSync-LSZ2EYOF.js +0 -8
  174. package/dist/chunk-24QZEO3Q.js +0 -41
  175. package/dist/chunk-BU66S5B7.js +0 -1
  176. package/dist/chunk-G3NHWMP5.js +0 -233
  177. package/dist/chunk-HODO5BX5.js +0 -28
  178. package/dist/chunk-L3AQCDCY.js +0 -386
  179. package/dist/chunk-P5GB6NEO.js +0 -66
  180. package/dist/chunk-SWKE6FWH.js +0 -47
  181. package/dist/cms/CmsPage.d.ts +0 -17
  182. package/dist/cms/CmsPreview.d.ts +0 -37
  183. package/dist/cms/CmsSection.d.ts +0 -8
  184. package/dist/cms/PortableTextRenderer.d.ts +0 -7
  185. package/dist/cms/index.d.ts +0 -37
  186. package/dist/cms/index.js +0 -5
  187. package/dist/cms/sanity-image.d.ts +0 -47
  188. package/dist/cms/sections/CtaSection.d.ts +0 -3
  189. package/dist/cms/sections/CustomSection.d.ts +0 -7
  190. package/dist/cms/sections/FaqSection.d.ts +0 -3
  191. package/dist/cms/sections/FormSection.d.ts +0 -8
  192. package/dist/cms/sections/GallerySection.d.ts +0 -3
  193. package/dist/cms/sections/HeroSection.d.ts +0 -3
  194. package/dist/cms/sections/RichTextSection.d.ts +0 -3
  195. package/dist/cms/sections/TestimonialsSection.d.ts +0 -3
  196. package/dist/cms/sections/index.d.ts +0 -8
  197. package/dist/cms/server-api.d.ts +0 -49
  198. package/dist/cms/server.d.ts +0 -1
  199. package/dist/cms/server.js +0 -5
  200. package/dist/cms/types.d.ts +0 -104
  201. package/dist/commerce/CalendarView.d.ts +0 -43
  202. package/dist/commerce/CheckoutForm.d.ts +0 -11
  203. package/dist/commerce/EventCalendar.d.ts +0 -26
  204. package/dist/commerce/EventCheckout.d.ts +0 -42
  205. package/dist/commerce/EventEmbed.d.ts +0 -11
  206. package/dist/commerce/EventModal.d.ts +0 -43
  207. package/dist/commerce/EventTile.d.ts +0 -10
  208. package/dist/commerce/EventsAgenda.d.ts +0 -38
  209. package/dist/commerce/EventsWidget.d.ts +0 -84
  210. package/dist/commerce/OfferingCard.d.ts +0 -9
  211. package/dist/commerce/OfferingList.d.ts +0 -9
  212. package/dist/commerce/ProductDetail.d.ts +0 -38
  213. package/dist/commerce/ProductEmbed.d.ts +0 -11
  214. package/dist/commerce/ProductGrid.d.ts +0 -41
  215. package/dist/commerce/ProductPage.d.ts +0 -39
  216. package/dist/commerce/RegistrationForm.d.ts +0 -9
  217. package/dist/commerce/SizeChart.d.ts +0 -8
  218. package/dist/commerce/UpcomingEvents.d.ts +0 -9
  219. package/dist/commerce/api.d.ts +0 -179
  220. package/dist/commerce/events-extras.d.ts +0 -60
  221. package/dist/commerce/index.d.ts +0 -33
  222. package/dist/commerce/index.js +0 -8022
  223. package/dist/commerce/server.d.ts +0 -161
  224. package/dist/commerce/server.js +0 -2
  225. package/dist/commerce/types.d.ts +0 -340
  226. package/dist/commerce/useEventModal.d.ts +0 -20
  227. package/dist/commerce/utils.d.ts +0 -17
  228. package/dist/engage/EngageWidget.d.ts +0 -21
  229. package/dist/engage/index.d.ts +0 -14
  230. package/dist/engage/index.js +0 -45
  231. package/dist/engage/types.d.ts +0 -33
  232. package/dist/seo/ManagedContent.d.ts +0 -14
  233. package/dist/server-api-BVCBLJKL.js +0 -9
  234. package/dist/website/cms/server.d.ts +0 -2
  235. package/dist/website/cms/server.js +0 -5
  236. package/dist/website/cms-server.d.ts +0 -2
  237. package/dist/website/cms.d.ts +0 -2
  238. package/dist/website/cms.js +0 -5
  239. package/src/commerce/README.md +0 -109
@@ -8,11 +8,31 @@ export interface Review {
8
8
  role?: string;
9
9
  rating: number;
10
10
  image?: string;
11
+ /** A business-supplied work/property photo. `image` remains the reviewer avatar. */
12
+ photo?: ReviewPhoto | null;
11
13
  date?: string;
12
14
  platform?: string;
13
15
  isFeatured?: boolean;
14
16
  serviceTags?: string[];
15
17
  }
18
+ export interface ReviewPhoto {
19
+ fileId: string;
20
+ url: string;
21
+ altText: string;
22
+ caption: string;
23
+ }
24
+ export interface VisualReviewCardProps {
25
+ review: Review;
26
+ showRating?: boolean;
27
+ className?: string;
28
+ }
29
+ export interface VisualReviewGalleryProps {
30
+ reviews: Review[];
31
+ title?: string;
32
+ subtitle?: string;
33
+ showRating?: boolean;
34
+ className?: string;
35
+ }
16
36
  export interface ReviewStats {
17
37
  total_reviews: number;
18
38
  average_rating: number;
@@ -30,6 +50,8 @@ export interface TestimonialSectionProps {
30
50
  autoplay?: boolean;
31
51
  autoplayInterval?: number;
32
52
  showRating?: boolean;
53
+ /** Show attached business photos above the quote. Defaults to true. */
54
+ showPhoto?: boolean;
33
55
  maxReviews?: number;
34
56
  featuredOnly?: boolean;
35
57
  service?: string;
@@ -1,7 +1,7 @@
1
- import { createSeoRevalidationHandler } from '../chunk-NI2XNEMR.js';
1
+ import { createSeoRevalidationHandler } from '../chunk-7YEEOIWI.js';
2
2
  import '../chunk-XTRZGXB2.js';
3
- export { SITE_CACHE_TAGS, SITE_REVALIDATE_PATH, isSiteRevalidatePong } from '../chunk-RYVDGXC2.js';
4
- import '../chunk-56KNHB4U.js';
3
+ export { SITE_CACHE_TAGS, SITE_REVALIDATE_PATH, isSiteRevalidatePong } from '../chunk-6KU7STM3.js';
4
+ import '../chunk-5S2XDG5O.js';
5
5
  import '../chunk-PKBMQBKP.js';
6
6
 
7
7
  // src/revalidate/index.ts
@@ -1,4 +1,4 @@
1
- export { GET, INDEXNOW_KEY_PATH, createIndexNowKeyRoute, fetchIndexNowKey } from '../chunk-PXKIGZ2F.js';
2
- import '../chunk-X6F6SO4S.js';
1
+ export { GET, INDEXNOW_KEY_PATH, createIndexNowKeyRoute, fetchIndexNowKey } from '../chunk-EATJPSTS.js';
2
+ import '../chunk-C7TLGL3R.js';
3
3
  import '../chunk-MH2DSGC6.js';
4
4
  import '../chunk-PKBMQBKP.js';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @sonordev/site-kit/runtime — how a package that builds on site-kit talks to
3
+ * Sonor from the browser, without carrying a transport of its own.
4
+ *
5
+ * `@sonordev/commerce-kit` is built on this entry, and any other kit should
6
+ * be: the credential lifecycle (short-lived site tokens, refreshed once on an
7
+ * authentication failure), retries with a timeout, the auth circuit breaker
8
+ * and the one reader of the API origin the layout publishes all live in
9
+ * site-kit, so a kit that goes through here gets every fix site-kit ships.
10
+ * The visitor's analytics ids come from here too (`readAnalyticsIdentity`),
11
+ * read-only, so a kit can attribute what it sends without knowing where
12
+ * site-kit keeps them.
13
+ *
14
+ * Deliberately NOT stamped `'use client'` and free of React, Next and
15
+ * `server-only`: it is imported from client components and server code alike
16
+ * (`getClientApiConfig` is built to run during server rendering), and a
17
+ * function exported from a stamped entry can't be called from a server
18
+ * component. `@sonordev/site-kit/client` is stamped, which is why this isn't
19
+ * part of it. src/shared/client-entry-boundary.test.ts and tsup.config.ts
20
+ * keep it that way (ISOMORPHIC_ENTRIES in src/shared/build-entries.ts).
21
+ *
22
+ * Stable public surface, covered by semver: runtime/index.test.ts pins the
23
+ * exact list of exports, so adding or removing one is a deliberate change.
24
+ * See README.md.
25
+ */
26
+ export { sonorFetch } from '../shared/sonorFetch';
27
+ export type { SonorFetchOptions } from '../shared/sonorFetch';
28
+ export type { FetchRetryOptions } from '../shared/fetchWithRetry';
29
+ export { getClientApiConfig, readPublishedApiConfig, DEFAULT_SONOR_API_URL } from '../shared/clientApiConfig';
30
+ export type { ClientApiConfigOptions } from '../shared/clientApiConfig';
31
+ export { readAnalyticsIdentity } from '../shared/identity-reader';
32
+ export type { AnalyticsIdentity } from '../shared/identity-reader';
@@ -0,0 +1,7 @@
1
+ export { readAnalyticsIdentity } from '../chunk-5ROTTMBL.js';
2
+ import '../chunk-5TM3WPCI.js';
3
+ export { DEFAULT_SONOR_API_URL, getClientApiConfig, readPublishedApiConfig } from '../chunk-3G7YABRA.js';
4
+ export { sonorFetch } from '../chunk-56VDS2RP.js';
5
+ import '../chunk-ZLFGXKLG.js';
6
+ import '../chunk-5S2XDG5O.js';
7
+ import '../chunk-PKBMQBKP.js';
package/dist/seo/api.d.ts CHANGED
@@ -32,10 +32,6 @@ export declare const getInternalLinks: (projectId: string, sourcePath: string, o
32
32
  position?: string;
33
33
  limit?: number;
34
34
  }) => Promise<any[]>;
35
- /**
36
- * Fetch content block - cached per request
37
- */
38
- export declare const getContentBlock: (projectId: string, path: string, section: string) => Promise<any>;
39
35
  /**
40
36
  * Fetch A/B test and determine variant - cached per request
41
37
  */
@@ -1,9 +1,10 @@
1
1
  'use client';
2
- export { SitemapSync } from '../chunk-T4DLETKR.js';
2
+ export { SitemapSync } from '../chunk-K22OLAPC.js';
3
3
  import '../chunk-YVKRYQRG.js';
4
- import '../chunk-43OCZ3JA.js';
4
+ import '../chunk-CAH4Y4PY.js';
5
5
  import '../chunk-EKBEOXTH.js';
6
- import '../chunk-BEBR4OJD.js';
7
- import '../chunk-WGG6GTKW.js';
8
- import '../chunk-56KNHB4U.js';
6
+ import '../chunk-3G7YABRA.js';
7
+ import '../chunk-56VDS2RP.js';
8
+ import '../chunk-ZLFGXKLG.js';
9
+ import '../chunk-5S2XDG5O.js';
9
10
  import '../chunk-PKBMQBKP.js';
@@ -1,4 +1,27 @@
1
+ import type { Metadata } from 'next';
1
2
  import type { GetManagedMetadataOptions, ManagedMetadataResult, GetABVariantOptions, ABTestResult } from './types';
3
+ /**
4
+ * The canonical every page gets when nobody says otherwise: itself.
5
+ *
6
+ * Relative on purpose. Next resolves './' against `metadataBase` AND the route
7
+ * being rendered, so one value is right in a page and also in a root layout,
8
+ * whose metadata every page beneath it inherits. An absolute canonical built
9
+ * from `path` is wrong in exactly that second case: a layout that asks for '/'
10
+ * stamps the homepage on every inner page, telling search engines each one is
11
+ * a copy of it. A site that sets nothing ships no canonical at all.
12
+ *
13
+ * Without a `metadataBase` Next emits the path alone ('/privacy'), which is
14
+ * still a valid canonical; with one it is absolute.
15
+ */
16
+ export declare const SELF_CANONICAL = "./";
17
+ type Alternates = NonNullable<Metadata['alternates']>;
18
+ /**
19
+ * Merge alternates key by key, later parts winning, so a page that supplies
20
+ * only `languages` keeps its canonical and one that supplies a canonical (or
21
+ * `null`, to opt out) replaces the default. Next replaces the whole
22
+ * `alternates` object otherwise.
23
+ */
24
+ export declare function mergeAlternates(...parts: Array<Metadata['alternates'] | undefined>): Alternates;
2
25
  /**
3
26
  * Get managed metadata for a page
4
27
  *
@@ -43,3 +66,4 @@ export declare function getABVariant(options: GetABVariantOptions): Promise<ABTe
43
66
  export declare function getManagedMetadataWithAB(options: GetManagedMetadataOptions & {
44
67
  sessionId?: string;
45
68
  }): Promise<ManagedMetadataResult>;
69
+ export {};
@@ -1,13 +1,12 @@
1
- export type { SonorSEOConfig, SEOPageData, GetManagedMetadataOptions, ManagedMetadataResult, SchemaMarkup, ManagedSchemaProps, FAQItem, ManagedFAQData, ManagedFAQProps, ManagedLink, ManagedInternalLinksProps, ManagedContentBlock, ManagedContentProps, ABTest, ABTestResult, GetABVariantOptions, ManagedRedirect, GetRedirectOptions, RedirectResult, ManagedScript, ManagedScriptsProps, RobotsDirective, GetRobotsOptions, SitemapEntry, GetSitemapEntriesOptions, } from './types';
1
+ export type { SonorSEOConfig, SEOPageData, GetManagedMetadataOptions, ManagedMetadataResult, SchemaMarkup, ManagedSchemaProps, FAQItem, ManagedFAQData, ManagedFAQProps, ManagedLink, ManagedInternalLinksProps, ABTest, ABTestResult, GetABVariantOptions, ManagedRedirect, GetRedirectOptions, RedirectResult, ManagedScript, ManagedScriptsProps, RobotsDirective, GetRobotsOptions, SitemapEntry, GetSitemapEntriesOptions, } from './types';
2
2
  export type { EntityType, SEOEntity, PageSeoContext, } from './server-api';
3
3
  export { getManagedMetadata, getManagedMetadataWithAB, getABVariant, } from './getManagedMetadata';
4
4
  export { withManagedMetadata } from './withManagedMetadata';
5
5
  export { getRedirect, getRobotsDirective, generateSitemap, isIndexable, } from './routing';
6
- export { getSEOPageData, getSchemaMarkups, getFAQData, getInternalLinks, getContentBlock, getABTest, recordABImpression, getRedirectData, getManagedScripts, getRobotsData, getSitemapEntries, registerSitemap, getEntities, getPrimaryEntity, getEntityEnhancedSchema, getVisibilityScore, getVisibilitySummary, } from './server-api';
6
+ export { getSEOPageData, getSchemaMarkups, getFAQData, getInternalLinks, getABTest, recordABImpression, getRedirectData, getManagedScripts, getRobotsData, getSitemapEntries, registerSitemap, getEntities, getPrimaryEntity, getEntityEnhancedSchema, getVisibilityScore, getVisibilitySummary, } from './server-api';
7
7
  export { ManagedSchema, LLMSchema, createSchema, createBreadcrumbSchema } from './ManagedSchema';
8
8
  export { createWebSiteOrganizationStub } from './groundingSchema';
9
9
  export { ManagedFAQ } from './ManagedFAQ';
10
10
  export { ManagedInternalLinks } from './ManagedInternalLinks';
11
- export { ManagedContent, getManagedContentData } from './ManagedContent';
12
11
  export { ManagedScripts, ManagedNoScripts } from './ManagedScripts';
13
12
  export { SitemapSync } from '../SitemapSync';
package/dist/seo/index.js CHANGED
@@ -2,25 +2,26 @@ export { ManagedNoScripts, ManagedScripts } from '../chunk-MVLMXC44.js';
2
2
  import { pickManagedLlmSchemaForJsonLd } from '../chunk-NZ4RXN3G.js';
3
3
  import { safeJsonLd } from '../chunk-4KZ6W3ZH.js';
4
4
  import { withoutSchemaPlaceholders } from '../chunk-VWWITFWM.js';
5
- export { SitemapSync } from '../chunk-T4DLETKR.js';
6
- import { getManagedMetadata } from '../chunk-4YTYGG2C.js';
7
- export { generateSitemap, getABVariant, getManagedMetadata, getManagedMetadataWithAB, getRedirect, getRobotsDirective, isIndexable } from '../chunk-4YTYGG2C.js';
8
- import { getContentBlock, getSchemaMarkups, getSEOPageData, getEntityEnhancedSchema, getFAQData, getInternalLinks, getEntities, pruneSchemaTypes } from '../chunk-662ILEZ6.js';
9
- export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from '../chunk-662ILEZ6.js';
5
+ export { SitemapSync } from '../chunk-K22OLAPC.js';
6
+ import { getManagedMetadata, mergeAlternates } from '../chunk-URJN75ZG.js';
7
+ export { generateSitemap, getABVariant, getManagedMetadata, getManagedMetadataWithAB, getRedirect, getRobotsDirective, isIndexable } from '../chunk-URJN75ZG.js';
8
+ import { getSchemaMarkups, getSEOPageData, getEntityEnhancedSchema, getFAQData, getInternalLinks, pruneSchemaTypes } from '../chunk-Y35BWW2C.js';
9
+ export { getABTest, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from '../chunk-Y35BWW2C.js';
10
10
  import '../chunk-BQR4IPBW.js';
11
- import '../chunk-RYVDGXC2.js';
12
11
  import '../chunk-MJP63SSS.js';
13
- import '../chunk-X6F6SO4S.js';
12
+ import '../chunk-6KU7STM3.js';
13
+ import '../chunk-C7TLGL3R.js';
14
14
  import '../chunk-MH2DSGC6.js';
15
15
  import '../chunk-YVKRYQRG.js';
16
16
  import '../chunk-DIKNRN34.js';
17
17
  import '../chunk-FESKKJAS.js';
18
18
  import '../chunk-A4CC4ZG3.js';
19
- import '../chunk-43OCZ3JA.js';
19
+ import '../chunk-CAH4Y4PY.js';
20
20
  import '../chunk-EKBEOXTH.js';
21
- import '../chunk-BEBR4OJD.js';
22
- import '../chunk-WGG6GTKW.js';
23
- import '../chunk-56KNHB4U.js';
21
+ import '../chunk-3G7YABRA.js';
22
+ import '../chunk-56VDS2RP.js';
23
+ import '../chunk-ZLFGXKLG.js';
24
+ import '../chunk-5S2XDG5O.js';
24
25
  import '../chunk-PKBMQBKP.js';
25
26
  import { Suspense } from 'react';
26
27
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -37,6 +38,7 @@ function withManagedMetadata(path, pageMetadata) {
37
38
  return {
38
39
  ...managed,
39
40
  ...pageSpecific,
41
+ alternates: mergeAlternates(managed.alternates, pageSpecific.alternates),
40
42
  openGraph: {
41
43
  ...managed.openGraph,
42
44
  ...pageSpecific.openGraph
@@ -475,125 +477,5 @@ async function ManagedInternalLinksAsync({
475
477
  function ManagedInternalLinks(props) {
476
478
  return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ManagedInternalLinksAsync, { ...props }) });
477
479
  }
478
- function renderMarkdown(content) {
479
- return content.replace(/^### (.*$)/gim, "<h3>$1</h3>").replace(/^## (.*$)/gim, "<h2>$1</h2>").replace(/^# (.*$)/gim, "<h1>$1</h1>").replace(/\*\*(.*)\*\*/gim, "<strong>$1</strong>").replace(/\*(.*)\*/gim, "<em>$1</em>").replace(/\[(.*?)\]\((.*?)\)/gim, '<a href="$2">$1</a>').replace(/\n\n/gim, "</p><p>").replace(/^(.+)$/gim, "<p>$1</p>");
480
- }
481
- function injectEntityAnnotations(html, entities) {
482
- if (!entities.length) return html;
483
- let annotatedHtml = html;
484
- const sortedEntities = [...entities].sort((a, b) => b.name.length - a.name.length);
485
- for (const entity of sortedEntities) {
486
- if (entity.name.length < 3) continue;
487
- const regex = new RegExp(
488
- `(?<![\\w-])(?<!data-sonor-entity=")${escapeRegExp(entity.name)}(?![\\w-])`,
489
- "gi"
490
- );
491
- const schemaType = getSchemaTypeForEntity(entity.entity_type);
492
- annotatedHtml = annotatedHtml.replace(regex, (match) => {
493
- return `<span class="aeo-entity aeo-entity-${entity.entity_type}" data-sonor-entity="${entity.id}" data-sonor-entity-type="${entity.entity_type}" data-sonor-entity-name="${entity.name}" itemscope itemtype="https://schema.org/${schemaType}"><span itemprop="name">${match}</span></span>`;
494
- });
495
- }
496
- return annotatedHtml;
497
- }
498
- function escapeRegExp(string) {
499
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
500
- }
501
- function getSchemaTypeForEntity(entityType) {
502
- const typeMap = {
503
- organization: "Organization",
504
- person: "Person",
505
- service: "Service",
506
- product: "Product",
507
- location: "Place",
508
- concept: "Thing",
509
- credential: "EducationalOccupationalCredential"
510
- };
511
- return typeMap[entityType] || "Thing";
512
- }
513
- async function ManagedContentAsync({
514
- path,
515
- section,
516
- fallback,
517
- className,
518
- components = {},
519
- injectEntityAnnotations: shouldInjectEntities = false,
520
- site
521
- }) {
522
- const block = await getContentBlock(path, section, site);
523
- if (!block) {
524
- if (fallback) {
525
- return /* @__PURE__ */ jsx(Fragment, { children: fallback });
526
- }
527
- return null;
528
- }
529
- let entities = [];
530
- if (shouldInjectEntities) {
531
- try {
532
- entities = await getEntities();
533
- } catch (err) {
534
- console.warn("@sonordev/seo: Failed to fetch entities for annotation:", err);
535
- }
536
- }
537
- const containerClass = className || `sk-content sk-content--${section}`;
538
- const processHtml = (html) => {
539
- if (shouldInjectEntities && entities.length > 0) {
540
- return injectEntityAnnotations(html, entities);
541
- }
542
- return html;
543
- };
544
- switch (block.content_type) {
545
- case "html":
546
- return /* @__PURE__ */ jsx(
547
- "div",
548
- {
549
- className: containerClass,
550
- dangerouslySetInnerHTML: { __html: processHtml(block.content) }
551
- }
552
- );
553
- case "markdown":
554
- const htmlContent = processHtml(renderMarkdown(block.content));
555
- return /* @__PURE__ */ jsx(
556
- "div",
557
- {
558
- className: containerClass,
559
- dangerouslySetInnerHTML: { __html: htmlContent }
560
- }
561
- );
562
- case "json":
563
- const jsonData = typeof block.content === "string" ? JSON.parse(block.content) : block.content;
564
- return /* @__PURE__ */ jsxs(
565
- "div",
566
- {
567
- className: containerClass,
568
- "data-content": JSON.stringify(jsonData),
569
- children: [
570
- jsonData.title && /* @__PURE__ */ jsx("h2", { children: jsonData.title }),
571
- jsonData.subtitle && /* @__PURE__ */ jsx("p", { className: "subtitle", children: jsonData.subtitle }),
572
- jsonData.content && /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: jsonData.content } }),
573
- jsonData.items && /* @__PURE__ */ jsx("ul", { children: jsonData.items.map((item, index) => /* @__PURE__ */ jsx("li", { children: typeof item === "string" ? item : item.text }, index)) })
574
- ]
575
- }
576
- );
577
- case "react":
578
- const componentData = typeof block.content === "string" ? JSON.parse(block.content) : block.content;
579
- const componentName = componentData.component;
580
- const componentProps = componentData.props || {};
581
- const Component = components[componentName];
582
- if (!Component) {
583
- console.warn(`@sonordev/seo: Component "${componentName}" not found in components map`);
584
- return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
585
- }
586
- return /* @__PURE__ */ jsx("div", { className: containerClass, children: /* @__PURE__ */ jsx(Component, { ...componentProps }) });
587
- default:
588
- console.warn(`@sonordev/seo: Unknown content type "${block.content_type}"`);
589
- return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
590
- }
591
- }
592
- async function getManagedContentData(path, section, site) {
593
- return getContentBlock(path, section, site);
594
- }
595
- function ManagedContent(props) {
596
- return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ManagedContentAsync, { ...props }) });
597
- }
598
480
 
599
- export { LLMSchema, ManagedContent, ManagedFAQ, ManagedInternalLinks, ManagedSchema, createBreadcrumbSchema, createSchema, createWebSiteOrganizationStub, getManagedContentData, withManagedMetadata };
481
+ export { LLMSchema, ManagedFAQ, ManagedInternalLinks, ManagedSchema, createBreadcrumbSchema, createSchema, createWebSiteOrganizationStub, withManagedMetadata };
@@ -1,4 +1,4 @@
1
- export { GET, INDEXNOW_KEY_PATH, createIndexNowKeyRoute, fetchIndexNowKey } from '../chunk-PXKIGZ2F.js';
2
- import '../chunk-X6F6SO4S.js';
1
+ export { GET, INDEXNOW_KEY_PATH, createIndexNowKeyRoute, fetchIndexNowKey } from '../chunk-EATJPSTS.js';
2
+ import '../chunk-C7TLGL3R.js';
3
3
  import '../chunk-MH2DSGC6.js';
4
4
  import '../chunk-PKBMQBKP.js';
package/dist/seo/llms.js CHANGED
@@ -1,19 +1,20 @@
1
- export { createLLMsFullTxtHandler, createLLMsTxtHandler, formatSourcedFactsSection, llmsResponseHeaders } from '../chunk-WDQB4OXY.js';
1
+ export { createLLMsFullTxtHandler, createLLMsTxtHandler, formatSourcedFactsSection, llmsResponseHeaders } from '../chunk-M62U7TJF.js';
2
2
  export { buildAiDiscoveryHeaders, wantsLlmsDiscoveryLink } from '../chunk-PO2TRJPY.js';
3
3
  export { AI_RETRIEVAL_CRAWLERS, AI_TRAINING_CRAWLERS, buildAiCrawlerRules, createRobotsTxtHandler } from '../chunk-QLTDFUJ7.js';
4
- export { LEGACY_PUBLICATION_PATH, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, createLlmsRevalidateHandler, createSeoRevalidationHandler, parseSeoRevalidationPayload } from '../chunk-NI2XNEMR.js';
5
- import '../chunk-XTRZGXB2.js';
4
+ export { LEGACY_PUBLICATION_PATH, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, createLlmsRevalidateHandler, createSeoRevalidationHandler, parseSeoRevalidationPayload } from '../chunk-7YEEOIWI.js';
6
5
  export { AEOBlock, AEOCitedContent, AEOClaim, AEOComparison, AEODefinition, AEOEntity, AEOProvenanceList, AEOStep, AEOSteps, AEOSummary, DEFAULT_SPEAKABLE_SELECTORS, SpeakableSchema, createSpeakableSchema, getSpeakableSelectorsForPage } from '../chunk-PSAG45YF.js';
7
- export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-Z65DHMTW.js';
8
- export { getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices } from '../chunk-6U3VLV2C.js';
6
+ import '../chunk-XTRZGXB2.js';
7
+ export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-TZ5RTANX.js';
8
+ export { getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices } from '../chunk-JIH32RH2.js';
9
9
  import '../chunk-L5UOHS6E.js';
10
10
  import '../chunk-WMVK77ND.js';
11
- import '../chunk-VX5CMNMM.js';
11
+ import '../chunk-UAYAJPEP.js';
12
12
  export { LLMS_DISCLAIMER_MAX_LENGTH, LLMS_PUBLIC_SUMMARY_MAX_LENGTH, LLM_GEO_CONTRACT_VERSION, MANAGED_LLM_SCHEMA_KNOWN_KEYS, pickManagedLlmSchemaForJsonLd, sanitizeLlmsDisclaimerLine, sanitizeLlmsPublicSummary, sanitizePrimaryLanguageTag } from '../chunk-NZ4RXN3G.js';
13
13
  import '../chunk-4KZ6W3ZH.js';
14
14
  import '../chunk-MJP63SSS.js';
15
15
  import '../chunk-YVKRYQRG.js';
16
16
  import '../chunk-FESKKJAS.js';
17
17
  import '../chunk-A4CC4ZG3.js';
18
- import '../chunk-56KNHB4U.js';
18
+ import '../chunk-3G7YABRA.js';
19
+ import '../chunk-5S2XDG5O.js';
19
20
  import '../chunk-PKBMQBKP.js';
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ import { HEX_COLOR, colorLuminance, DARK_LUMINANCE } from '../chunk-S22FSH7C.js';
2
3
  import { findSitemapRoute, findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-ZEGVKVD5.js';
3
4
  import { inferPageType } from '../chunk-YVKRYQRG.js';
4
5
  import { resolveSyncSite, postRegisterSitemap } from '../chunk-DIKNRN34.js';
5
6
  import '../chunk-FESKKJAS.js';
6
7
  import '../chunk-A4CC4ZG3.js';
7
- import { HEX_COLOR, colorLuminance, DARK_LUMINANCE } from '../chunk-S22FSH7C.js';
8
8
  import '../chunk-PKBMQBKP.js';
9
9
  import fs, { existsSync, readFileSync } from 'fs';
10
10
  import path2 from 'path';
@@ -458,7 +458,7 @@ async function registerLocalSitemap(options) {
458
458
  }
459
459
  if (options.writeLlms && result.success) {
460
460
  try {
461
- const { writeLLMsTxtToPublic } = await import('../writeLLMsTxt-2NQVDGYI.js');
461
+ const { writeLLMsTxtToPublic } = await import('../writeLLMsTxt-UZGN6IBU.js');
462
462
  const written = await writeLLMsTxtToPublic({
463
463
  // Resolved here too: the sync's own `site` is scoped to the branch that
464
464
  // posts, and this runs on the skip path as well.
@@ -61,12 +61,6 @@ export declare const getInternalLinks: (sourcePath: string, options?: {
61
61
  limit?: number;
62
62
  site?: string;
63
63
  }) => Promise<any[]>;
64
- /**
65
- * Fetch content block - cached per request
66
- * @param site Sub-site host override; resolves from NEXT_PUBLIC_SITE_URL when omitted
67
- * @server-only
68
- */
69
- export declare const getContentBlock: (path: string, section: string, site?: string) => Promise<any>;
70
64
  /**
71
65
  * Fetch A/B test and determine variant - cached per request
72
66
  * @server-only
@@ -1,4 +1,4 @@
1
- export { getSEOPageData, getSchemaMarkups, getFAQData, getInternalLinks, getContentBlock, getABTest, recordABImpression, getRedirectData, getManagedScripts, getRobotsData, getSitemapEntries, registerSitemap, } from './server-api';
1
+ export { getSEOPageData, getSchemaMarkups, getFAQData, getInternalLinks, getABTest, recordABImpression, getRedirectData, getManagedScripts, getRobotsData, getSitemapEntries, registerSitemap, } from './server-api';
2
2
  export { getManagedMetadata, getManagedMetadataWithAB, } from './getManagedMetadata';
3
3
  export { generateSitemap, registerLocalSitemap, } from './routing';
4
4
  export type * from './types';
@@ -1,9 +1,9 @@
1
- export { generateSitemap, getManagedMetadata, getManagedMetadataWithAB, registerLocalSitemap } from '../chunk-4YTYGG2C.js';
2
- export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap } from '../chunk-662ILEZ6.js';
1
+ export { generateSitemap, getManagedMetadata, getManagedMetadataWithAB, registerLocalSitemap } from '../chunk-URJN75ZG.js';
2
+ export { getABTest, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap } from '../chunk-Y35BWW2C.js';
3
3
  import '../chunk-BQR4IPBW.js';
4
- import '../chunk-RYVDGXC2.js';
5
4
  import '../chunk-MJP63SSS.js';
6
- import '../chunk-X6F6SO4S.js';
5
+ import '../chunk-6KU7STM3.js';
6
+ import '../chunk-C7TLGL3R.js';
7
7
  import '../chunk-MH2DSGC6.js';
8
8
  import '../chunk-DIKNRN34.js';
9
9
  import '../chunk-FESKKJAS.js';
@@ -1,10 +1,10 @@
1
- export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-Y6LP36UW.js';
1
+ export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-OE3NXEOF.js';
2
+ import '../chunk-TZ5RTANX.js';
3
+ import '../chunk-JIH32RH2.js';
2
4
  import '../chunk-Z22QVHT4.js';
3
- import '../chunk-Z65DHMTW.js';
4
- import '../chunk-6U3VLV2C.js';
5
5
  import '../chunk-L5UOHS6E.js';
6
6
  import '../chunk-WMVK77ND.js';
7
- import '../chunk-VX5CMNMM.js';
7
+ import '../chunk-UAYAJPEP.js';
8
8
  import '../chunk-NZ4RXN3G.js';
9
9
  import '../chunk-MJP63SSS.js';
10
10
  import '../chunk-ZEGVKVD5.js';
@@ -12,4 +12,5 @@ import '../chunk-YVKRYQRG.js';
12
12
  import '../chunk-DIKNRN34.js';
13
13
  import '../chunk-FESKKJAS.js';
14
14
  import '../chunk-A4CC4ZG3.js';
15
+ import '../chunk-3G7YABRA.js';
15
16
  import '../chunk-PKBMQBKP.js';
@@ -43,6 +43,15 @@ export interface GetManagedMetadataOptions {
43
43
  * Default: 'metadata' (icons included from project logo_url).
44
44
  */
45
45
  favicon?: 'metadata' | 'component';
46
+ /**
47
+ * Where this call lives. 'page' (default): Sonor's managed canonical and
48
+ * hreflang for `path` apply. 'layout': pass this when calling from a root or
49
+ * shared layout, whose metadata every route beneath it inherits; the page
50
+ * then gets the self-referencing default canonical and nothing path-specific.
51
+ * Either way a page with no managed canonical gets `alternates.canonical: './'`
52
+ * (its own URL, resolved against `metadataBase`).
53
+ */
54
+ scope?: 'page' | 'layout';
46
55
  }
47
56
  export interface ManagedMetadataResult extends Metadata {
48
57
  _managed: boolean;
@@ -143,36 +152,6 @@ export interface ManagedInternalLinksProps {
143
152
  */
144
153
  site?: string;
145
154
  }
146
- export interface ManagedContentBlock {
147
- id: string;
148
- project_id: string;
149
- path: string;
150
- section: string;
151
- content_type: 'html' | 'markdown' | 'json' | 'react';
152
- content: string | Record<string, unknown>;
153
- is_published: boolean;
154
- published_at?: string;
155
- updated_at: string;
156
- }
157
- export interface ManagedContentProps {
158
- /** @deprecated Project is resolved from API key by the portal */
159
- projectId?: string;
160
- path: string;
161
- section: string;
162
- /** Fallback content if none found */
163
- fallback?: React.ReactNode;
164
- className?: string;
165
- /** For 'react' type, map of component names to components */
166
- components?: Record<string, React.ComponentType<unknown>>;
167
- /** Inject entity annotations from knowledge graph (data-sonor-entity attributes) */
168
- injectEntityAnnotations?: boolean;
169
- /**
170
- * Sub-site host for multi-site projects (e.g. `charlotte.example.com`): shows that
171
- * host's block, falling back to a project-wide one. Omit to resolve from
172
- * NEXT_PUBLIC_SITE_URL.
173
- */
174
- site?: string;
175
- }
176
155
  /**
177
156
  * Entity from the knowledge graph (for content annotation)
178
157
  */
@@ -8,7 +8,14 @@
8
8
  *
9
9
  * Server-only — see `./server-fetch`. Never import into a client component.
10
10
  */
11
- export { resolveServerApiConfig, requireServerApiConfig, resolveApiOrigin, serverApiFetch, } from './server-fetch';
11
+ export { resolveServerApiConfig, requireServerApiConfig, resolveApiOrigin, serverApiFetch, isNextControlFlow, } from './server-fetch';
12
+ /**
13
+ * The cache tags Sonor expires through the site's revalidation route. Tag a
14
+ * `serverApiFetch` with the one for your content (`tags: [SITE_CACHE_TAGS.commerce]`)
15
+ * and an edit in Sonor refreshes it. Never spell a tag as a string.
16
+ */
17
+ export { SITE_CACHE_TAGS } from '../contracts/site-cache';
18
+ export type { SiteCacheTag } from '../contracts/site-cache';
12
19
  export type { ServerApiConfig, ResolveServerApiConfigOptions, ServerFetchOptions, } from './server-fetch';
13
20
  /**
14
21
  * Mint a short-lived, project-scoped client token from the raw `SONOR_API_KEY`,
@@ -1,6 +1,7 @@
1
- export { resolveClientCredential } from '../chunk-DNPNYWVL.js';
2
- import '../chunk-VX5CMNMM.js';
3
- export { requireServerApiConfig, resolveApiOrigin, resolveServerApiConfig, serverApiFetch } from '../chunk-X6F6SO4S.js';
1
+ export { resolveClientCredential } from '../chunk-BQ2CXKTQ.js';
2
+ import '../chunk-UAYAJPEP.js';
3
+ export { SITE_CACHE_TAGS } from '../chunk-6KU7STM3.js';
4
+ export { isNextControlFlow, requireServerApiConfig, resolveApiOrigin, resolveServerApiConfig, serverApiFetch } from '../chunk-C7TLGL3R.js';
4
5
  import '../chunk-MH2DSGC6.js';
5
- import '../chunk-56KNHB4U.js';
6
+ import '../chunk-5S2XDG5O.js';
6
7
  import '../chunk-PKBMQBKP.js';
@@ -39,17 +39,5 @@
39
39
  * realistic redeploy gap; marketing sites routinely go many months untouched.
40
40
  */
41
41
  import 'server-only';
42
- import { resolveFetch } from '../shared/fresh-fetch';
43
- export { resolveFetch };
44
- /**
45
- * Next signals "this render must go dynamic" by THROWING (DynamicServerError,
46
- * static-gen bailout, redirect/notFound digests, React's postpone). Those are
47
- * the framework's control flow, not a mint failure. Swallowing one makes Next
48
- * believe the render succeeded statically — which is precisely how the raw key
49
- * ended up stranded in prerendered HTML with no error anywhere. Let them
50
- * propagate; only real network/HTTP failures fall back to the raw key.
51
- *
52
- * @internal Exported for unit tests; not part of the package's public API.
53
- */
54
- export declare function isFrameworkSignal(err: unknown): boolean;
42
+ export { resolveFetch } from '../shared/fresh-fetch';
55
43
  export declare function resolveClientCredential(rawKey: string, apiUrl: string): Promise<string>;
@@ -51,6 +51,22 @@ export declare function requireServerApiConfig(options?: ResolveServerApiConfigO
51
51
  * the origin-resolution logic lives in one place.
52
52
  */
53
53
  export declare function resolveApiOrigin(apiUrl?: string): string;
54
+ /**
55
+ * True for an error Next throws to steer rendering rather than to report a
56
+ * failure: the dynamic-usage bailout an uncached fetch raises while a route
57
+ * is prerendered, `redirect()`, `notFound()` and the other `NEXT_*` signals,
58
+ * a postponed or interrupted prerender. Rethrow these. Caught, "render this
59
+ * route at request time" becomes "prerender it with no data", which reads
60
+ * as a failed fetch on every build and caches the empty page.
61
+ *
62
+ * Single source of truth for this check across site-kit and the kits built
63
+ * on it (serverApiFetch, the credential mint, commerce-kit). It mirrors
64
+ * Next's `unstable_rethrow` (including the `cause` chain), plus the
65
+ * static-generation bailout `dynamic = 'error'` raises, without importing
66
+ * Next into the data plane; server-fetch.test.ts checks it against the
67
+ * errors the installed Next throws.
68
+ */
69
+ export declare function isNextControlFlow(error: unknown): boolean;
54
70
  export interface ServerFetchOptions {
55
71
  /** HTTP method. Defaults to 'GET'. */
56
72
  method?: string;
@@ -110,5 +126,8 @@ export interface ServerFetchOptions {
110
126
  * - Optional retry/backoff on transient failures (default on)
111
127
  * - Returns null on failure (or missing key, unless `requireKey`) instead of
112
128
  * throwing, so a single bad fetch never crashes a render.
129
+ * - Lets Next's own control-flow errors through ({@link isNextControlFlow}),
130
+ * so a route that turns dynamic renders at request time instead of
131
+ * prerendering with nothing.
113
132
  */
114
133
  export declare function serverApiFetch<T>(path: string, options?: ServerFetchOptions): Promise<T | null>;
@@ -0,0 +1,9 @@
1
+ export { ensureMetadata, getABTest, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-Y35BWW2C.js';
2
+ import './chunk-MJP63SSS.js';
3
+ import './chunk-6KU7STM3.js';
4
+ import './chunk-C7TLGL3R.js';
5
+ import './chunk-MH2DSGC6.js';
6
+ import './chunk-DIKNRN34.js';
7
+ import './chunk-FESKKJAS.js';
8
+ import './chunk-A4CC4ZG3.js';
9
+ import './chunk-PKBMQBKP.js';