@sonordev/site-kit 5.3.1 → 5.4.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.
- package/README.md +17 -0
- package/agent-manifest.json +5 -4
- package/dist/AnalyticsProvider-2XIOMRCN.mjs +11 -0
- package/dist/{AnalyticsProvider-NA7EMJCA.mjs.map → AnalyticsProvider-2XIOMRCN.mjs.map} +1 -1
- package/dist/AnalyticsProvider-Y2P2BPOI.js +32 -0
- package/dist/{AnalyticsProvider-XE3ADUUH.js.map → AnalyticsProvider-Y2P2BPOI.js.map} +1 -1
- package/dist/{BlogViewTracker-DVJHZ7CM.js → BlogViewTracker-6EGEDPP3.js} +6 -6
- package/dist/{BlogViewTracker-DVJHZ7CM.js.map → BlogViewTracker-6EGEDPP3.js.map} +1 -1
- package/dist/{BlogViewTracker-MKJYTTJQ.mjs → BlogViewTracker-R4YQ76WP.mjs} +5 -5
- package/dist/{BlogViewTracker-MKJYTTJQ.mjs.map → BlogViewTracker-R4YQ76WP.mjs.map} +1 -1
- package/dist/ChatWidget-2OFWPCWF.js +20 -0
- package/dist/{ChatWidget-BZ3KOSXG.js.map → ChatWidget-2OFWPCWF.js.map} +1 -1
- package/dist/ChatWidget-4AOGHYXQ.mjs +11 -0
- package/dist/{ChatWidget-BD4F4XLD.mjs.map → ChatWidget-4AOGHYXQ.mjs.map} +1 -1
- package/dist/EngageWidget-SFO2XRNG.mjs +9 -0
- package/dist/{EngageWidget-L7B6PCM3.mjs.map → EngageWidget-SFO2XRNG.mjs.map} +1 -1
- package/dist/EngageWidget-T4KAAD3G.js +18 -0
- package/dist/{EngageWidget-JPP6EDCJ.js.map → EngageWidget-T4KAAD3G.js.map} +1 -1
- package/dist/{FileField-7WPRONDS.mjs → FileField-7DF2SLPF.mjs} +5 -5
- package/dist/{FileField-7WPRONDS.mjs.map → FileField-7DF2SLPF.mjs.map} +1 -1
- package/dist/{FileField-GHT7444Y.js → FileField-CE2XNBBG.js} +6 -6
- package/dist/{FileField-GHT7444Y.js.map → FileField-CE2XNBBG.js.map} +1 -1
- package/dist/{FormSpotlight-WZVS6HHR.mjs → FormSpotlight-IRLKSZGV.mjs} +3 -3
- package/dist/{FormSpotlight-WZVS6HHR.mjs.map → FormSpotlight-IRLKSZGV.mjs.map} +1 -1
- package/dist/{FormSpotlight-BB2IB7IX.js → FormSpotlight-ZD3WR5BC.js} +15 -15
- package/dist/{FormSpotlight-BB2IB7IX.js.map → FormSpotlight-ZD3WR5BC.js.map} +1 -1
- package/dist/{FormStage-Y3NHHMV2.mjs → FormStage-2OSRNQJL.mjs} +3 -3
- package/dist/{FormStage-Y3NHHMV2.mjs.map → FormStage-2OSRNQJL.mjs.map} +1 -1
- package/dist/{FormStage-FLBLXENZ.js → FormStage-OSPXOUQE.js} +13 -13
- package/dist/{FormStage-FLBLXENZ.js.map → FormStage-OSPXOUQE.js.map} +1 -1
- package/dist/ManagedForm-5G37EDJT.mjs +14 -0
- package/dist/{ManagedForm-AJM6D4SK.mjs.map → ManagedForm-5G37EDJT.mjs.map} +1 -1
- package/dist/ManagedForm-JCHGBBQW.js +23 -0
- package/dist/{ManagedForm-2OPCHDNJ.js.map → ManagedForm-JCHGBBQW.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-L2ZHJ7F4.js → ManagedNewsletterForm-4LVJZROZ.js} +8 -8
- package/dist/{ManagedNewsletterForm-L2ZHJ7F4.js.map → ManagedNewsletterForm-4LVJZROZ.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-MJI2JXIB.mjs → ManagedNewsletterForm-QJSVH23S.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-MJI2JXIB.mjs.map → ManagedNewsletterForm-QJSVH23S.mjs.map} +1 -1
- package/dist/{SignalCore-23YDDSWO.mjs → SignalCore-L6Z3YTCF.mjs} +5 -5
- package/dist/{SignalCore-23YDDSWO.mjs.map → SignalCore-L6Z3YTCF.mjs.map} +1 -1
- package/dist/{SignalCore-G2VM7NUP.js → SignalCore-NQ4YEOI7.js} +11 -11
- package/dist/{SignalCore-G2VM7NUP.js.map → SignalCore-NQ4YEOI7.js.map} +1 -1
- package/dist/SitemapSync-3LUZWBTB.js +18 -0
- package/dist/{SitemapSync-T2N3TCWF.js.map → SitemapSync-3LUZWBTB.js.map} +1 -1
- package/dist/SitemapSync-MYSTLJOM.mjs +9 -0
- package/dist/{SitemapSync-YLWMU6J3.mjs.map → SitemapSync-MYSTLJOM.mjs.map} +1 -1
- package/dist/SitemapSync.d.ts.map +1 -1
- package/dist/analytics/AnalyticsProvider.d.ts +11 -1
- package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
- package/dist/analytics/WebVitals.d.ts +7 -1
- package/dist/analytics/WebVitals.d.ts.map +1 -1
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +25 -12
- package/dist/analytics/index.mjs +6 -5
- package/dist/analytics/send-gate.d.ts +119 -0
- package/dist/analytics/send-gate.d.ts.map +1 -0
- package/dist/analytics/send-gate.test.d.ts +20 -0
- package/dist/analytics/send-gate.test.d.ts.map +1 -0
- package/dist/blog/AuthorPage.d.ts +1 -1
- package/dist/blog/AuthorPage.d.ts.map +1 -1
- package/dist/blog/BlogLayout.d.ts +3 -1
- package/dist/blog/BlogLayout.d.ts.map +1 -1
- package/dist/blog/BlogList.d.ts +3 -1
- package/dist/blog/BlogList.d.ts.map +1 -1
- package/dist/blog/BlogPost.d.ts +3 -1
- package/dist/blog/BlogPost.d.ts.map +1 -1
- package/dist/blog/BlogSidebar.d.ts +3 -1
- package/dist/blog/BlogSidebar.d.ts.map +1 -1
- package/dist/blog/ClusterLandingPage.d.ts +3 -1
- package/dist/blog/ClusterLandingPage.d.ts.map +1 -1
- package/dist/blog/ClusterNavigation.d.ts +3 -1
- package/dist/blog/ClusterNavigation.d.ts.map +1 -1
- package/dist/blog/RelatedPosts.d.ts +4 -1
- package/dist/blog/RelatedPosts.d.ts.map +1 -1
- package/dist/blog/artwork-components.test.d.ts +2 -0
- package/dist/blog/artwork-components.test.d.ts.map +1 -0
- package/dist/blog/artwork.d.ts +14 -0
- package/dist/blog/artwork.d.ts.map +1 -0
- package/dist/blog/artwork.test.d.ts +2 -0
- package/dist/blog/artwork.test.d.ts.map +1 -0
- package/dist/blog/blog-styles.d.ts.map +1 -1
- package/dist/blog/blog-tables.d.ts +13 -0
- package/dist/blog/blog-tables.d.ts.map +1 -0
- package/dist/blog/blog-tables.test.d.ts +2 -0
- package/dist/blog/blog-tables.test.d.ts.map +1 -0
- package/dist/blog/index.d.ts +3 -0
- package/dist/blog/index.d.ts.map +1 -1
- package/dist/blog/index.js +52 -30
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +15 -12
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/publication-render.test.d.ts +2 -0
- package/dist/blog/publication-render.test.d.ts.map +1 -0
- package/dist/blog/publication-routes.test.d.ts +2 -0
- package/dist/blog/publication-routes.test.d.ts.map +1 -0
- package/dist/blog/routes.d.ts +40 -0
- package/dist/blog/routes.d.ts.map +1 -0
- package/dist/blog/server-core.d.ts +28 -21
- package/dist/blog/server-core.d.ts.map +1 -1
- package/dist/blog/server-ui.d.ts +4 -0
- package/dist/blog/server-ui.d.ts.map +1 -1
- package/dist/blog/server-ui.js +49 -28
- package/dist/blog/server-ui.js.map +1 -1
- package/dist/blog/server-ui.mjs +9 -15
- package/dist/blog/server-ui.mjs.map +1 -1
- package/dist/blog/server.d.ts +28 -21
- package/dist/blog/server.d.ts.map +1 -1
- package/dist/blog/server.js +71 -42
- package/dist/blog/server.mjs +3 -2
- package/dist/blog/types.d.ts +11 -1
- package/dist/blog/types.d.ts.map +1 -1
- package/dist/blog-styles-6EY3BS5Y.js +595 -0
- package/dist/blog-styles-6EY3BS5Y.js.map +1 -0
- package/dist/blog-styles-7AKRUMV7.mjs +592 -0
- package/dist/blog-styles-7AKRUMV7.mjs.map +1 -0
- package/dist/blog-tables-DWDEWA3S.js +17 -0
- package/dist/blog-tables-DWDEWA3S.js.map +1 -0
- package/dist/blog-tables-QGIHOESZ.mjs +4 -0
- package/dist/blog-tables-QGIHOESZ.mjs.map +1 -0
- package/dist/{chunk-KP56C66Z.js → chunk-2KIGFOPM.js} +126 -188
- package/dist/chunk-2KIGFOPM.js.map +1 -0
- package/dist/{chunk-EDZWNCSE.js → chunk-3EPMDPWI.js} +2 -2
- package/dist/{chunk-EDZWNCSE.js.map → chunk-3EPMDPWI.js.map} +1 -1
- package/dist/chunk-4B4S56WJ.mjs +110 -0
- package/dist/chunk-4B4S56WJ.mjs.map +1 -0
- package/dist/{chunk-47566YF4.js → chunk-4WQB2ORG.js} +14 -14
- package/dist/{chunk-47566YF4.js.map → chunk-4WQB2ORG.js.map} +1 -1
- package/dist/{chunk-5TGSM5EQ.js → chunk-5737U6DI.js} +14 -14
- package/dist/{chunk-5TGSM5EQ.js.map → chunk-5737U6DI.js.map} +1 -1
- package/dist/{chunk-DN6A6KXH.mjs → chunk-6CUBSQMD.mjs} +3 -3
- package/dist/{chunk-DN6A6KXH.mjs.map → chunk-6CUBSQMD.mjs.map} +1 -1
- package/dist/{chunk-JBGRXICL.js → chunk-746RKQHA.js} +75 -70
- package/dist/chunk-746RKQHA.js.map +1 -0
- package/dist/{chunk-GTK3CGWF.js → chunk-7IPSQ5JR.js} +6 -6
- package/dist/{chunk-GTK3CGWF.js.map → chunk-7IPSQ5JR.js.map} +1 -1
- package/dist/{chunk-4S7BHFGT.js → chunk-7PLH3H3W.js} +3 -3
- package/dist/{chunk-4S7BHFGT.js.map → chunk-7PLH3H3W.js.map} +1 -1
- package/dist/chunk-7U7C6XRI.mjs +6 -0
- package/dist/{chunk-HRQ4367C.mjs.map → chunk-7U7C6XRI.mjs.map} +1 -1
- package/dist/{chunk-X4PL7R63.mjs → chunk-7Y2UPFSY.mjs} +3 -3
- package/dist/{chunk-X4PL7R63.mjs.map → chunk-7Y2UPFSY.mjs.map} +1 -1
- package/dist/{chunk-XR47TOGW.mjs → chunk-A2VLEORI.mjs} +3 -3
- package/dist/{chunk-XR47TOGW.mjs.map → chunk-A2VLEORI.mjs.map} +1 -1
- package/dist/{chunk-PA5ZVCW2.mjs → chunk-ACTLQ2RH.mjs} +3 -3
- package/dist/{chunk-PA5ZVCW2.mjs.map → chunk-ACTLQ2RH.mjs.map} +1 -1
- package/dist/{chunk-VLR2UYO4.js → chunk-AWFZIXCT.js} +12 -11
- package/dist/chunk-AWFZIXCT.js.map +1 -0
- package/dist/{chunk-COAVBUMS.mjs → chunk-B36PTS7B.mjs} +413 -94
- package/dist/chunk-B36PTS7B.mjs.map +1 -0
- package/dist/{chunk-LFJRMY4V.js → chunk-DPDV5Z4G.js} +12 -12
- package/dist/{chunk-LFJRMY4V.js.map → chunk-DPDV5Z4G.js.map} +1 -1
- package/dist/{chunk-W47J6ZZG.mjs → chunk-DQM5GR2P.mjs} +4 -4
- package/dist/{chunk-W47J6ZZG.mjs.map → chunk-DQM5GR2P.mjs.map} +1 -1
- package/dist/{chunk-VGX6G3TA.mjs → chunk-EBMPXFOP.mjs} +3 -3
- package/dist/{chunk-VGX6G3TA.mjs.map → chunk-EBMPXFOP.mjs.map} +1 -1
- package/dist/{chunk-DHXQBTXE.mjs → chunk-EEQYKMGH.mjs} +75 -70
- package/dist/chunk-EEQYKMGH.mjs.map +1 -0
- package/dist/{chunk-77HT6TYK.mjs → chunk-G5I3XEQS.mjs} +3 -3
- package/dist/{chunk-77HT6TYK.mjs.map → chunk-G5I3XEQS.mjs.map} +1 -1
- package/dist/chunk-GHECYDSZ.mjs +134 -0
- package/dist/chunk-GHECYDSZ.mjs.map +1 -0
- package/dist/{chunk-UJOEN4X6.js → chunk-GQ6CUOLA.js} +15 -15
- package/dist/{chunk-UJOEN4X6.js.map → chunk-GQ6CUOLA.js.map} +1 -1
- package/dist/{chunk-DTX4R45S.js → chunk-HBMF3M5F.js} +4 -4
- package/dist/{chunk-DTX4R45S.js.map → chunk-HBMF3M5F.js.map} +1 -1
- package/dist/{chunk-NW5CBNRU.mjs → chunk-HDDV63XJ.mjs} +3 -3
- package/dist/{chunk-NW5CBNRU.mjs.map → chunk-HDDV63XJ.mjs.map} +1 -1
- package/dist/{chunk-DBJRJ2Q2.mjs → chunk-HH5KGXTK.mjs} +4 -4
- package/dist/{chunk-DBJRJ2Q2.mjs.map → chunk-HH5KGXTK.mjs.map} +1 -1
- package/dist/{chunk-AKQA5ZYZ.mjs → chunk-I4PDSDVE.mjs} +3 -3
- package/dist/{chunk-AKQA5ZYZ.mjs.map → chunk-I4PDSDVE.mjs.map} +1 -1
- package/dist/{chunk-2MPOO6QJ.js → chunk-ITFZZ6YT.js} +3 -3
- package/dist/{chunk-2MPOO6QJ.js.map → chunk-ITFZZ6YT.js.map} +1 -1
- package/dist/{chunk-WZZYTFDV.mjs → chunk-JJ26JKBJ.mjs} +8 -3
- package/dist/chunk-JJ26JKBJ.mjs.map +1 -0
- package/dist/{chunk-Z33JXJTJ.js → chunk-KMGGAL2X.js} +2 -2
- package/dist/{chunk-Z33JXJTJ.js.map → chunk-KMGGAL2X.js.map} +1 -1
- package/dist/{chunk-4IMZ45YA.mjs → chunk-KQ3VAOAF.mjs} +4 -4
- package/dist/{chunk-4IMZ45YA.mjs.map → chunk-KQ3VAOAF.mjs.map} +1 -1
- package/dist/{chunk-GPH3VVLP.js → chunk-LBS4PRC7.js} +3 -3
- package/dist/{chunk-GPH3VVLP.js.map → chunk-LBS4PRC7.js.map} +1 -1
- package/dist/chunk-LC7AM4J5.js +118 -0
- package/dist/chunk-LC7AM4J5.js.map +1 -0
- package/dist/{chunk-5HMN3FXL.js → chunk-LF4L3ZP5.js} +8 -8
- package/dist/{chunk-5HMN3FXL.js.map → chunk-LF4L3ZP5.js.map} +1 -1
- package/dist/{chunk-LHD45PGP.js → chunk-LHYVFWHL.js} +8 -8
- package/dist/{chunk-LHD45PGP.js.map → chunk-LHYVFWHL.js.map} +1 -1
- package/dist/{chunk-I72AUITZ.mjs → chunk-LIYSLNEK.mjs} +96 -644
- package/dist/chunk-LIYSLNEK.mjs.map +1 -0
- package/dist/{chunk-HIV5YK5G.js → chunk-LUYUFILE.js} +4 -4
- package/dist/{chunk-HIV5YK5G.js.map → chunk-LUYUFILE.js.map} +1 -1
- package/dist/{chunk-4HL6CAZ7.mjs → chunk-MIFP6QEQ.mjs} +4 -4
- package/dist/{chunk-4HL6CAZ7.mjs.map → chunk-MIFP6QEQ.mjs.map} +1 -1
- package/dist/{chunk-SI7R3IJX.mjs → chunk-MTANHZKJ.mjs} +7 -7
- package/dist/{chunk-SI7R3IJX.mjs.map → chunk-MTANHZKJ.mjs.map} +1 -1
- package/dist/{chunk-R4PFWVGZ.mjs → chunk-N6AVWMIB.mjs} +4 -4
- package/dist/{chunk-R4PFWVGZ.mjs.map → chunk-N6AVWMIB.mjs.map} +1 -1
- package/dist/{chunk-WD57YWY5.mjs → chunk-N6X76QUF.mjs} +3 -3
- package/dist/{chunk-WD57YWY5.mjs.map → chunk-N6X76QUF.mjs.map} +1 -1
- package/dist/{chunk-7UPPYERC.mjs → chunk-NUH245XK.mjs} +4 -4
- package/dist/{chunk-7UPPYERC.mjs.map → chunk-NUH245XK.mjs.map} +1 -1
- package/dist/chunk-NVSWTDWU.mjs +25 -0
- package/dist/chunk-NVSWTDWU.mjs.map +1 -0
- package/dist/chunk-OL2QBWAU.js +29 -0
- package/dist/chunk-OL2QBWAU.js.map +1 -0
- package/dist/{chunk-UYR22S67.js → chunk-OXZYP32B.js} +7 -7
- package/dist/{chunk-UYR22S67.js.map → chunk-OXZYP32B.js.map} +1 -1
- package/dist/{chunk-QG7WHAGD.js → chunk-QWLL3B6U.js} +15 -15
- package/dist/{chunk-QG7WHAGD.js.map → chunk-QWLL3B6U.js.map} +1 -1
- package/dist/{chunk-26JXNW7B.mjs → chunk-RO55G3OA.mjs} +2 -2
- package/dist/{chunk-26JXNW7B.mjs.map → chunk-RO55G3OA.mjs.map} +1 -1
- package/dist/{chunk-FH4LLJFL.mjs → chunk-SJXGIUHP.mjs} +9 -8
- package/dist/chunk-SJXGIUHP.mjs.map +1 -0
- package/dist/{chunk-4TU246Q4.mjs → chunk-SZHKNGNR.mjs} +2 -2
- package/dist/{chunk-4TU246Q4.mjs.map → chunk-SZHKNGNR.mjs.map} +1 -1
- package/dist/{chunk-GQTSQR63.js → chunk-U53KN4SA.js} +10 -5
- package/dist/chunk-U53KN4SA.js.map +1 -0
- package/dist/{chunk-AJBJH3BA.mjs → chunk-UOLY4NXK.mjs} +127 -189
- package/dist/chunk-UOLY4NXK.mjs.map +1 -0
- package/dist/{chunk-AVPMSJCQ.js → chunk-URVGBWCP.js} +4 -4
- package/dist/{chunk-AVPMSJCQ.js.map → chunk-URVGBWCP.js.map} +1 -1
- package/dist/chunk-UTOHMK52.js +8 -0
- package/dist/{chunk-TMQKZ4DO.js.map → chunk-UTOHMK52.js.map} +1 -1
- package/dist/{chunk-SHZXSIRH.js → chunk-VA36CJRV.js} +4 -4
- package/dist/{chunk-SHZXSIRH.js.map → chunk-VA36CJRV.js.map} +1 -1
- package/dist/{chunk-ZMFJXFUY.js → chunk-VWDT7H6L.js} +96 -644
- package/dist/chunk-VWDT7H6L.js.map +1 -0
- package/dist/{chunk-2VQ5YXOD.js → chunk-WSUQ76LN.js} +18 -18
- package/dist/{chunk-2VQ5YXOD.js.map → chunk-WSUQ76LN.js.map} +1 -1
- package/dist/{chunk-GM5E6R5W.mjs → chunk-XWF7QPIP.mjs} +3 -3
- package/dist/{chunk-GM5E6R5W.mjs.map → chunk-XWF7QPIP.mjs.map} +1 -1
- package/dist/chunk-YQTE32QK.js +137 -0
- package/dist/chunk-YQTE32QK.js.map +1 -0
- package/dist/{chunk-ISKJLXB4.mjs → chunk-ZDFVYSKK.mjs} +4 -4
- package/dist/{chunk-ISKJLXB4.mjs.map → chunk-ZDFVYSKK.mjs.map} +1 -1
- package/dist/{chunk-APL44ZVK.js → chunk-ZLPXFV5Y.js} +5 -5
- package/dist/{chunk-APL44ZVK.js.map → chunk-ZLPXFV5Y.js.map} +1 -1
- package/dist/{chunk-TAIGHH5J.js → chunk-ZY5AVC4P.js} +418 -98
- package/dist/chunk-ZY5AVC4P.js.map +1 -0
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.mjs +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/commerce/index.js +58 -57
- package/dist/commerce/index.mjs +7 -6
- package/dist/engage/index.js +10 -10
- package/dist/engage/index.mjs +7 -7
- package/dist/fleet/index.js +8 -8
- package/dist/fleet/index.mjs +4 -4
- package/dist/forms/index.js +16 -16
- package/dist/forms/index.mjs +9 -9
- package/dist/forms/server.js +10 -10
- package/dist/forms/server.mjs +8 -8
- package/dist/forms/static.js +7 -7
- package/dist/forms/static.mjs +6 -6
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +65 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -10
- package/dist/index.mjs.map +1 -1
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +8 -8
- package/dist/layout/client.mjs +7 -7
- package/dist/layout/index.js +10 -10
- package/dist/layout/index.mjs +8 -8
- package/dist/layout/types.d.ts +16 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.mjs +2 -2
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +6 -5
- package/dist/seo/client.mjs +5 -4
- package/dist/seo/index.js +6 -5
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +5 -4
- package/dist/seo/index.mjs.map +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/frame.d.ts +71 -0
- package/dist/shared/frame.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/index.mjs +1 -1
- package/dist/sync/BookingWidget.d.ts +0 -23
- package/dist/sync/BookingWidget.d.ts.map +1 -1
- package/dist/sync/MeetingFormatStep.d.ts +13 -0
- package/dist/sync/MeetingFormatStep.d.ts.map +1 -0
- package/dist/sync/api.d.ts +9 -10
- package/dist/sync/api.d.ts.map +1 -1
- package/dist/sync/booking-flow.d.ts +7 -0
- package/dist/sync/booking-flow.d.ts.map +1 -0
- package/dist/sync/booking-flow.test.d.ts +2 -0
- package/dist/sync/booking-flow.test.d.ts.map +1 -0
- package/dist/sync/index.d.ts +2 -2
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +20 -16
- package/dist/sync/index.mjs +4 -4
- package/dist/sync/types.d.ts +34 -0
- package/dist/sync/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/AnalyticsProvider-NA7EMJCA.mjs +0 -10
- package/dist/AnalyticsProvider-XE3ADUUH.js +0 -31
- package/dist/ChatWidget-BD4F4XLD.mjs +0 -11
- package/dist/ChatWidget-BZ3KOSXG.js +0 -20
- package/dist/EngageWidget-JPP6EDCJ.js +0 -18
- package/dist/EngageWidget-L7B6PCM3.mjs +0 -9
- package/dist/ManagedForm-2OPCHDNJ.js +0 -23
- package/dist/ManagedForm-AJM6D4SK.mjs +0 -14
- package/dist/SitemapSync-T2N3TCWF.js +0 -17
- package/dist/SitemapSync-YLWMU6J3.mjs +0 -8
- package/dist/chunk-AJBJH3BA.mjs.map +0 -1
- package/dist/chunk-CGCYZJYX.mjs +0 -41
- package/dist/chunk-CGCYZJYX.mjs.map +0 -1
- package/dist/chunk-COAVBUMS.mjs.map +0 -1
- package/dist/chunk-DHXQBTXE.mjs.map +0 -1
- package/dist/chunk-FH4LLJFL.mjs.map +0 -1
- package/dist/chunk-GQTSQR63.js.map +0 -1
- package/dist/chunk-HRQ4367C.mjs +0 -6
- package/dist/chunk-I72AUITZ.mjs.map +0 -1
- package/dist/chunk-JBGRXICL.js.map +0 -1
- package/dist/chunk-KP56C66Z.js.map +0 -1
- package/dist/chunk-TAIGHH5J.js.map +0 -1
- package/dist/chunk-TMQKZ4DO.js +0 -8
- package/dist/chunk-TPL2IHFI.js +0 -43
- package/dist/chunk-TPL2IHFI.js.map +0 -1
- package/dist/chunk-VLR2UYO4.js.map +0 -1
- package/dist/chunk-WZZYTFDV.mjs.map +0 -1
- package/dist/chunk-ZMFJXFUY.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/blog/ServiceCallout.tsx","../src/blog/ClusterNavigation.tsx","../src/blog/processBlogHtml.ts","../src/blog/reading-time.ts","../src/blog/author-social.ts","../src/blog/blog-styles.ts","../src/blog/BlogPost.tsx","../src/blog/BlogList.tsx","../src/blog/BlogSidebar.tsx","../src/blog/BlogLayout.tsx","../src/blog/RelatedPosts.tsx"],"names":["jsxs","Fragment","jsx","cls","fetchCategories","fetchRelatedPosts"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAqZnC,IAAA;AAAK,CAAA;AAMA,IAAM,WAAA;AAAA;AAAA,EAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","file":"chunk-I72AUITZ.mjs","sourcesContent":["/**\n * @sonordev/site-kit/blog - Service Callout / CTA Component\n *\n * Renders a promotional call-to-action section within blog posts.\n * Automatically generated by Signal AI during blog creation, linking\n * article content to the business's relevant services.\n *\n * Two variants:\n * - 'featured' (default): Full-width gradient banner with button\n * - 'inline': Compact card with icon accent\n *\n * Uses site-kit brand tokens (--sk-primary, --sk-bg, etc.) for theming.\n * Supports full Tailwind override via `styles` prop.\n *\n * @example\n * ```tsx\n * <ServiceCallout\n * title=\"Ready to build your MVP?\"\n * description=\"Our team specializes in lean SaaS builds.\"\n * cta=\"Get Started\"\n * url=\"/services/application-development\"\n * />\n * ```\n */\n\nimport React from 'react'\n\nexport interface ServiceCalloutProps {\n title: string\n description?: string\n cta?: string\n url: string\n variant?: 'featured' | 'inline'\n /** Override default styles with Tailwind classes */\n styles?: {\n wrapper?: string\n title?: string\n description?: string\n button?: string\n }\n /** Strip all default styles (BYO Tailwind) */\n unstyled?: boolean\n}\n\n// Default inline styles using CSS custom properties for brand theming\nconst defaults = {\n featured: {\n wrapper: {\n display: 'flex',\n flexWrap: 'wrap' as const,\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '1.5rem',\n padding: '2rem 2.5rem',\n margin: '3rem 0',\n borderRadius: '1rem',\n background: 'linear-gradient(135deg, color-mix(in srgb, var(--sk-primary, #2563eb) 8%, transparent), color-mix(in srgb, var(--sk-primary, #2563eb) 15%, transparent))',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #2563eb) 25%, transparent)',\n },\n title: {\n fontSize: '1.25rem',\n fontWeight: 700,\n color: 'var(--sk-text-primary, #0f172a)',\n margin: 0,\n },\n description: {\n fontSize: '0.9375rem',\n color: 'var(--sk-text-secondary, #475569)',\n marginTop: '0.5rem',\n maxWidth: '40rem',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n padding: '0.75rem 1.75rem',\n borderRadius: '0.5rem',\n fontWeight: 600,\n fontSize: '0.9375rem',\n color: '#ffffff',\n background: 'var(--sk-primary, #2563eb)',\n textDecoration: 'none',\n transition: 'transform 0.15s, box-shadow 0.15s',\n whiteSpace: 'nowrap' as const,\n },\n },\n inline: {\n wrapper: {\n display: 'flex',\n gap: '1rem',\n padding: '1.25rem 1.5rem',\n margin: '2rem 0',\n borderRadius: '0.75rem',\n background: 'var(--sk-bg-elevated, #f8fafc)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #2563eb) 20%, var(--sk-surface-border, #e2e8f0))',\n },\n icon: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '2.5rem',\n height: '2.5rem',\n borderRadius: '0.625rem',\n background: 'var(--sk-primary, #2563eb)',\n color: '#ffffff',\n flexShrink: 0,\n fontSize: '1.125rem',\n },\n title: {\n fontSize: '1rem',\n fontWeight: 600,\n color: 'var(--sk-text-primary, #0f172a)',\n margin: 0,\n },\n description: {\n fontSize: '0.875rem',\n color: 'var(--sk-text-secondary, #475569)',\n marginTop: '0.25rem',\n },\n link: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.25rem',\n marginTop: '0.5rem',\n fontSize: '0.875rem',\n fontWeight: 600,\n color: 'var(--sk-primary, #2563eb)',\n textDecoration: 'none',\n },\n },\n}\n\nexport function ServiceCallout({\n title,\n description,\n cta = 'Learn More',\n url,\n variant = 'featured',\n styles,\n unstyled = false,\n}: ServiceCalloutProps) {\n if (variant === 'inline') {\n return (\n <aside\n className={styles?.wrapper}\n style={unstyled ? undefined : defaults.inline.wrapper}\n role=\"complementary\"\n aria-label=\"Related service\"\n >\n <div style={unstyled ? undefined : defaults.inline.icon}>→</div>\n <div>\n <h4\n className={styles?.title}\n style={unstyled ? undefined : defaults.inline.title}\n >\n {title}\n </h4>\n {description && (\n <p\n className={styles?.description}\n style={unstyled ? undefined : defaults.inline.description}\n >\n {description}\n </p>\n )}\n <a\n href={url}\n className={styles?.button}\n style={unstyled ? undefined : defaults.inline.link}\n >\n {cta} →\n </a>\n </div>\n </aside>\n )\n }\n\n // Featured variant (default)\n return (\n <section\n className={styles?.wrapper}\n style={unstyled ? undefined : defaults.featured.wrapper}\n role=\"complementary\"\n aria-label=\"Call to action\"\n >\n <div>\n <h3\n className={styles?.title}\n style={unstyled ? undefined : defaults.featured.title}\n >\n {title}\n </h3>\n {description && (\n <p\n className={styles?.description}\n style={unstyled ? undefined : defaults.featured.description}\n >\n {description}\n </p>\n )}\n </div>\n <a\n href={url}\n className={styles?.button}\n style={unstyled ? undefined : defaults.featured.button}\n >\n {cta} →\n </a>\n </section>\n )\n}\n\n/**\n * Renders all service callouts for a blog post.\n * First callout uses 'featured' variant, subsequent use 'inline'.\n */\nexport function ServiceCallouts({\n callouts,\n styles,\n unstyled,\n}: {\n callouts: Array<{ title: string; description?: string; cta?: string; url: string }>\n styles?: ServiceCalloutProps['styles']\n unstyled?: boolean\n}) {\n if (!callouts || callouts.length === 0) return null\n\n return (\n <>\n {callouts.map((callout, i) => (\n <ServiceCallout\n key={callout.url + i}\n {...callout}\n variant={i === 0 ? 'featured' : 'inline'}\n styles={styles}\n unstyled={unstyled}\n />\n ))}\n </>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Cluster Navigation Component\n *\n * Renders cluster context on blog post pages:\n * - \"Full Guide\" pillar backlink (on support articles only)\n * - Sibling article list with article_type badges\n *\n * Adapts to light/dark themes automatically using the same --sk-* variables\n * as the rest of site-kit, with currentColor-based fallbacks.\n */\n\nimport React from 'react'\nimport type { ClusterNavigation as ClusterNavigationType } from './types'\n\n// ============================================================================\n// CSS\n// ============================================================================\n\nconst clusterNavCss = `\n.sk-cluster-nav {\n --_cn-primary: var(--sk-primary, currentColor);\n --_cn-bg: var(--sk-bg-elevated, color-mix(in srgb, currentColor 6%, transparent));\n --_cn-border: var(--sk-surface-border, color-mix(in srgb, currentColor 12%, transparent));\n --_cn-text: var(--sk-text-primary, inherit);\n --_cn-text2: var(--sk-text-secondary, color-mix(in srgb, currentColor 70%, transparent));\n --_cn-text3: var(--sk-text-tertiary, color-mix(in srgb, currentColor 45%, transparent));\n\n margin: 2rem 0;\n padding: 1.5rem;\n border-radius: 0.75rem;\n background: var(--_cn-bg);\n border: 1px solid var(--_cn-border);\n color: var(--_cn-text);\n}\n\n.sk-cluster-pillar-link {\n margin-bottom: 1.25rem;\n padding-bottom: 1.25rem;\n border-bottom: 1px solid var(--_cn-border);\n}\n.sk-cluster-pillar-link-label {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--_cn-text3);\n margin: 0 0 0.375rem 0;\n}\n.sk-cluster-pillar-link a {\n font-size: 0.9375rem;\n font-weight: 600;\n color: var(--_cn-primary);\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-cluster-pillar-link a:hover { opacity: 0.8; }\n\n.sk-cluster-siblings-title {\n font-size: 0.6875rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: var(--_cn-text3);\n margin: 0 0 0.75rem 0;\n}\n.sk-cluster-siblings-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.sk-cluster-siblings-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.sk-cluster-siblings-item a {\n font-size: 0.875rem;\n color: var(--_cn-text2);\n text-decoration: none;\n transition: color 0.15s;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.sk-cluster-siblings-item a:hover { color: var(--_cn-primary); }\n.sk-cluster-type-badge {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n padding: 0.125rem 0.4rem;\n border-radius: 9999px;\n font-size: 0.625rem;\n font-weight: 500;\n text-transform: capitalize;\n background: color-mix(in srgb, var(--_cn-primary) 10%, transparent);\n color: var(--_cn-primary);\n border: 1px solid color-mix(in srgb, var(--_cn-primary) 20%, transparent);\n}\n`\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport interface ClusterNavigationProps {\n /** Cluster navigation data */\n navigation: ClusterNavigationType\n /** Base path for blog URLs (default: /blog) */\n basePath?: string\n /**\n * Fallback category slug for URL building (optional). Each linked article's\n * OWN category takes precedence when present — applying one category to\n * every sibling produced wrong-category URLs (duplicate content / redirect\n * chains) on category-segmented sites whenever a cluster spans categories.\n */\n category?: string\n /** Append a trailing slash to article URLs (only for trailingSlash sites) */\n trailingSlash?: boolean\n /** Disable default styles */\n unstyled?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport function ClusterNavigation({\n navigation,\n basePath = '/blog',\n category,\n trailingSlash = false,\n unstyled = false,\n className,\n}: ClusterNavigationProps) {\n if (!navigation) return null\n\n const siblings = (navigation.siblings || []).filter(\n s => s.article_type !== 'pillar'\n )\n\n const hasPillarLink = !navigation.is_pillar && navigation.pillar\n const hasSiblings = siblings.length > 0\n\n if (!hasPillarLink && !hasSiblings) return null\n\n const articleUrl = (article: { slug: string; category?: string }) => {\n const cat = article.category || category\n const path = cat\n ? `${basePath}/${cat}/${article.slug}`\n : `${basePath}/${article.slug}`\n return trailingSlash ? `${path}/` : path\n }\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: clusterNavCss }} />}\n\n <nav className={`${unstyled ? '' : 'sk-cluster-nav'} ${className || ''}`}>\n {hasPillarLink && navigation.pillar && (\n <div className={unstyled ? '' : 'sk-cluster-pillar-link'}>\n <p className={unstyled ? '' : 'sk-cluster-pillar-link-label'}>Full Guide</p>\n <a href={articleUrl(navigation.pillar)}>\n {navigation.pillar.title}\n </a>\n </div>\n )}\n\n {hasSiblings && (\n <div>\n <p className={unstyled ? '' : 'sk-cluster-siblings-title'}>\n {navigation.is_pillar ? 'Deep Dives' : 'More in This Series'}\n </p>\n <ul className={unstyled ? '' : 'sk-cluster-siblings-list'}>\n {siblings.map((sibling) => (\n <li key={sibling.slug} className={unstyled ? '' : 'sk-cluster-siblings-item'}>\n <span className={unstyled ? '' : 'sk-cluster-type-badge'}>\n {sibling.article_type}\n </span>\n <a href={articleUrl(sibling)}>{sibling.title}</a>\n </li>\n ))}\n </ul>\n </div>\n )}\n </nav>\n </>\n )\n}\n","/**\n * Post-process Portal/blog HTML for safe, consistent link behavior.\n * Server-safe string transforms only (no DOM).\n */\n\n/** Normalize hostname for same-site detection (strips leading www). */\nexport function normalizeSiteHost(siteUrl: string): string {\n try {\n const base = siteUrl.startsWith('http') ? siteUrl : `https://${siteUrl}`\n const u = new URL(base)\n return u.hostname.replace(/^www\\./i, '').toLowerCase()\n } catch {\n return ''\n }\n}\n\n/**\n * Resolve canonical site URL for link classification.\n * Pass `explicit` from props when env vars are not set (e.g. non-Vercel hosts).\n */\nexport function resolveBlogSiteUrl(explicit?: string): string {\n const fromProp = explicit?.trim()\n if (fromProp) return fromProp\n const next = process.env.NEXT_PUBLIC_SITE_URL?.trim()\n if (next) return next\n const site = process.env.SITE_URL?.trim()\n if (site) return site\n const vercel = process.env.VERCEL_URL?.trim()\n if (vercel) return vercel.startsWith('http') ? vercel : `https://${vercel}`\n return ''\n}\n\n/**\n * Add `target=\"_blank\"` and `rel=\"noopener noreferrer\"` to external http(s) links.\n * Same registrable host (with or without `www`) is treated as internal.\n * Skips anchors that already set `target`.\n */\nexport function addExternalLinkTargets(html: string, siteUrl: string): string {\n if (!html || !siteUrl) return html\n const siteHost = normalizeSiteHost(siteUrl)\n if (!siteHost) return html\n\n return html.replace(/<a\\b([^>]*)>/gi, (_full, attrs: string) => {\n const hrefMatch = attrs.match(/\\bhref\\s*=\\s*([\"'])([^\"']*)\\1/i)\n if (!hrefMatch) return `<a${attrs}>`\n const href = hrefMatch[2].trim()\n if (!/^https?:\\/\\//i.test(href)) return `<a${attrs}>`\n\n try {\n const url = new URL(href)\n const linkHost = url.hostname.replace(/^www\\./i, '').toLowerCase()\n if (linkHost === siteHost) return `<a${attrs}>`\n if (/\\btarget\\s*=/i.test(attrs)) return `<a${attrs}>`\n const trimmed = attrs.trim()\n return `<a ${trimmed} target=\"_blank\" rel=\"noopener noreferrer\">`\n } catch {\n return `<a${attrs}>`\n }\n })\n}\n","import type { BlogPost } from './types'\n\n/**\n * Single source of truth for reading-time display.\n *\n * The DB/API column is `reading_time` (blog_posts) — `reading_time_minutes`\n * never existed server-side and exists on the type only for callers that\n * pre-map their own data. Every \"X min read\" chip resolves through here.\n */\nexport function readingTimeMinutes(\n post: Pick<BlogPost, 'reading_time' | 'reading_time_minutes'>\n): number | null {\n const value = post.reading_time_minutes ?? post.reading_time\n return typeof value === 'number' && value > 0 ? value : null\n}\n","import type { BlogAuthor } from './types'\n\nexport interface AuthorSocialLink {\n label: string\n href: string\n}\n\nconst withPrefix = (value: string, base: string): string =>\n value.startsWith('http') ? value : `${base}${value}`\n\n/**\n * Single source of truth for author social display.\n *\n * The real blog_authors columns are linkedin_url / twitter_url / website_url\n * (E-E-A-T fields); `social_links` / `website` are the legacy shape that no\n * API response ever carried. Real columns win; legacy handles get their host\n * prefixed unless they are already full URLs.\n */\nexport function getAuthorSocialLinks(\n author: Pick<\n BlogAuthor,\n 'linkedin_url' | 'twitter_url' | 'website_url' | 'website' | 'social_links'\n >\n): AuthorSocialLink[] {\n const links: AuthorSocialLink[] = []\n\n const linkedin = author.linkedin_url || author.social_links?.linkedin\n if (linkedin) links.push({ label: 'LinkedIn', href: withPrefix(linkedin, 'https://linkedin.com/in/') })\n\n const twitter = author.twitter_url\n ? author.twitter_url\n : author.social_links?.twitter\n ? withPrefix(author.social_links.twitter, 'https://twitter.com/')\n : null\n if (twitter) links.push({ label: 'Twitter', href: twitter })\n\n const website = author.website_url || author.website\n if (website) links.push({ label: 'Website', href: website })\n\n const github = author.social_links?.github\n if (github) links.push({ label: 'GitHub', href: withPrefix(github, 'https://github.com/') })\n\n return links\n}\n","/**\n * Scoped CSS for BlogPost and BlogList default rendering.\n *\n * Injected via `<style>` in the server component output so consumers\n * get a polished blog with zero configuration.\n *\n * All colours use `--sk-*` CSS custom properties with `color-mix()` fallbacks\n * that adapt to both light and dark host sites. The host can set:\n *\n * --sk-primary Brand accent (links, highlights)\n * --sk-bg Page background\n * --sk-bg-elevated Card / elevated surface background\n * --sk-text-primary Main text\n * --sk-text-secondary Subdued text\n * --sk-text-tertiary Faint text / meta\n * --sk-surface-border Subtle border color\n *\n * If none are set the defaults produce a clean neutral light-mode look.\n */\n\n// ---------------------------------------------------------------------------\n// BlogPost styles\n// ---------------------------------------------------------------------------\n\nexport const blogPostCss = /* css */ `\n/* ===== Layout ===== */\n.sk-blog-article {\n --_sk-primary: var(--sk-primary, #2563eb);\n --_sk-bg: var(--sk-bg, #ffffff);\n --_sk-bg-el: var(--sk-bg-elevated, #f8fafc);\n --_sk-text: var(--sk-text-primary, inherit);\n --_sk-text2: var(--sk-text-secondary, #475569);\n --_sk-text3: var(--sk-text-tertiary, #94a3b8);\n --_sk-border: var(--sk-surface-border, #e2e8f0);\n max-width: 1080px;\n margin: 0 auto;\n padding: 0 1rem;\n color: var(--_sk-text);\n}\n\n/* ===== Header ===== */\n.sk-blog-header { margin-bottom: 2.5rem; }\n\n.sk-blog-breadcrumb {\n display: flex;\n align-items: center;\n gap: 0.4rem;\n margin-bottom: 1.25rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-breadcrumb a {\n color: var(--_sk-primary);\n text-decoration: none;\n font-weight: 500;\n}\n.sk-blog-breadcrumb a:hover { text-decoration: underline; }\n.sk-blog-breadcrumb-sep { color: var(--_sk-text3); }\n\n.sk-blog-title {\n font-size: 2.5rem;\n font-weight: 800;\n line-height: 1.15;\n letter-spacing: -0.02em;\n text-wrap: balance;\n margin: 0 0 0.75rem;\n color: var(--_sk-text);\n}\n.sk-blog-subtitle {\n font-size: 1.25rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n margin: 0 0 1rem;\n}\n.sk-blog-meta {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.5rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-meta-item { white-space: nowrap; }\n.sk-blog-meta-dot {\n width: 3px; height: 3px;\n border-radius: 50%;\n background: var(--_sk-text3);\n flex-shrink: 0;\n}\n\n/* ===== Featured image ===== */\n.sk-blog-featured-wrap {\n margin: 0 0 2.5rem;\n border-radius: 0.75rem;\n overflow: hidden;\n}\n.sk-blog-featured-img {\n display: block;\n width: 100%;\n max-height: 500px;\n object-fit: cover;\n}\n\n/* ===== Content + TOC grid ===== */\n.sk-blog-layout {\n display: grid;\n grid-template-columns: 1fr;\n gap: 3rem;\n}\n@media (min-width: 1024px) {\n .sk-blog-layout--has-toc {\n grid-template-columns: 1fr 320px;\n }\n}\n\n/* ===== Article body typography ===== */\n.sk-blog-content {\n font-size: 1.125rem;\n line-height: 1.8;\n color: var(--_sk-text);\n overflow-wrap: break-word;\n}\n.sk-blog-content > * + * { margin-top: 1.5em; }\n.sk-blog-content h2,\n.sk-blog-content h3,\n.sk-blog-content h4 {\n scroll-margin-top: 5rem;\n line-height: 1.3;\n font-weight: 700;\n color: var(--_sk-text);\n}\n.sk-blog-content h2 { font-size: 1.5rem; margin-top: 2.5em; margin-bottom: 0.75em; }\n.sk-blog-content h3 { font-size: 1.25rem; margin-top: 2em; margin-bottom: 0.5em; }\n.sk-blog-content h4 { font-size: 1.1rem; margin-top: 1.5em; margin-bottom: 0.5em; }\n.sk-blog-content p { margin: 0 0 1.5em; }\n.sk-blog-content a {\n color: var(--_sk-primary);\n text-decoration: underline;\n text-decoration-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n text-underline-offset: 2px;\n transition: text-decoration-color 0.15s;\n}\n.sk-blog-content a:hover {\n text-decoration-color: var(--_sk-primary);\n}\n.sk-blog-content strong { font-weight: 700; color: var(--_sk-text); }\n.sk-blog-content em { font-style: italic; }\n.sk-blog-content blockquote {\n border-left: 3px solid var(--_sk-primary);\n padding: 0.75em 1.25em;\n margin: 1.5em 0;\n color: var(--_sk-text2);\n font-style: italic;\n background: color-mix(in srgb, var(--_sk-primary) 5%, var(--_sk-bg));\n border-radius: 0 0.5rem 0.5rem 0;\n}\n.sk-blog-content blockquote p:last-child { margin-bottom: 0; }\n.sk-blog-content ul,\n.sk-blog-content ol {\n padding-left: 1.5em;\n margin: 1.25em 0;\n}\n.sk-blog-content li { margin-bottom: 0.5em; }\n.sk-blog-content li::marker { color: var(--_sk-primary); }\n.sk-blog-content code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.875em;\n padding: 0.15em 0.4em;\n border-radius: 0.25rem;\n background: color-mix(in srgb, var(--_sk-text) 8%, var(--_sk-bg));\n}\n.sk-blog-content pre {\n margin: 1.5em 0;\n padding: 1.25em 1.5em;\n border-radius: 0.75rem;\n background: color-mix(in srgb, var(--_sk-text) 6%, var(--_sk-bg));\n overflow-x: auto;\n font-size: 0.875rem;\n line-height: 1.7;\n}\n.sk-blog-content pre code {\n background: none;\n padding: 0;\n font-size: inherit;\n}\n.sk-blog-content img {\n max-width: 100%;\n height: auto;\n border-radius: 0.5rem;\n margin: 1.5em auto;\n display: block;\n}\n.sk-blog-content hr {\n border: none;\n height: 1px;\n background: var(--_sk-border);\n margin: 2.5em 0;\n}\n.sk-blog-content table {\n width: 100%;\n border-collapse: collapse;\n margin: 1.5em 0;\n font-size: 0.95rem;\n}\n.sk-blog-content th,\n.sk-blog-content td {\n text-align: left;\n padding: 0.625rem 0.875rem;\n border-bottom: 1px solid var(--_sk-border);\n}\n.sk-blog-content th {\n font-weight: 600;\n color: var(--_sk-text);\n}\n.sk-blog-content td { color: var(--_sk-text2); }\n\n/* ===== Table of contents ===== */\n.sk-blog-toc {\n position: sticky;\n top: 6rem;\n align-self: start;\n padding: 1.25rem;\n border-radius: 0.75rem;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n max-height: calc(100vh - 8rem);\n overflow-y: auto;\n scrollbar-width: thin;\n scrollbar-color: var(--_sk-border) transparent;\n}\n.sk-blog-toc::-webkit-scrollbar { width: 5px; }\n.sk-blog-toc::-webkit-scrollbar-track { background: transparent; }\n.sk-blog-toc::-webkit-scrollbar-thumb { background: var(--_sk-border); border-radius: 3px; }\n.sk-blog-toc::-webkit-scrollbar-thumb:hover { background: var(--_sk-text3); }\n.sk-blog-toc-title {\n margin: 0 0 0.75rem;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n color: var(--_sk-text3);\n}\n.sk-blog-toc-list {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n.sk-blog-toc-list li { margin-bottom: 0.4rem; }\n.sk-blog-toc-list a {\n display: block;\n font-size: 0.8125rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n text-decoration: none;\n padding: 0.15rem 0;\n transition: color 0.15s;\n}\n.sk-blog-toc-list a:hover { color: var(--_sk-primary); }\n.sk-blog-toc-indent-3 { padding-left: 0.75rem; }\n.sk-blog-toc-indent-4 { padding-left: 1.5rem; }\n\n@media (max-width: 1023px) {\n .sk-blog-toc { display: none; }\n}\n\n/* ===== Tags ===== */\n.sk-blog-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin-top: 2.5rem;\n}\n.sk-blog-tag {\n display: inline-block;\n padding: 0.25rem 0.875rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border-radius: 9999px;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n color: var(--_sk-text2);\n text-decoration: none;\n transition: color 0.15s, border-color 0.15s;\n}\n.sk-blog-tag:hover {\n color: var(--_sk-primary);\n border-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n}\n\n/* ===== Author card ===== */\n.sk-blog-author {\n margin-top: 3rem;\n padding: 1.5rem;\n border-radius: 0.75rem;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n display: flex;\n gap: 1.25rem;\n align-items: flex-start;\n}\n.sk-blog-author-avatar {\n width: 72px;\n height: 72px;\n border-radius: 50%;\n object-fit: cover;\n flex-shrink: 0;\n}\n.sk-blog-author-name {\n margin: 0 0 0.125rem;\n font-size: 1.0625rem;\n font-weight: 700;\n color: var(--_sk-text);\n}\n.sk-blog-author-title {\n margin: 0 0 0.25rem;\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-blog-author-bio {\n margin: 0.5rem 0 0;\n font-size: 0.875rem;\n line-height: 1.6;\n color: var(--_sk-text2);\n}\n.sk-blog-author-links {\n display: flex;\n gap: 1rem;\n margin-top: 0.625rem;\n}\n.sk-blog-author-links a {\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--_sk-primary);\n text-decoration: none;\n}\n.sk-blog-author-links a:hover { text-decoration: underline; }\n\n@media (max-width: 640px) {\n .sk-blog-author { flex-direction: column; align-items: center; text-align: center; }\n .sk-blog-author-links { justify-content: center; }\n}\n\n/* ===== Related posts ===== */\n.sk-blog-related { margin-top: 3.5rem; }\n.sk-blog-related-title {\n font-size: 1.375rem;\n font-weight: 700;\n margin: 0 0 1.5rem;\n color: var(--_sk-text);\n}\n.sk-blog-related-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n gap: 1.25rem;\n}\n.sk-blog-related-card {\n border-radius: 0.75rem;\n overflow: hidden;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n text-decoration: none;\n color: inherit;\n display: flex;\n flex-direction: column;\n transition: transform 0.2s, box-shadow 0.2s;\n}\n.sk-blog-related-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0,0,0,0.08);\n}\n.sk-blog-related-card img {\n width: 100%;\n height: 160px;\n object-fit: cover;\n}\n.sk-blog-related-card-body { padding: 1rem 1.125rem; }\n.sk-blog-related-card h3 {\n font-size: 0.9375rem;\n font-weight: 650;\n line-height: 1.4;\n margin: 0 0 0.375rem;\n color: var(--_sk-text);\n}\n.sk-blog-related-card p {\n font-size: 0.8125rem;\n line-height: 1.5;\n color: var(--_sk-text2);\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* ===== Not found ===== */\n.sk-blog-not-found {\n text-align: center;\n padding: 5rem 1rem;\n}\n.sk-blog-not-found h1 {\n font-size: 1.5rem;\n font-weight: 700;\n margin: 0 0 0.75rem;\n color: var(--_sk-text);\n}\n.sk-blog-not-found p {\n color: var(--_sk-text2);\n margin: 0 0 1.5rem;\n}\n.sk-blog-not-found a {\n display: inline-block;\n padding: 0.75rem 1.5rem;\n border-radius: 0.5rem;\n background: var(--_sk-primary);\n color: #fff;\n font-weight: 600;\n font-size: 0.875rem;\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-blog-not-found a:hover { opacity: 0.9; }\n\n/* ===== Responsive ===== */\n@media (max-width: 768px) {\n .sk-blog-title { font-size: 1.75rem; }\n .sk-blog-subtitle { font-size: 1.0625rem; }\n .sk-blog-content { font-size: 1rem; }\n .sk-blog-related-grid { grid-template-columns: 1fr; }\n}\n`.trim()\n\n// ---------------------------------------------------------------------------\n// BlogList styles\n// ---------------------------------------------------------------------------\n\nexport const blogListCss = /* css */ `\n/* ===== BlogList layout ===== */\n.sk-bloglist {\n --_sk-primary: var(--sk-primary, #2563eb);\n --_sk-bg: var(--sk-bg, #ffffff);\n --_sk-bg-el: var(--sk-bg-elevated, #f8fafc);\n --_sk-text: var(--sk-text-primary, inherit);\n --_sk-text2: var(--sk-text-secondary, #475569);\n --_sk-text3: var(--sk-text-tertiary, #94a3b8);\n --_sk-border: var(--sk-surface-border, #e2e8f0);\n}\n\n/* ===== Category filter ===== */\n.sk-bloglist-cats {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin-bottom: 2rem;\n}\n.sk-bloglist-cat {\n display: inline-block;\n padding: 0.375rem 1rem;\n border-radius: 9999px;\n font-size: 0.8125rem;\n font-weight: 600;\n text-decoration: none;\n transition: background 0.15s, color 0.15s, border-color 0.15s;\n border: 1px solid var(--_sk-border);\n background: var(--_sk-bg-el);\n color: var(--_sk-text2);\n}\n.sk-bloglist-cat:hover {\n border-color: color-mix(in srgb, var(--_sk-primary) 40%, transparent);\n color: var(--_sk-primary);\n}\n.sk-bloglist-cat--active {\n background: var(--_sk-primary);\n color: #fff;\n border-color: var(--_sk-primary);\n}\n.sk-bloglist-cat--active:hover { color: #fff; opacity: 0.9; }\n\n/* ===== Card grid ===== */\n.sk-bloglist-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n}\n\n/* ===== Post card ===== */\n.sk-bloglist-card {\n border-radius: 0.75rem;\n overflow: hidden;\n background: var(--_sk-bg-el);\n border: 1px solid var(--_sk-border);\n display: flex;\n flex-direction: column;\n transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;\n}\n.sk-bloglist-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0,0,0,0.08);\n border-color: color-mix(in srgb, var(--_sk-primary) 30%, var(--_sk-border));\n}\n.sk-bloglist-card-img-link { display: block; overflow: hidden; }\n.sk-bloglist-card-img {\n display: block;\n width: 100%;\n height: 200px;\n object-fit: cover;\n transition: transform 0.4s;\n}\n.sk-bloglist-card:hover .sk-bloglist-card-img { transform: scale(1.03); }\n.sk-bloglist-card-body {\n padding: 1.25rem;\n display: flex;\n flex-direction: column;\n flex: 1;\n}\n.sk-bloglist-card-meta {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n margin-bottom: 0.625rem;\n}\n.sk-bloglist-card-category {\n display: inline-block;\n padding: 0.125rem 0.5rem;\n border-radius: 0.25rem;\n font-size: 0.6875rem;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n background: color-mix(in srgb, var(--_sk-primary) 12%, transparent);\n color: var(--_sk-primary);\n}\n.sk-bloglist-card-date {\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n.sk-bloglist-card-title {\n font-size: 1.0625rem;\n font-weight: 700;\n line-height: 1.4;\n margin: 0 0 0.5rem;\n}\n.sk-bloglist-card-title a {\n color: var(--_sk-text);\n text-decoration: none;\n transition: color 0.15s;\n}\n.sk-bloglist-card:hover .sk-bloglist-card-title a { color: var(--_sk-primary); }\n.sk-bloglist-card-excerpt {\n font-size: 0.875rem;\n line-height: 1.6;\n color: var(--_sk-text2);\n margin: 0 0 1rem;\n display: -webkit-box;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n overflow: hidden;\n flex: 1;\n}\n.sk-bloglist-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 0.75rem;\n border-top: 1px solid var(--_sk-border);\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n\n/* ===== Pagination ===== */\n.sk-bloglist-pagination {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 0.75rem;\n margin-top: 3rem;\n}\n.sk-bloglist-page-link {\n display: inline-block;\n padding: 0.5rem 1.25rem;\n border-radius: 0.5rem;\n background: var(--_sk-primary);\n color: #fff;\n font-size: 0.875rem;\n font-weight: 600;\n text-decoration: none;\n transition: opacity 0.15s;\n}\n.sk-bloglist-page-link:hover { opacity: 0.9; }\n.sk-bloglist-page-info {\n font-size: 0.8125rem;\n color: var(--_sk-text3);\n}\n\n/* ===== Empty state ===== */\n.sk-bloglist-empty {\n text-align: center;\n padding: 3rem 1rem;\n color: var(--_sk-text2);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 640px) {\n .sk-bloglist-grid { grid-template-columns: 1fr; }\n}\n`.trim()\n","/**\n * @sonordev/site-kit/blog - Blog Post Component\n *\n * Fetches and displays a single blog post with full content, table of contents,\n * author info, related posts, and SEO metadata support.\n *\n * Ships with world-class default styling via scoped `.sk-blog-*` classes.\n * No configuration needed — just `<BlogPost slug={slug} />`.\n *\n * Override with `styles` prop (per-element class names) or `unstyled` for\n * complete control. The `children` render prop gives full data access.\n */\n\nimport React from 'react'\nimport { marked } from 'marked'\nimport type { BlogPost as BlogPostType, TocItem, BlogAuthor, ClusterNavigation as ClusterNavigationType } from './types'\nimport { ServiceCallouts } from './ServiceCallout'\nimport { readingTimeMinutes } from './reading-time'\nimport { getAuthorSocialLinks } from './author-social'\nimport { ClusterNavigation } from './ClusterNavigation'\nimport { addExternalLinkTargets, resolveBlogSiteUrl } from './processBlogHtml'\nimport { blogPostCss } from './blog-styles'\n\n/**\n * Extract cluster navigation from a post's cluster fields (pure function, no\n * API calls). Mirrored copy: server-core.ts getClusterNavigation is\n * identical. Keep the two in sync — they CANNOT be consolidated because\n * blog/index is a CLIENT_ENTRY that must never import blog/server-core (see\n * build-entries.ts and client-entry-boundary.test.ts).\n */\nfunction getClusterNav(post: Record<string, any>): ClusterNavigationType | null {\n if (!post.cluster_id && !post.cluster_slug) return null\n const isPillar = post.article_type === 'pillar'\n return {\n cluster_name: post.cluster_name || '',\n cluster_slug: post.cluster_slug || '',\n pillar: isPillar ? null\n : post.parent_pillar_slug\n ? {\n slug: post.parent_pillar_slug,\n title: post.parent_pillar_title || '',\n category: post.parent_pillar_category || undefined,\n }\n : null,\n siblings: post.sibling_articles || [],\n is_pillar: isPillar,\n }\n}\n\n// ============================================================================\n// Markdown helpers\n// ============================================================================\n\nfunction looksLikeMarkdown(text: string): boolean {\n if (text.trimStart().startsWith('<')) return false\n const markers = [/^#{1,6}\\s/m, /\\*\\*[^*]+\\*\\*/, /\\[([^\\]]+)\\]\\([^)]+\\)/, /^[-*]\\s/m, /^>\\s/m]\n let hits = 0\n for (const re of markers) if (re.test(text)) hits++\n return hits >= 2\n}\n\nfunction slugify(text: string): string {\n return text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')\n}\n\n/** Convert markdown to HTML if needed, and inject IDs into headings for TOC anchors. */\nfunction ensureHtml(raw: string): string {\n if (!raw) return raw\n let html = raw\n if (looksLikeMarkdown(html)) {\n html = marked.parse(html, { gfm: true, breaks: false, async: false }) as string\n }\n html = injectHeadingIds(html)\n return html\n}\n\n/** Add `id` attributes to h2-h4 that lack them so TOC anchor links work. */\nfunction injectHeadingIds(html: string): string {\n return html.replace(/<h([2-4])([^>]*)>(.*?)<\\/h[2-4]>/gi, (_full, level, attrs: string, inner: string) => {\n if (/\\bid\\s*=/i.test(attrs)) return _full\n const text = inner.replace(/<[^>]*>/g, '')\n const id = slugify(text)\n return `<h${level}${attrs} id=\"${id}\">${inner}</h${level}>`\n })\n}\n\n// ============================================================================\n// STYLE TYPES\n// ============================================================================\n\nexport interface BlogPostStyles {\n article?: string\n header?: string\n breadcrumb?: string\n breadcrumbLink?: string\n title?: string\n subtitle?: string\n meta?: string\n metaItem?: string\n featuredImageWrapper?: string\n featuredImage?: string\n contentLayout?: string\n content?: string\n tocSidebar?: string\n tocTitle?: string\n tocList?: string\n tocItem?: string\n tocLink?: string\n tags?: string\n tag?: string\n faqSection?: string\n faqTitle?: string\n faqItem?: string\n faqQuestion?: string\n faqAnswer?: string\n authorCard?: string\n relatedSection?: string\n relatedTitle?: string\n relatedGrid?: string\n relatedCard?: string\n notFound?: string\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\nasync function fetchBlogPost(apiUrl: string, apiKey: string, slug: string): Promise<BlogPostType | null> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n if (!response.ok) {\n if (response.status === 404) return null\n console.error('[Blog] Failed to fetch post:', response.statusText)\n return null\n }\n const data = await response.json()\n return data.post\n } catch (error) {\n console.error('[Blog] Error fetching post:', error)\n return null\n }\n}\n\nasync function fetchRelatedPosts(apiUrl: string, apiKey: string, postId: string, limit: number = 3): Promise<BlogPostType[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n body: JSON.stringify({ current_post_id: postId, limit }),\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching related posts:', error)\n return []\n }\n}\n\n// ============================================================================\n// TOC GENERATION\n// ============================================================================\n\nfunction generateTableOfContents(html: string): TocItem[] {\n const headingRegex = /<h([2-4])[^>]*(?:id=\"([^\"]*)\")?[^>]*>(.*?)<\\/h[2-4]>/gi\n const items: TocItem[] = []\n let match\n while ((match = headingRegex.exec(html)) !== null) {\n const level = parseInt(match[1])\n const existingId = match[2]\n const text = match[3].replace(/<[^>]*>/g, '')\n const id = existingId || slugify(text)\n items.push({ id, text, level })\n }\n return items\n}\n\n// ============================================================================\n// COMPONENT PROPS\n// ============================================================================\n\nexport interface BlogPostServerProps {\n apiUrl?: string\n apiKey?: string\n slug: string\n showToc?: boolean\n showRelated?: boolean\n relatedCount?: number\n showAuthor?: boolean\n basePath?: string\n className?: string\n styles?: BlogPostStyles\n unstyled?: boolean\n siteUrl?: string\n children?: (props: {\n post: BlogPostType\n tableOfContents: TocItem[]\n relatedPosts: BlogPostType[]\n }) => React.ReactNode\n}\n\n// ============================================================================\n// CLASS HELPER — pick custom `styles` class or default `.sk-blog-*` class\n// ============================================================================\n\nfunction cls(unstyled: boolean, styles: BlogPostStyles, key: keyof BlogPostStyles, defaultClass: string, extra?: string): string | undefined {\n if (unstyled) return styles[key] || undefined\n const base = styles[key] || defaultClass\n return extra ? `${base} ${extra}` : base\n}\n\n// ============================================================================\n// BLOG POST COMPONENT\n// ============================================================================\n\nexport async function BlogPost({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n slug,\n showToc = true,\n showRelated = true,\n relatedCount = 3,\n showAuthor = true,\n basePath = '/blog',\n className,\n styles = {},\n unstyled = false,\n siteUrl,\n children,\n}: BlogPostServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n const post = await fetchBlogPost(apiUrl, apiKey, slug)\n\n // ---------- NOT FOUND ----------\n if (!post) {\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogPostCss }} />}\n <div className={cls(unstyled, styles, 'notFound', 'sk-blog-not-found', className)}>\n <h1>Post Not Found</h1>\n <p>The blog post you’re looking for doesn’t exist or has been removed.</p>\n <a href={basePath}>← Back to Blog</a>\n </div>\n </>\n )\n }\n\n // ---------- PREPARE DATA ----------\n const rawContent = post.content_html || post.content || ''\n const content = ensureHtml(rawContent)\n const siteUrlResolved = resolveBlogSiteUrl(siteUrl)\n const contentWithExternalTargets = addExternalLinkTargets(content, siteUrlResolved)\n const tableOfContents = showToc ? generateTableOfContents(content) : []\n const relatedPosts = showRelated ? await fetchRelatedPosts(apiUrl, apiKey, post.id, relatedCount) : []\n\n const faqRaw = (post.faq_items ?? (post as { faqItems?: unknown }).faqItems) as Array<{ question: string; answer: string }> | undefined\n const faqItemsProcessed = faqRaw?.map((item) => ({\n ...item,\n answer: addExternalLinkTargets(item.answer || '', siteUrlResolved),\n })) ?? faqRaw\n\n // Client islands, dynamically imported so tsup splits + 'use client'-stamps\n // their chunks (same pattern for both).\n const { BlogViewTracker } = await import('./BlogViewTracker')\n\n // ---------- CUSTOM RENDER ----------\n if (children) {\n return (\n <>\n <BlogViewTracker slug={post.slug} />\n {children({ post, tableOfContents, relatedPosts })}\n </>\n )\n }\n\n const { BlogPostFaqSection } = await import('./BlogPostFaqSection')\n\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })\n : null\n\n const hasToc = showToc && tableOfContents.length > 0\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogPostCss }} />}\n <BlogViewTracker slug={post.slug} />\n\n <article className={cls(unstyled, styles, 'article', 'sk-blog-article', className)}>\n {/* ===== Header ===== */}\n <header className={cls(unstyled, styles, 'header', 'sk-blog-header')}>\n <nav className={cls(unstyled, styles, 'breadcrumb', 'sk-blog-breadcrumb')}>\n <a href={basePath} className={styles.breadcrumbLink || undefined}>Blog</a>\n {post.category && (\n <>\n <span className=\"sk-blog-breadcrumb-sep\">/</span>\n <a\n href={`${basePath}?category=${post.category}`}\n className={styles.breadcrumbLink || undefined}\n >\n {typeof post.category === 'string' ? post.category : (post.category as any)?.name || 'Uncategorized'}\n </a>\n </>\n )}\n </nav>\n\n <h1 className={cls(unstyled, styles, 'title', 'sk-blog-title')}>{post.title}</h1>\n\n {post.subtitle && (\n <p className={cls(unstyled, styles, 'subtitle', 'sk-blog-subtitle')}>{post.subtitle}</p>\n )}\n\n <div className={cls(unstyled, styles, 'meta', 'sk-blog-meta')}>\n {post.author && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>\n By {typeof post.author === 'string' ? post.author : post.author.name}\n </span>\n )}\n {post.author && date && <span className=\"sk-blog-meta-dot\" />}\n {date && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>{date}</span>\n )}\n {date && readingTimeMinutes(post) && <span className=\"sk-blog-meta-dot\" />}\n {readingTimeMinutes(post) && (\n <span className={cls(unstyled, styles, 'metaItem', 'sk-blog-meta-item')}>\n {readingTimeMinutes(post)} min read\n </span>\n )}\n </div>\n </header>\n\n {/* ===== Featured Image ===== */}\n {post.featured_image && (\n <figure className={cls(unstyled, styles, 'featuredImageWrapper', 'sk-blog-featured-wrap')}>\n <img\n src={post.featured_image}\n alt={post.featured_image_alt || post.title}\n className={cls(unstyled, styles, 'featuredImage', 'sk-blog-featured-img')}\n />\n </figure>\n )}\n\n {/* ===== Content + TOC ===== */}\n <div className={cls(unstyled, styles, 'contentLayout', hasToc ? 'sk-blog-layout sk-blog-layout--has-toc' : 'sk-blog-layout')}>\n <div\n className={cls(unstyled, styles, 'content', 'sk-blog-content')}\n dangerouslySetInnerHTML={{ __html: contentWithExternalTargets }}\n />\n\n {hasToc && (\n <aside className={cls(unstyled, styles, 'tocSidebar', 'sk-blog-toc')}>\n <h4 className={cls(unstyled, styles, 'tocTitle', 'sk-blog-toc-title')}>On This Page</h4>\n <ul className={cls(unstyled, styles, 'tocList', 'sk-blog-toc-list')}>\n {tableOfContents.map((item) => (\n <li\n key={item.id}\n className={cls(unstyled, styles, 'tocItem', item.level > 2 ? `sk-blog-toc-indent-${item.level}` : '')}\n >\n <a href={`#${item.id}`} className={styles.tocLink || undefined}>{item.text}</a>\n </li>\n ))}\n </ul>\n </aside>\n )}\n </div>\n\n {/* ===== Tags ===== */}\n {post.tags && post.tags.length > 0 && (\n <div className={cls(unstyled, styles, 'tags', 'sk-blog-tags')}>\n {post.tags.map((tag, index) => {\n const tagName = typeof tag === 'string' ? tag : tag?.name || ''\n return (\n <a key={`${tagName}-${index}`} href={`${basePath}?tag=${encodeURIComponent(tagName)}`} className={cls(unstyled, styles, 'tag', 'sk-blog-tag')}>\n #{tagName}\n </a>\n )\n })}\n </div>\n )}\n\n {/* ===== Service Callouts ===== */}\n <ServiceCallouts\n callouts={(post as any).service_callouts ?? (post as any).serviceCallouts ?? []}\n unstyled={unstyled}\n />\n\n {/* ===== FAQ ===== */}\n <BlogPostFaqSection\n items={(faqItemsProcessed ?? []) as any[]}\n unstyled={unstyled}\n styles={unstyled ? {\n section: styles.faqSection,\n title: styles.faqTitle,\n item: styles.faqItem,\n question: styles.faqQuestion,\n answerInner: styles.faqAnswer,\n } : undefined}\n />\n\n {/* ===== Author ===== */}\n {showAuthor && post.author && typeof post.author === 'object' && (\n <AuthorSection author={normalizeAuthorForDisplay(post.author)} className={styles.authorCard} unstyled={unstyled} />\n )}\n\n {/* ===== Cluster Navigation ===== */}\n {(() => {\n const clusterNav = getClusterNav(post as any)\n if (!clusterNav) return null\n return (\n <ClusterNavigation\n navigation={clusterNav}\n basePath={basePath}\n unstyled={unstyled}\n />\n )\n })()}\n\n {/* ===== Related Posts ===== */}\n {showRelated && relatedPosts.length > 0 && (\n <section className={cls(unstyled, styles, 'relatedSection', 'sk-blog-related')}>\n <h2 className={cls(unstyled, styles, 'relatedTitle', 'sk-blog-related-title')}>Related Posts</h2>\n <div className={cls(unstyled, styles, 'relatedGrid', 'sk-blog-related-grid')}>\n {relatedPosts.map((rp) => (\n <a key={rp.id} href={`${basePath}/${rp.slug}`} className={cls(unstyled, styles, 'relatedCard', 'sk-blog-related-card')}>\n {rp.featured_image && <img src={rp.featured_image} alt={rp.title} />}\n <div className=\"sk-blog-related-card-body\">\n <h3>{rp.title}</h3>\n {rp.excerpt && <p>{rp.excerpt.slice(0, 120)}...</p>}\n </div>\n </a>\n ))}\n </div>\n </section>\n )}\n </article>\n </>\n )\n}\n\n// ============================================================================\n// AUTHOR HELPERS\n// ============================================================================\n\nfunction normalizeAuthorForDisplay(author: Record<string, unknown> | BlogAuthor): BlogAuthor & { sameAs?: string[]; title?: string } {\n const a = author as Record<string, unknown>\n return {\n id: (a.id as string) ?? 'author',\n project_id: (a.project_id as string) ?? '',\n name: (a.name as string) ?? 'Author',\n slug: (a.slug as string) ?? 'author',\n bio: (a.bio as string) ?? undefined,\n avatar_url: (a.avatar_url as string) ?? (a.image as string) ?? (a.image_url as string) ?? undefined,\n website: (a.website as string) ?? (a.url as string) ?? undefined,\n social_links: a.social_links as BlogAuthor['social_links'] | undefined,\n // Real API columns (blog_authors) — previously dropped here, so\n // AuthorSection could never render socials from a live author row.\n linkedin_url: (a.linkedin_url as string) ?? undefined,\n twitter_url: (a.twitter_url as string) ?? undefined,\n website_url: (a.website_url as string) ?? undefined,\n same_as: (a.same_as as string[]) ?? undefined,\n is_active: (a.is_active as boolean) ?? true,\n ...(normalizeSocialProfiles(a.socialProfiles).length\n ? { sameAs: normalizeSocialProfiles(a.socialProfiles) }\n : {}),\n ...(a.title ? { title: a.title as string } : {}),\n } as BlogAuthor & { sameAs?: string[]; title?: string }\n}\n\n/**\n * socialProfiles arrives as either string[] (site config) or the\n * {linkedin, twitter} object sonor-api emits — accept both into sameAs.\n */\nfunction normalizeSocialProfiles(value: unknown): string[] {\n if (Array.isArray(value)) return value.filter((v): v is string => typeof v === 'string' && !!v)\n if (value && typeof value === 'object') {\n return Object.values(value as Record<string, unknown>).filter(\n (v): v is string => typeof v === 'string' && !!v\n )\n }\n return []\n}\n\nfunction AuthorSection({ author, className, unstyled = false }: { author: BlogAuthor & { sameAs?: string[]; title?: string }; className?: string; unstyled?: boolean }) {\n const base = unstyled ? className : (className || 'sk-blog-author')\n const socialLinks = getAuthorSocialLinks(author)\n return (\n <section className={base || undefined}>\n {author.avatar_url && <img src={author.avatar_url} alt={author.name} className={unstyled ? undefined : 'sk-blog-author-avatar'} />}\n <div>\n <h3 className={unstyled ? undefined : 'sk-blog-author-name'}>{author.name}</h3>\n {'title' in author && author.title && <p className={unstyled ? undefined : 'sk-blog-author-title'}>{author.title}</p>}\n {author.bio && <p className={unstyled ? undefined : 'sk-blog-author-bio'}>{author.bio}</p>}\n {socialLinks.length > 0 && (\n <div className={unstyled ? undefined : 'sk-blog-author-links'}>\n {socialLinks.map((link) => <a key={link.label} href={link.href} target=\"_blank\" rel=\"noopener noreferrer\">{link.label}</a>)}\n </div>\n )}\n {'sameAs' in author && author.sameAs && author.sameAs.length > 0 && socialLinks.length === 0 && (\n <div className={unstyled ? undefined : 'sk-blog-author-links'}>\n {author.sameAs.map((url, i) => <a key={i} href={url} target=\"_blank\" rel=\"noopener noreferrer\">Profile</a>)}\n </div>\n )}\n </div>\n </section>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Blog List Component\n *\n * Fetches and displays a list of blog posts with pagination, filtering, and sorting.\n *\n * Ships with world-class default styling via scoped `.sk-bloglist-*` classes.\n * No configuration needed — just `<BlogList basePath=\"/blog\" />`.\n *\n * Override with `styles` prop (per-element class names) or `unstyled` for\n * complete control. The `children` render prop gives full data access.\n */\n\nimport React from 'react'\nimport type { BlogListResult, BlogPost, BlogCategory } from './types'\nimport { blogListCss } from './blog-styles'\nimport { readingTimeMinutes } from './reading-time'\n\n// ============================================================================\n// STYLE TYPES\n// ============================================================================\n\nexport interface BlogListStyles {\n container?: string\n categoryNav?: string\n categoryLink?: string\n categoryLinkActive?: string\n categoryLinkInactive?: string\n grid?: string\n card?: string\n cardImageWrapper?: string\n cardImage?: string\n cardBody?: string\n cardMeta?: string\n cardCategory?: string\n cardDate?: string\n cardTitle?: string\n cardTitleLink?: string\n cardExcerpt?: string\n cardFooter?: string\n cardAuthor?: string\n cardReadingTime?: string\n cardReadMore?: string\n pagination?: string\n paginationLink?: string\n paginationInfo?: string\n emptyState?: string\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\ninterface FetchBlogListParams {\n apiUrl: string\n apiKey: string\n category?: string\n tag?: string\n author?: string\n featured?: boolean\n search?: string\n /** Topic cluster slug — the server resolves it to cluster_id */\n cluster?: string\n page?: number\n perPage?: number\n orderBy?: 'published_at' | 'title' | 'view_count'\n order?: 'asc' | 'desc'\n}\n\nasync function fetchBlogList(params: FetchBlogListParams): Promise<BlogListResult> {\n const {\n apiUrl,\n apiKey,\n category,\n tag,\n author,\n featured,\n search,\n cluster,\n page = 1,\n perPage = 12,\n orderBy = 'published_at',\n order = 'desc',\n } = params\n\n const queryParams = new URLSearchParams()\n if (category) queryParams.set('category', category)\n if (tag) queryParams.set('tag', tag)\n if (author) queryParams.set('author', author)\n if (featured) queryParams.set('featured', 'true')\n if (search) queryParams.set('search', search)\n if (cluster) queryParams.set('cluster', cluster)\n queryParams.set('page', String(page))\n queryParams.set('per_page', String(perPage))\n queryParams.set('order_by', orderBy)\n queryParams.set('order', order)\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts?${queryParams}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) {\n console.error('[Blog] Failed to fetch posts:', response.statusText)\n return emptyResult()\n }\n\n const data = await response.json()\n return {\n posts: data.posts || [],\n pagination: {\n page: data.pagination?.page || 1,\n perPage: data.pagination?.per_page || 12,\n total: data.pagination?.total || 0,\n totalPages: data.pagination?.total_pages || 0,\n hasNext: data.pagination?.has_next || false,\n hasPrev: data.pagination?.has_prev || false,\n },\n }\n } catch (error) {\n console.error('[Blog] Error fetching posts:', error)\n return emptyResult()\n }\n}\n\nfunction emptyResult(): BlogListResult {\n return { posts: [], pagination: { page: 1, perPage: 12, total: 0, totalPages: 0, hasNext: false, hasPrev: false } }\n}\n\nasync function fetchCategories(apiUrl: string, apiKey: string): Promise<BlogCategory[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\n// ============================================================================\n// CLASS HELPER\n// ============================================================================\n\nfunction cls(unstyled: boolean, styles: BlogListStyles, key: keyof BlogListStyles, defaultClass: string, extra?: string): string | undefined {\n if (unstyled) return styles[key] || undefined\n const base = styles[key] || defaultClass\n return extra ? `${base} ${extra}` : base\n}\n\n// ============================================================================\n// BLOG LIST COMPONENT\n// ============================================================================\n\nexport interface BlogListServerProps {\n apiUrl?: string\n apiKey?: string\n category?: string\n tag?: string\n /** Author slug (preferred) or display name; slug filtering requires the current Sonor API */\n author?: string\n featured?: boolean\n search?: string\n /**\n * Topic cluster slug — pairs with getTopicCluster. Note: an unknown slug\n * yields an UNfiltered list (pre-existing API behavior).\n */\n cluster?: string\n page?: number\n perPage?: number\n orderBy?: 'published_at' | 'title' | 'view_count'\n order?: 'asc' | 'desc'\n showCategoryFilter?: boolean\n showPagination?: boolean\n className?: string\n basePath?: string\n styles?: BlogListStyles\n unstyled?: boolean\n renderPost?: (post: BlogPost) => React.ReactNode\n children?: (props: {\n posts: BlogPost[]\n pagination: BlogListResult['pagination']\n categories: BlogCategory[]\n }) => React.ReactNode\n}\n\nexport async function BlogList({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n category,\n tag,\n author,\n featured,\n search,\n cluster,\n page = 1,\n perPage = 12,\n orderBy = 'published_at',\n order = 'desc',\n showCategoryFilter = false,\n showPagination = true,\n className,\n basePath = '/blog',\n styles = {},\n unstyled = false,\n renderPost,\n children,\n}: BlogListServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n const [blogData, categories] = await Promise.all([\n fetchBlogList({ apiUrl, apiKey, category, tag, author, featured, search, cluster, page, perPage, orderBy, order }),\n showCategoryFilter ? fetchCategories(apiUrl, apiKey) : Promise.resolve([]),\n ])\n\n if (children) {\n return children({ posts: blogData.posts, pagination: blogData.pagination, categories })\n }\n\n const { posts, pagination } = blogData\n\n // ---------- EMPTY STATE ----------\n if (posts.length === 0) {\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogListCss }} />}\n <div className={cls(unstyled, styles, 'emptyState', 'sk-bloglist sk-bloglist-empty', className)}>\n <p>No posts found.</p>\n </div>\n </>\n )\n }\n\n return (\n <>\n {!unstyled && <style dangerouslySetInnerHTML={{ __html: blogListCss }} />}\n\n <div className={cls(unstyled, styles, 'container', 'sk-bloglist', className)}>\n {/* Category Filter */}\n {showCategoryFilter && categories.length > 0 && (\n <nav className={cls(unstyled, styles, 'categoryNav', 'sk-bloglist-cats')}>\n <a\n href={basePath}\n className={cls(unstyled, styles, 'categoryLink', !category ? 'sk-bloglist-cat sk-bloglist-cat--active' : 'sk-bloglist-cat')}\n >\n All\n </a>\n {categories.map((cat) => (\n <a\n key={cat.slug}\n href={`${basePath}?category=${cat.slug}`}\n className={cls(unstyled, styles, 'categoryLink', category === cat.slug ? 'sk-bloglist-cat sk-bloglist-cat--active' : 'sk-bloglist-cat')}\n >\n {cat.name} ({cat.post_count})\n </a>\n ))}\n </nav>\n )}\n\n {/* Blog Grid */}\n <div className={cls(unstyled, styles, 'grid', 'sk-bloglist-grid')}>\n {posts.map((post) =>\n renderPost ? (\n <React.Fragment key={post.id}>{renderPost(post)}</React.Fragment>\n ) : (\n <BlogPostCard key={post.id} post={post} basePath={basePath} styles={styles} unstyled={unstyled} />\n )\n )}\n </div>\n\n {/* Pagination */}\n {showPagination && pagination.totalPages > 1 && (\n <nav className={cls(unstyled, styles, 'pagination', 'sk-bloglist-pagination')}>\n {pagination.hasPrev && (\n <a href={buildPaginationUrl(basePath, page - 1, category)} className={cls(unstyled, styles, 'paginationLink', 'sk-bloglist-page-link')}>\n ← Previous\n </a>\n )}\n <span className={cls(unstyled, styles, 'paginationInfo', 'sk-bloglist-page-info')}>\n Page {pagination.page} of {pagination.totalPages}\n </span>\n {pagination.hasNext && (\n <a href={buildPaginationUrl(basePath, page + 1, category)} className={cls(unstyled, styles, 'paginationLink', 'sk-bloglist-page-link')}>\n Next →\n </a>\n )}\n </nav>\n )}\n </div>\n </>\n )\n}\n\n// ============================================================================\n// BLOG POST CARD (Default rendering)\n// ============================================================================\n\ninterface BlogPostCardProps {\n post: BlogPost\n basePath: string\n styles?: BlogListStyles\n unstyled?: boolean\n}\n\nfunction BlogPostCard({ post, basePath, styles = {}, unstyled = false }: BlogPostCardProps) {\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })\n : null\n\n return (\n <article className={cls(unstyled, styles, 'card', 'sk-bloglist-card')}>\n {post.featured_image && (\n <a href={`${basePath}/${post.slug}`} className={cls(unstyled, styles, 'cardImageWrapper', 'sk-bloglist-card-img-link')}>\n <img\n src={post.featured_image}\n alt={post.featured_image_alt || post.title}\n className={cls(unstyled, styles, 'cardImage', 'sk-bloglist-card-img')}\n />\n </a>\n )}\n\n <div className={cls(unstyled, styles, 'cardBody', 'sk-bloglist-card-body')}>\n {/* Meta */}\n <div className={cls(unstyled, styles, 'cardMeta', 'sk-bloglist-card-meta')}>\n {post.category && (\n <span className={cls(unstyled, styles, 'cardCategory', 'sk-bloglist-card-category')}>\n {typeof post.category === 'string' ? post.category : post.category?.name || 'Uncategorized'}\n </span>\n )}\n {(post as any).article_type && (\n <span className=\"sk-bloglist-card-article-type\" style={{\n display: 'inline-flex', alignItems: 'center',\n padding: '0.0625rem 0.375rem', borderRadius: '9999px',\n fontSize: '0.6875rem', fontWeight: 500,\n background: (post as any).article_type === 'pillar' ? 'rgba(99,102,241,0.1)' : 'rgba(99,102,241,0.05)',\n color: '#6366f1', border: '1px solid rgba(99,102,241,0.15)',\n textTransform: 'capitalize',\n }}>\n {(post as any).article_type}\n </span>\n )}\n {date && <span className={cls(unstyled, styles, 'cardDate', 'sk-bloglist-card-date')}>{date}</span>}\n </div>\n\n {/* Title */}\n <h3 className={cls(unstyled, styles, 'cardTitle', 'sk-bloglist-card-title')}>\n <a href={`${basePath}/${post.slug}`} className={styles.cardTitleLink || undefined}>\n {post.title}\n </a>\n </h3>\n\n {/* Excerpt */}\n {post.excerpt && (\n <p className={cls(unstyled, styles, 'cardExcerpt', 'sk-bloglist-card-excerpt')}>\n {post.excerpt}\n </p>\n )}\n\n {/* Footer */}\n <div className={cls(unstyled, styles, 'cardFooter', 'sk-bloglist-card-footer')}>\n {post.author && (\n <span className={cls(unstyled, styles, 'cardAuthor', '')}>\n By {typeof post.author === 'string' ? post.author : post.author.name}\n </span>\n )}\n {readingTimeMinutes(post) && (\n <span className={cls(unstyled, styles, 'cardReadingTime', '')}>\n {readingTimeMinutes(post)} min read\n </span>\n )}\n </div>\n </div>\n </article>\n )\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\nfunction buildPaginationUrl(basePath: string, page: number, category?: string): string {\n const params = new URLSearchParams()\n params.set('page', String(page))\n if (category) params.set('category', category)\n return `${basePath}?${params}`\n}\n","/**\n * @sonordev/site-kit/blog - Blog Sidebar Component\n * \n * A reusable sidebar for blog pages with categories, recent posts,\n * tags, newsletter signup, and custom widgets.\n */\n\nimport React from 'react'\nimport type { BlogPost, BlogCategory, BlogTag } from './types'\nimport { widgetStyle, widgetTitleStyle } from './widget-styles'\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\nasync function fetchRecentPosts(\n apiUrl: string,\n apiKey: string,\n limit: number = 5\n): Promise<BlogPost[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/recent?limit=${limit}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching recent posts:', error)\n return []\n }\n}\n\nasync function fetchCategories(apiUrl: string, apiKey: string): Promise<BlogCategory[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\nasync function fetchTags(apiUrl: string, apiKey: string): Promise<BlogTag[]> {\n try {\n const response = await fetch(`${apiUrl}/public/blog/tags`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.tags || []\n } catch (error) {\n console.error('[Blog] Error fetching tags:', error)\n return []\n }\n}\n\n// ============================================================================\n// BLOG SIDEBAR COMPONENT\n// ============================================================================\n\nexport interface BlogSidebarProps {\n /** Portal API URL */\n apiUrl?: string\n /** Project API key */\n apiKey?: string\n /** Show categories widget */\n showCategories?: boolean\n /** Show recent posts widget */\n showRecentPosts?: boolean\n /** Number of recent posts to show */\n recentPostsCount?: number\n /** Show tags widget */\n showTags?: boolean\n /** Show search widget */\n showSearch?: boolean\n /** Base URL for blog links */\n basePath?: string\n /** Custom class name */\n className?: string\n /** Current category filter (for highlighting) */\n currentCategory?: string\n /** Additional widgets to render */\n children?: React.ReactNode\n}\n\nexport async function BlogSidebar({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n showCategories = true,\n showRecentPosts = true,\n recentPostsCount = 5,\n showTags = true,\n showSearch = true,\n basePath = '/blog',\n className,\n currentCategory,\n children,\n}: BlogSidebarProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for sidebar')\n return null\n }\n\n // Fetch data in parallel\n const [categories, recentPosts, tags] = await Promise.all([\n showCategories ? fetchCategories(apiUrl, apiKey) : Promise.resolve([]),\n showRecentPosts ? fetchRecentPosts(apiUrl, apiKey, recentPostsCount) : Promise.resolve([]),\n showTags ? fetchTags(apiUrl, apiKey) : Promise.resolve([]),\n ])\n\n return (\n <aside className={className} style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>\n {/* Search Widget */}\n {showSearch && <SearchWidget basePath={basePath} />}\n\n {/* Categories Widget */}\n {showCategories && categories.length > 0 && (\n <CategoriesWidget\n categories={categories}\n basePath={basePath}\n currentCategory={currentCategory}\n />\n )}\n\n {/* Recent Posts Widget */}\n {showRecentPosts && recentPosts.length > 0 && (\n <RecentPostsWidget posts={recentPosts} basePath={basePath} />\n )}\n\n {/* Tags Widget */}\n {showTags && tags.length > 0 && (\n <TagsWidget tags={tags} basePath={basePath} />\n )}\n\n {/* Custom Widgets */}\n {children}\n </aside>\n )\n}\n\n// ============================================================================\n// WIDGET COMPONENTS\n// ============================================================================\n\nfunction SearchWidget({ basePath }: { basePath: string }) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Search</h4>\n <form action={basePath} method=\"get\">\n <input\n type=\"search\"\n name=\"search\"\n placeholder=\"Search posts...\"\n style={{\n width: '100%',\n padding: '10px 12px',\n border: '1px solid var(--sk-border)',\n borderRadius: 8,\n fontSize: 14,\n }}\n />\n </form>\n </div>\n )\n}\n\nfunction CategoriesWidget({\n categories,\n basePath,\n currentCategory,\n}: {\n categories: BlogCategory[]\n basePath: string\n currentCategory?: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Categories</h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n <li style={{ marginBottom: 8 }}>\n <a\n href={basePath}\n style={{\n ...categoryLinkStyle,\n fontWeight: !currentCategory ? 600 : 400,\n color: !currentCategory ? 'var(--sk-primary)' : 'var(--sk-text-primary)',\n }}\n >\n All Posts\n </a>\n </li>\n {categories.map((cat) => (\n <li key={cat.slug} style={{ marginBottom: 8 }}>\n <a\n href={`${basePath}?category=${cat.slug}`}\n style={{\n ...categoryLinkStyle,\n fontWeight: currentCategory === cat.slug ? 600 : 400,\n color: currentCategory === cat.slug ? 'var(--sk-primary)' : 'var(--sk-text-primary)',\n }}\n >\n {cat.name}\n <span style={{ color: 'var(--sk-text-tertiary)', marginLeft: 8 }}>({cat.post_count})</span>\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nfunction RecentPostsWidget({\n posts,\n basePath,\n}: {\n posts: BlogPost[]\n basePath: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Recent Posts</h4>\n <ul style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {posts.map((post) => {\n const date = post.published_at\n ? new Date(post.published_at).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n })\n : null\n\n return (\n <li\n key={post.id}\n style={{\n marginBottom: 16,\n paddingBottom: 16,\n borderBottom: '1px solid var(--sk-border)',\n }}\n >\n <div style={{ display: 'flex', gap: 12 }}>\n {post.featured_image && (\n <a href={`${basePath}/${post.slug}`}>\n <img\n src={post.featured_image}\n alt=\"\"\n style={{\n width: 64,\n height: 48,\n objectFit: 'cover',\n borderRadius: 6,\n flexShrink: 0,\n }}\n />\n </a>\n )}\n <div style={{ flex: 1, minWidth: 0 }}>\n <a\n href={`${basePath}/${post.slug}`}\n style={{\n fontSize: 14,\n fontWeight: 500,\n color: 'var(--sk-text-primary)',\n textDecoration: 'none',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {post.title}\n </a>\n {date && (\n <span style={{ fontSize: 12, color: 'var(--sk-text-tertiary)', display: 'block', marginTop: 4 }}>\n {date}\n </span>\n )}\n </div>\n </div>\n </li>\n )\n })}\n </ul>\n </div>\n )\n}\n\nfunction TagsWidget({\n tags,\n basePath,\n}: {\n tags: BlogTag[]\n basePath: string\n}) {\n return (\n <div style={widgetStyle}>\n <h4 style={widgetTitleStyle}>Popular Tags</h4>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {tags.slice(0, 15).map((tag) => (\n <a\n key={tag.slug}\n href={`${basePath}?tag=${encodeURIComponent(tag.name)}`}\n style={{\n padding: '4px 10px',\n backgroundColor: 'var(--sk-bg-elevated)',\n borderRadius: 9999,\n fontSize: 12,\n color: 'var(--sk-text-primary)',\n textDecoration: 'none',\n transition: 'background-color 0.2s',\n }}\n >\n {tag.name}\n </a>\n ))}\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// STYLES\n// ============================================================================\n\n\nconst categoryLinkStyle: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n fontSize: 14,\n textDecoration: 'none',\n}\n","/**\n * @sonordev/site-kit/blog - Blog Layout Component\n * \n * A complete blog layout with sidebar, responsive design, and optional hero.\n * Use this to wrap your blog pages for consistent styling.\n */\n\nimport React from 'react'\nimport { BlogSidebar, BlogSidebarProps } from './BlogSidebar'\n\n// ============================================================================\n// BLOG LAYOUT COMPONENT\n// ============================================================================\n\nexport interface BlogLayoutProps {\n /** Portal API URL */\n apiUrl?: string\n /** Project API key */\n apiKey?: string\n /** Layout style: 'sidebar-right', 'sidebar-left', 'full-width' */\n layout?: 'sidebar-right' | 'sidebar-left' | 'full-width'\n /** Show sidebar */\n showSidebar?: boolean\n /** Sidebar props */\n sidebarProps?: Partial<BlogSidebarProps>\n /** Hero section config */\n hero?: {\n title?: string\n subtitle?: string\n backgroundImage?: string\n backgroundColor?: string\n }\n /** Max width for content */\n maxWidth?: number\n /** Base URL for blog links */\n basePath?: string\n /** Custom class name */\n className?: string\n /** Current category (for sidebar highlighting) */\n currentCategory?: string\n /** Main content */\n children: React.ReactNode\n}\n\nexport async function BlogLayout({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n layout = 'sidebar-right',\n showSidebar = true,\n sidebarProps = {},\n hero,\n maxWidth = 1280,\n basePath = '/blog',\n className,\n currentCategory,\n children,\n}: BlogLayoutProps) {\n const hasSidebar = showSidebar && layout !== 'full-width'\n\n return (\n <div className={className}>\n {/* Hero Section */}\n {hero && (\n <section\n style={{\n padding: '60px 20px',\n backgroundColor: hero.backgroundColor || 'var(--sk-primary)',\n backgroundImage: hero.backgroundImage ? `url(${hero.backgroundImage})` : undefined,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n color: 'var(--sk-bg)',\n textAlign: 'center',\n }}\n >\n <div style={{ maxWidth, margin: '0 auto' }}>\n {hero.title && (\n <h1\n style={{\n fontSize: 'clamp(32px, 5vw, 48px)',\n fontWeight: 700,\n marginBottom: 16,\n }}\n >\n {hero.title}\n </h1>\n )}\n {hero.subtitle && (\n <p\n style={{\n fontSize: 'clamp(16px, 2vw, 20px)',\n opacity: 0.9,\n maxWidth: 600,\n margin: '0 auto',\n }}\n >\n {hero.subtitle}\n </p>\n )}\n </div>\n </section>\n )}\n\n {/* Main Content Area */}\n <div\n style={{\n maxWidth,\n margin: '0 auto',\n padding: '40px 20px',\n }}\n >\n <div\n style={{\n display: hasSidebar ? 'grid' : 'block',\n gridTemplateColumns: hasSidebar\n ? layout === 'sidebar-left'\n ? '300px 1fr'\n : '1fr 300px'\n : undefined,\n gap: 48,\n }}\n >\n {/* Sidebar (Left Position) */}\n {hasSidebar && layout === 'sidebar-left' && (\n <BlogSidebar\n apiUrl={apiUrl}\n apiKey={apiKey}\n basePath={basePath}\n currentCategory={currentCategory}\n {...sidebarProps}\n />\n )}\n\n {/* Main Content */}\n <main style={{ minWidth: 0 }}>{children}</main>\n\n {/* Sidebar (Right Position) */}\n {hasSidebar && layout === 'sidebar-right' && (\n <BlogSidebar\n apiUrl={apiUrl}\n apiKey={apiKey}\n basePath={basePath}\n currentCategory={currentCategory}\n {...sidebarProps}\n />\n )}\n </div>\n </div>\n </div>\n )\n}\n\n// ============================================================================\n// BLOG PAGE WRAPPER\n// ============================================================================\n\n/**\n * Convenience wrapper for a complete blog index page\n */\nexport interface BlogPageProps extends Omit<BlogLayoutProps, 'children'> {\n /** List component to render */\n listComponent: React.ReactNode\n}\n\nexport async function BlogPage({ listComponent, ...layoutProps }: BlogPageProps) {\n return <BlogLayout {...layoutProps}>{listComponent}</BlogLayout>\n}\n\n/**\n * Convenience wrapper for a single blog post page\n */\nexport interface BlogPostPageProps extends Omit<BlogLayoutProps, 'children'> {\n /** Post component to render */\n postComponent: React.ReactNode\n}\n\nexport async function BlogPostPage({ postComponent, ...layoutProps }: BlogPostPageProps) {\n return (\n <BlogLayout {...layoutProps} showSidebar={false} layout=\"full-width\">\n <div style={{ maxWidth: 800, margin: '0 auto' }}>{postComponent}</div>\n </BlogLayout>\n )\n}\n\n// ============================================================================\n// CATEGORY PAGE WRAPPER\n// ============================================================================\n\nexport interface CategoryPageProps extends BlogLayoutProps {\n /** Category slug being viewed */\n category: string\n /** Category display name */\n categoryName?: string\n /** List component */\n listComponent: React.ReactNode\n}\n\nexport async function CategoryPage({\n category,\n categoryName,\n listComponent,\n hero,\n ...layoutProps\n}: CategoryPageProps) {\n const categoryHero = hero || {\n title: categoryName || category,\n subtitle: `Browse all posts in ${categoryName || category}`,\n backgroundColor: 'var(--sk-primary)',\n }\n\n return (\n <BlogLayout {...layoutProps} hero={categoryHero} currentCategory={category}>\n {listComponent}\n </BlogLayout>\n )\n}\n","/**\n * @sonordev/site-kit/blog - Related Posts Component\n * \n * Fetches and displays related blog posts via Portal API\n */\n\nimport React from 'react'\nimport type { RelatedPostsProps, BlogPost } from './types'\n\nasync function fetchRelatedPosts(\n apiUrl: string,\n apiKey: string,\n currentPostId: string,\n limit: number\n): Promise<BlogPost[]> {\n try {\n // `/public/blog/*`, not `/api/public/blog/*`. public-blog.controller is\n // one of only two public controllers whose @Controller() omits the `api/`\n // segment (public-images is the other); every other blog call in this\n // module already uses the short form. This one did not, so related posts\n // 404'd and silently rendered as none.\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n // The controller reads snake_case `current_post_id` and looks the post\n // up by id. camelCase here meant the id arrived as undefined, the\n // lookup matched nothing, and this rendered \"no related posts\" as a\n // clean 200 — the silent sibling of the 404 path bug fixed above.\n body: JSON.stringify({\n current_post_id: currentPostId,\n limit,\n }),\n })\n \n if (!response.ok) {\n console.error('Failed to fetch related posts:', response.statusText)\n return []\n }\n \n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('Failed to fetch related posts:', error)\n return []\n }\n}\n\ninterface RelatedPostsServerProps {\n apiUrl?: string\n apiKey?: string\n currentPostId: string\n limit?: number\n className?: string\n renderItem?: (post: BlogPost) => React.ReactNode\n}\n\nexport async function RelatedPosts({\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey = process.env.SONOR_API_KEY || '',\n currentPostId,\n limit = 3,\n className,\n renderItem,\n}: RelatedPostsServerProps) {\n if (!apiKey) {\n console.warn('[Blog] No API key configured for RelatedPosts')\n return null\n }\n \n const posts = await fetchRelatedPosts(apiUrl, apiKey, currentPostId, limit)\n\n if (posts.length === 0) return null\n\n return (\n <section className={className}>\n <h3 style={{ marginBottom: 16 }}>Related Posts</h3>\n <div style={{ display: 'grid', gap: 16 }}>\n {posts.map((post) =>\n renderItem ? (\n renderItem(post)\n ) : (\n <article key={post.id} style={{ borderBottom: '1px solid var(--sk-border)', paddingBottom: 16 }}>\n {post.featured_image && (\n <img\n src={post.featured_image}\n alt={post.title}\n style={{\n width: '100%',\n height: 120,\n objectFit: 'cover',\n borderRadius: 8,\n marginBottom: 8,\n }}\n />\n )}\n <a href={`/blog/${post.slug}`} style={{ textDecoration: 'none' }}>\n <h4 style={{ margin: 0, color: 'inherit' }}>{post.title}</h4>\n </a>\n {post.excerpt && (\n <p style={{ margin: '4px 0 0', fontSize: 14, color: 'var(--sk-text-secondary)' }}>\n {post.excerpt}\n </p>\n )}\n </article>\n )\n )}\n </div>\n </section>\n )\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/blog/excerpt.ts","../src/blog/server-core.ts"],"names":["resolveServerApiConfig","description"],"mappings":"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","file":"chunk-JBGRXICL.js","sourcesContent":["/**\n * Excerpt sanitizing for blog metadata, schema and feeds.\n *\n * Pure (no `server-only` chain) so it is unit-testable and safe to reuse.\n * Source of truth for turning a stored excerpt into display-safe prose.\n */\n\n/**\n * Turn a stored excerpt into something safe to put in a meta description,\n * a schema `description`, or an RSS `<description>`.\n *\n * The AI blog pipeline stores content as JSON sections\n * (`{\"heading\": \"## ...\", \"content\": \"## ...\\n\\nIf you're asking **how**...\"}`)\n * and that value has been shipping verbatim into <meta name=\"description\">.\n * nkylawfirm.com had three live articles whose SERP snippet was raw JSON with\n * markdown asterisks and literal \\n. Parse the sections out, strip markdown,\n * and cap at a sentence boundary.\n */\nexport function sanitizeExcerpt(raw: string | undefined | null, maxLength = 160): string {\n if (!raw) return ''\n let text = String(raw).trim()\n\n // JSON section(s) — take the prose, not the heading, and never the braces.\n if (text.startsWith('{') || text.startsWith('[')) {\n const fromSections = (value: unknown): string => {\n const list = Array.isArray(value) ? value : [value]\n return list\n .map((s) => (s && typeof s === 'object' ? (s as any).content || (s as any).heading || '' : ''))\n .filter(Boolean)\n .join(' ')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n // Concatenated objects: \"{...}\\n\\n{...}\" — take the first.\n const first = text.split(/\\}\\s*[\\r\\n]+\\s*\\{/)[0]\n try {\n parsed = JSON.parse(first.endsWith('}') ? first : `${first}}`)\n } catch {\n parsed = null\n }\n }\n text = parsed ? fromSections(parsed) : text.replace(/[{}\"[\\]]/g, ' ')\n }\n\n const plain = text\n .replace(/```[\\s\\S]*?```/g, ' ') // fenced code\n .replace(/!\\[[^\\]]*\\]\\([^)]*\\)/g, ' ') // images\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1') // links -> text\n .replace(/^#{1,6}\\s+/gm, '') // headings\n .replace(/[*_~`>]/g, '') // emphasis / quotes / code\n .replace(/\\\\n/g, ' ') // literal escaped newlines\n .replace(/\\s+/g, ' ')\n .trim()\n\n if (plain.length <= maxLength) return plain\n\n // Prefer a sentence boundary, then a word boundary.\n const window = plain.slice(0, maxLength + 1)\n const lastStop = Math.max(window.lastIndexOf('. '), window.lastIndexOf('? '), window.lastIndexOf('! '))\n if (lastStop > maxLength * 0.5) return window.slice(0, lastStop + 1).trim()\n\n const cut = plain.slice(0, maxLength)\n const lastSpace = cut.lastIndexOf(' ')\n return `${(lastSpace > maxLength * 0.6 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—–-]+$/, '')}…`\n}\n","/**\n * @sonordev/site-kit/blog/server\n *\n * Data and metadata helpers only (no React components). For `BlogPost` / `BlogList`\n * in the App Router, import from `@sonordev/site-kit/blog/server-ui` so Next never\n * treats `getAllBlogSlugs` / `generateBlogStaticParams` as client code.\n */\n\nimport type { Metadata } from 'next'\nimport type { BlogPost as BlogPostRecord, BlogAuthor, TocItem, TopicCluster, ClusterNavigation } from './types'\n\n/**\n * Server key/URL resolution — SINGLE SOURCE OF TRUTH.\n *\n * Every fetcher below resolves its API config through `resolveServerApiConfig`.\n * Do NOT re-fork a local `getConfig()` here: this file used to carry a drifted\n * copy of that helper, and the copy grew a `process.env.NEXT_PUBLIC_SONOR_API_KEY`\n * fallback the canonical one never had. Because Next inlines `NEXT_PUBLIC_*` into\n * every bundle a module lands in, and this module was reachable from the\n * client-stamped `@sonordev/site-kit/blog` barrel, that fallback published the\n * site's raw `sonor_` project key to the browser. One diverging copy, one leaked\n * credential.\n *\n * This import also carries `server-only` transitively, which is the point: if a\n * client component ever reaches this module again, the consumer's build fails\n * loudly instead of silently shipping an `x-api-key` fetch to visitors.\n */\nimport { resolveServerApiConfig } from '../server/server-fetch'\nimport { sanitizeExcerpt } from './excerpt'\n\nexport { sanitizeExcerpt }\n\n// ============================================================================\n// SEO VALIDATION UTILITIES\n// ============================================================================\n\nexport const SEO_LIMITS = {\n title: { min: 30, max: 60, recommended: 55 },\n metaDescription: { min: 120, max: 160, recommended: 155 },\n excerpt: { min: 100, max: 300, recommended: 200 },\n slug: { max: 75 },\n focusKeyphrase: { min: 2, max: 4, words: true }, // 2-4 words\n} as const\n\nexport interface SeoValidationResult {\n field: string\n value: string\n length: number\n limit: { min?: number; max: number; recommended?: number }\n status: 'good' | 'warning' | 'error'\n message: string\n}\n\n/**\n * Validate SEO title (60 chars max, keyword-first recommended)\n */\nexport function validateSeoTitle(title: string, focusKeyphrase?: string): SeoValidationResult {\n const length = title.length\n let status: SeoValidationResult['status'] = 'good'\n let message = 'Title length is optimal'\n\n if (length > SEO_LIMITS.title.max) {\n status = 'error'\n message = `Title is ${length - SEO_LIMITS.title.max} characters too long (max ${SEO_LIMITS.title.max})`\n } else if (length < SEO_LIMITS.title.min) {\n status = 'warning'\n message = `Title is short (${length}/${SEO_LIMITS.title.min} min)`\n } else if (focusKeyphrase && !title.toLowerCase().includes(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Focus keyphrase not found in title'\n } else if (focusKeyphrase && !title.toLowerCase().startsWith(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Title should start with focus keyphrase for best results'\n }\n\n return { field: 'title', value: title, length, limit: SEO_LIMITS.title, status, message }\n}\n\n/**\n * Validate meta description (150-160 chars, benefit-driven)\n */\nexport function validateMetaDescription(description: string, focusKeyphrase?: string): SeoValidationResult {\n const length = description.length\n let status: SeoValidationResult['status'] = 'good'\n let message = 'Meta description is optimal'\n\n if (length > SEO_LIMITS.metaDescription.max) {\n status = 'error'\n message = `Description will be truncated (${length}/${SEO_LIMITS.metaDescription.max})`\n } else if (length < SEO_LIMITS.metaDescription.min) {\n status = 'warning'\n message = `Description is short (${length}/${SEO_LIMITS.metaDescription.min} min)`\n } else if (focusKeyphrase && !description.toLowerCase().includes(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Focus keyphrase not found in description'\n }\n\n return { field: 'meta_description', value: description, length, limit: SEO_LIMITS.metaDescription, status, message }\n}\n\n/**\n * Full SEO validation for a blog post\n */\nexport function validateBlogPostSeo(post: Partial<BlogPostRecord>): SeoValidationResult[] {\n const results: SeoValidationResult[] = []\n const focusKeyphrase = post.focus_keyphrase\n\n if (post.meta_title || post.title) {\n results.push(validateSeoTitle(post.meta_title || post.title || '', focusKeyphrase))\n }\n\n if (post.meta_description) {\n results.push(validateMetaDescription(post.meta_description, focusKeyphrase))\n }\n\n // Check H1 alignment (title should match keyword)\n if (post.title && focusKeyphrase) {\n const titleLower = post.title.toLowerCase()\n const keyLower = focusKeyphrase.toLowerCase()\n if (!titleLower.includes(keyLower)) {\n results.push({\n field: 'h1_alignment',\n value: post.title,\n length: post.title.length,\n limit: { max: 100 },\n status: 'warning',\n message: 'H1 (title) should include the focus keyphrase',\n })\n }\n }\n\n // Check word count (1200-2500 recommended for long-form)\n if (post.word_count !== undefined) {\n let wordStatus: SeoValidationResult['status'] = 'good'\n let wordMessage = 'Content length is optimal for SEO'\n \n if (post.word_count < 600) {\n wordStatus = 'error'\n wordMessage = `Content is thin (${post.word_count} words). Aim for 1200+ words.`\n } else if (post.word_count < 1200) {\n wordStatus = 'warning'\n wordMessage = `Content is short (${post.word_count} words). Long-form (1200-2500) ranks better.`\n } else if (post.word_count > 2500) {\n wordMessage = `Comprehensive content (${post.word_count} words). Consider splitting into a topic cluster.`\n }\n\n results.push({\n field: 'word_count',\n value: String(post.word_count),\n length: post.word_count,\n limit: { min: 1200, max: 2500, recommended: 1800 },\n status: wordStatus,\n message: wordMessage,\n })\n }\n\n return results\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\n/**\n * Fetch a blog post by slug (server-side)\n */\nexport async function getBlogPost(slug: string): Promise<BlogPostRecord | null> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return null\n }\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) return null\n\n const data = await response.json()\n return data.post || null\n } catch (error) {\n console.error('[Blog] Error fetching post:', error)\n return null\n }\n}\n\n/**\n * Fetch all blog post slugs for static generation\n */\nexport async function getAllBlogSlugs(): Promise<\n { slug: string; id?: string; last_modified?: string; article_type?: string }[]\n> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return []\n }\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/slugs`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.slugs || []\n } catch (error) {\n console.error('[Blog] Error fetching slugs:', error)\n return []\n }\n}\n\n/**\n * Fetch blog categories\n */\nexport async function getBlogCategories(): Promise<{ name: string; slug: string; post_count: number }[]> {\n const config = resolveServerApiConfig()\n if (!config) return []\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\n// ============================================================================\n// METADATA GENERATION\n// ============================================================================\n\ninterface BlogMetadataOptions {\n /** Site name for og:site_name */\n siteName?: string\n /** Base URL of the site */\n siteUrl?: string\n /** URL path prefix for blog index and posts (default `/blog`, e.g. `/insights`) */\n blogBasePath?: string\n /** Default OG image */\n defaultImage?: string\n /** Twitter handle */\n twitterHandle?: string\n}\n\nfunction blogPathPrefix(options: BlogMetadataOptions): string {\n const raw = (options.blogBasePath ?? '/blog').trim() || '/blog'\n const withSlash = raw.startsWith('/') ? raw : `/${raw}`\n return withSlash.replace(/\\/$/, '') || '/blog'\n}\n\n/**\n * Generate metadata for a blog post page\n */\nexport async function generateBlogPostMetadata(\n slug: string,\n options: BlogMetadataOptions = {}\n): Promise<Metadata> {\n const post = await getBlogPost(slug)\n const { siteName, siteUrl = '', defaultImage, twitterHandle } = options\n const base = blogPathPrefix(options)\n\n if (!post) {\n return {\n title: 'Post Not Found',\n description: 'The requested blog post could not be found.',\n }\n }\n\n const title = post.meta_title || post.title\n const description = sanitizeExcerpt(post.meta_description || post.excerpt)\n // og_image / featured_image_width / featured_image_height never existed in\n // blog_posts (verified against the live schema) — reading them always\n // produced undefined. Resolution goes straight to featured_image.\n const image = post.featured_image || defaultImage\n const url = `${siteUrl}${base}/${post.slug}`\n\n return {\n title,\n description,\n openGraph: {\n title: post.og_title || title,\n description: post.og_description || description,\n url,\n siteName,\n type: 'article',\n publishedTime: post.published_at,\n authors: post.author ? [typeof post.author === 'string' ? post.author : post.author.name] : undefined,\n images: image\n ? [\n {\n url: image,\n width: 1200,\n height: 630,\n alt: post.featured_image_alt || post.title,\n },\n ]\n : undefined,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : undefined,\n creator: twitterHandle,\n },\n alternates: {\n canonical: post.canonical_url || url,\n },\n other: {\n 'article:published_time': post.published_at || '',\n 'article:section': typeof post.category === 'string' ? post.category : (post.category?.name || ''),\n },\n }\n}\n\n/**\n * Generate metadata for the blog index page\n */\nexport function generateBlogIndexMetadata(options: BlogMetadataOptions & {\n title?: string\n description?: string\n}): Metadata {\n const {\n title = 'Blog',\n description = 'Read our latest articles and insights.',\n siteName,\n siteUrl = '',\n defaultImage,\n twitterHandle,\n } = options\n const base = blogPathPrefix(options)\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url: `${siteUrl}${base}`,\n siteName,\n type: 'website',\n images: defaultImage ? [{ url: defaultImage }] : undefined,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: defaultImage ? [defaultImage] : undefined,\n creator: twitterHandle,\n },\n }\n}\n\n/**\n * Generate metadata for a category page\n */\nexport function generateBlogCategoryMetadata(\n categoryName: string,\n options: BlogMetadataOptions & { categorySlug?: string } = {}\n): Metadata {\n const { siteName, siteUrl = '', defaultImage, blogBasePath = '/blog' } = options\n const title = `${categoryName} - Blog`\n const description = `Browse all posts in ${categoryName}.`\n // The URL wants the route slug, not the display name: lowercasing \"Case\n // Studies\" produced /blog/category/case%20studies against a real route of\n // /blog/category/case-studies. Callers that have the slug pass it; the\n // fallback slugifies the name the same way the dashboard does.\n const slug =\n options.categorySlug ??\n categoryName\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url: `${siteUrl}${blogBasePath}/category/${slug}`,\n siteName,\n type: 'website',\n images: defaultImage ? [{ url: defaultImage }] : undefined,\n },\n }\n}\n\n// ============================================================================\n// STATIC PARAMS GENERATION\n// ============================================================================\n\n/**\n * Generate static params for blog post pages\n * Usage: export const generateStaticParams = generateBlogStaticParams\n */\nexport async function generateBlogStaticParams(): Promise<{ slug: string }[]> {\n const slugs = await getAllBlogSlugs()\n return slugs.map((s) => ({ slug: s.slug }))\n}\n\n/**\n * Generate static params for category pages\n * Usage: export const generateStaticParams = generateCategoryStaticParams\n */\nexport async function generateCategoryStaticParams(): Promise<{ category: string }[]> {\n const categories = await getBlogCategories()\n return categories.map((c) => ({ category: c.slug }))\n}\n\n// ============================================================================\n// SITEMAP GENERATION\n// ============================================================================\n\ninterface SitemapEntry {\n url: string\n lastModified?: Date\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\n/**\n * Generate sitemap entries for blog posts\n */\nexport async function generateBlogSitemap(\n siteUrl: string\n): Promise<SitemapEntry[]> {\n const slugs = await getAllBlogSlugs()\n const categories = await getBlogCategories()\n const clusters = await getTopicClusters()\n\n const entries: SitemapEntry[] = [\n // Blog index\n {\n url: `${siteUrl}/blog`,\n changeFrequency: 'daily',\n priority: 0.8,\n },\n ]\n\n // Cluster landing pages\n clusters.forEach((cluster) => {\n entries.push({\n url: `${siteUrl}/blog/cluster/${cluster.cluster_slug}`,\n changeFrequency: 'weekly',\n priority: 0.8,\n })\n })\n\n // Category pages\n categories.forEach((cat) => {\n entries.push({\n url: `${siteUrl}/blog/category/${cat.slug}`,\n changeFrequency: 'weekly',\n priority: 0.6,\n })\n })\n\n // Individual posts — pillar posts get higher priority (0.9 vs 0.7)\n slugs.forEach((post) => {\n const isPillar = (post as any).article_type === 'pillar'\n entries.push({\n url: `${siteUrl}/blog/${post.slug}`,\n lastModified: post.last_modified ? new Date(post.last_modified) : undefined,\n changeFrequency: isPillar ? 'weekly' : 'monthly',\n priority: isPillar ? 0.9 : 0.7,\n })\n })\n\n return entries\n}\n\n// ============================================================================\n// JSON-LD SCHEMA GENERATION\n// ============================================================================\n\n/**\n * Generate JSON-LD schema for a blog post\n */\nexport function generateBlogPostSchema(\n post: BlogPostRecord,\n options: { siteUrl?: string; siteName?: string; logoUrl?: string } = {}\n): object {\n const { siteUrl = '', siteName, logoUrl } = options\n\n const schema: any = {\n '@context': 'https://schema.org',\n '@type': 'BlogPosting',\n headline: post.title,\n description: sanitizeExcerpt(post.excerpt || post.meta_description),\n url: `${siteUrl}/blog/${post.slug}`,\n datePublished: post.published_at,\n dateModified: post.updated_at,\n author: {\n '@type': 'Person',\n name: typeof post.author === 'string' ? post.author : post.author?.name,\n },\n }\n\n if (post.featured_image) {\n // A bare URL string is valid schema.org — better than an ImageObject\n // carrying fabricated dimensions (the width/height columns don't exist).\n schema.image = post.featured_image\n }\n\n if (siteName || logoUrl) {\n schema.publisher = {\n '@type': 'Organization',\n name: siteName,\n logo: logoUrl\n ? {\n '@type': 'ImageObject',\n url: logoUrl,\n }\n : undefined,\n }\n }\n\n // Add FAQ schema if present\n if (post.faq_items && Array.isArray(post.faq_items) && post.faq_items.length > 0) {\n schema.mainEntity = {\n '@type': 'FAQPage',\n mainEntity: post.faq_items.map((faq: { question: string; answer: string }) => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n }\n }\n\n return schema\n}\n\n/**\n * Generate JSON-LD schema for blog index/listing page\n */\nexport function generateBlogListSchema(\n options: { siteUrl?: string; siteName?: string; description?: string } = {}\n): object {\n const { siteUrl = '', siteName, description } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Blog',\n name: siteName ? `${siteName} Blog` : 'Blog',\n description: description || 'Our latest articles and insights.',\n url: `${siteUrl}/blog`,\n }\n}\n\n// ============================================================================\n// FAQ SCHEMA (for PAA rankings)\n// ============================================================================\n\n/**\n * Generate standalone FAQ schema (great for PAA inclusion)\n */\nexport function generateFaqSchema(\n faqItems: { question: string; answer: string }[]\n): object | null {\n if (!faqItems || faqItems.length === 0) return null\n\n return {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqItems.map((faq) => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n }\n}\n\n// ============================================================================\n// HOWTO SCHEMA (for step-by-step posts)\n// ============================================================================\n\nexport interface HowToStep {\n name: string\n text: string\n image?: string\n url?: string\n}\n\n/**\n * Generate HowTo schema for step-by-step posts\n */\nexport function generateHowToSchema(\n post: BlogPostRecord,\n steps: HowToStep[],\n options: { siteUrl?: string } = {}\n): object {\n const { siteUrl = '' } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'HowTo',\n name: post.title,\n description: sanitizeExcerpt(post.excerpt || post.meta_description),\n image: post.featured_image,\n totalTime: post.reading_time ? `PT${post.reading_time}M` : undefined,\n step: steps.map((step, index) => ({\n '@type': 'HowToStep',\n position: index + 1,\n name: step.name,\n text: step.text,\n image: step.image,\n url: step.url || `${siteUrl}/blog/${post.slug}#step-${index + 1}`,\n })),\n }\n}\n\n// ============================================================================\n// RSS FEED GENERATION\n// ============================================================================\n\ninterface RssFeedOptions {\n siteUrl: string\n siteName: string\n description?: string\n language?: string\n copyright?: string\n managingEditor?: string\n webMaster?: string\n ttl?: number // Time to live in minutes\n imageUrl?: string\n}\n\n/**\n * Maximum posts a feed will accumulate. Preserves the historical intent of the\n * old `?limit=100` request (which the API silently ignored — it only reads\n * `per_page`, capped at 50, so feeds were stuck at the 12-post default).\n */\nconst FEED_MAX_POSTS = 100\n\n/**\n * Fetch all published blog posts for RSS feed.\n *\n * Paginates with `per_page`/`page` — the only pagination params the deployed\n * controller reads — accumulating up to FEED_MAX_POSTS. A mid-loop failure\n * returns what was accumulated so far: a partial feed beats an empty one.\n */\nexport async function getAllBlogPosts(): Promise<BlogPostRecord[]> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return []\n }\n const { apiUrl, apiKey } = config\n\n const posts: BlogPostRecord[] = []\n let page = 1\n try {\n while (posts.length < FEED_MAX_POSTS) {\n const response = await fetch(\n `${apiUrl}/public/blog/posts?per_page=50&page=${page}`,\n {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n }\n )\n\n if (!response.ok) break\n\n const data = await response.json()\n posts.push(...(data.posts || []))\n if (!data.pagination?.has_next) break\n page += 1\n }\n } catch (error) {\n console.error('[Blog] Error fetching posts for RSS:', error)\n }\n return posts.slice(0, FEED_MAX_POSTS)\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(text: string): string {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n\n/**\n * Strip HTML tags for RSS descriptions\n */\nfunction stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim()\n}\n\n/**\n * Generate RSS 2.0 feed XML\n */\nexport async function generateRssFeed(options: RssFeedOptions): Promise<string> {\n const {\n siteUrl,\n siteName,\n description = 'Latest blog posts and insights',\n language = 'en-us',\n copyright,\n managingEditor,\n webMaster,\n ttl = 60,\n imageUrl,\n } = options\n\n const posts = await getAllBlogPosts()\n const now = new Date().toUTCString()\n\n let rss = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n <channel>\n <title>${escapeXml(siteName)}</title>\n <link>${siteUrl}</link>\n <description>${escapeXml(description)}</description>\n <language>${language}</language>\n <lastBuildDate>${now}</lastBuildDate>\n <pubDate>${now}</pubDate>\n <ttl>${ttl}</ttl>\n <atom:link href=\"${siteUrl}/blog/rss.xml\" rel=\"self\" type=\"application/rss+xml\"/>\n`\n\n if (copyright) {\n rss += ` <copyright>${escapeXml(copyright)}</copyright>\\n`\n }\n\n if (managingEditor) {\n rss += ` <managingEditor>${escapeXml(managingEditor)}</managingEditor>\\n`\n }\n\n if (webMaster) {\n rss += ` <webMaster>${escapeXml(webMaster)}</webMaster>\\n`\n }\n\n if (imageUrl) {\n rss += ` <image>\n <url>${imageUrl}</url>\n <title>${escapeXml(siteName)}</title>\n <link>${siteUrl}</link>\n </image>\\n`\n }\n\n // Add each post as an item with FULL content (not excerpts)\n for (const post of posts) {\n const postUrl = `${siteUrl}/blog/${post.slug}`\n const pubDate = post.published_at ? new Date(post.published_at).toUTCString() : now\n const author = typeof post.author === 'string' ? post.author : post.author?.name || 'Unknown'\n \n // Use full content_html if available, otherwise content\n const fullContent = post.content_html || post.content || ''\n const description = sanitizeExcerpt(post.excerpt, 300) || stripHtml(fullContent).substring(0, 300) + '...'\n\n rss += ` <item>\n <title>${escapeXml(post.title)}</title>\n <link>${postUrl}</link>\n <guid isPermaLink=\"true\">${postUrl}</guid>\n <description>${escapeXml(description)}</description>\n <content:encoded><![CDATA[${fullContent}]]></content:encoded>\n <pubDate>${pubDate}</pubDate>\n <author>${escapeXml(author)}</author>\n`\n\n if (post.category) {\n const categoryName = typeof post.category === 'string' ? post.category : post.category.name\n rss += ` <category>${escapeXml(categoryName)}</category>\\n`\n }\n\n if (post.tags && Array.isArray(post.tags)) {\n for (const tag of post.tags) {\n const tagName = typeof tag === 'string' ? tag : tag.name\n rss += ` <category>${escapeXml(tagName)}</category>\\n`\n }\n }\n\n if (post.featured_image) {\n rss += ` <enclosure url=\"${post.featured_image}\" type=\"image/jpeg\"/>\\n`\n }\n\n rss += ` </item>\\n`\n }\n\n rss += ` </channel>\n</rss>`\n\n return rss\n}\n\n/**\n * Generate Atom feed XML\n */\nexport async function generateAtomFeed(options: RssFeedOptions): Promise<string> {\n const {\n siteUrl,\n siteName,\n description = 'Latest blog posts and insights',\n managingEditor,\n } = options\n\n const posts = await getAllBlogPosts()\n const now = new Date().toISOString()\n\n let atom = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\">\n <title>${escapeXml(siteName)}</title>\n <subtitle>${escapeXml(description)}</subtitle>\n <link href=\"${siteUrl}/blog/feed.xml\" rel=\"self\"/>\n <link href=\"${siteUrl}\"/>\n <id>${siteUrl}/blog</id>\n <updated>${now}</updated>\n`\n\n if (managingEditor) {\n atom += ` <author>\n <name>${escapeXml(managingEditor)}</name>\n </author>\\n`\n }\n\n for (const post of posts) {\n const postUrl = `${siteUrl}/blog/${post.slug}`\n const updated = post.updated_at || post.published_at || now\n const published = post.published_at || now\n const author = typeof post.author === 'string' ? post.author : post.author?.name || 'Unknown'\n const fullContent = post.content_html || post.content || ''\n\n atom += ` <entry>\n <title>${escapeXml(post.title)}</title>\n <link href=\"${postUrl}\"/>\n <id>${postUrl}</id>\n <updated>${new Date(updated).toISOString()}</updated>\n <published>${new Date(published).toISOString()}</published>\n <author>\n <name>${escapeXml(author)}</name>\n </author>\n <summary>${escapeXml(sanitizeExcerpt(post.excerpt, 300) || stripHtml(fullContent).substring(0, 300))}</summary>\n <content type=\"html\"><![CDATA[${fullContent}]]></content>\n </entry>\\n`\n }\n\n atom += `</feed>`\n\n return atom\n}\n\n// ============================================================================\n// TOPIC CLUSTER SUPPORT\n// ============================================================================\n\n/**\n * Fetch all active topic clusters for the project.\n * Uses the real cluster data from Portal API (not heuristic-based).\n */\nexport async function getTopicClusters(): Promise<TopicCluster[]> {\n const config = resolveServerApiConfig()\n if (!config) return []\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/clusters`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n\n return (data.clusters || []).map((c: any) => ({\n id: c.id,\n cluster_name: c.cluster_name,\n cluster_slug: c.cluster_slug,\n core_topic: c.core_topic,\n primary_entity: c.primary_entity,\n industry: c.industry,\n geo_target: c.geo_target,\n commercial_goal: c.commercial_goal,\n pillar_post_id: c.pillar_post_id,\n target_service_page: c.target_service_page,\n article_count: c.article_count,\n created_at: c.created_at,\n pillar: null,\n supports: [],\n interlink_map: [],\n }))\n } catch (error) {\n console.error('[Blog] Error fetching topic clusters:', error)\n return []\n }\n}\n\n/**\n * Fetch a single topic cluster with its pillar and support articles.\n */\nexport async function getTopicCluster(slug: string): Promise<TopicCluster | null> {\n const config = resolveServerApiConfig()\n if (!config) return null\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/clusters/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return null\n const data = await response.json()\n\n return {\n id: data.id,\n cluster_name: data.cluster_name,\n cluster_slug: data.cluster_slug,\n core_topic: data.core_topic,\n primary_entity: data.primary_entity,\n industry: data.industry,\n geo_target: data.geo_target,\n commercial_goal: data.commercial_goal,\n // Authoritative column once the API's detail response ships it;\n // derived from the embedded (published) pillar until then.\n pillar_post_id: data.pillar_post_id ?? data.pillar?.id,\n target_service_page: data.target_service_page,\n article_count: data.article_count,\n created_at: data.created_at,\n pillar: data.pillar || null,\n supports: data.supports || [],\n interlink_map: data.interlink_map || [],\n }\n } catch (error) {\n console.error('[Blog] Error fetching topic cluster:', error)\n return null\n }\n}\n\n/**\n * Get cluster navigation context for a blog post.\n * Returns the cluster name, pillar link, and sibling articles.\n */\nexport function getClusterNavigation(post: BlogPostRecord): ClusterNavigation | null {\n if (!post.cluster_id && !post.cluster_slug) return null\n\n const isPillar = post.article_type === 'pillar'\n\n // Mirrored copy: BlogPost.tsx has an identical builder. Keep the two in\n // sync — they CANNOT be consolidated because blog/index is a CLIENT_ENTRY\n // that must never import blog/server-core (see build-entries.ts and\n // client-entry-boundary.test.ts).\n return {\n cluster_name: post.cluster_name || '',\n cluster_slug: post.cluster_slug || '',\n pillar: isPillar\n ? null\n : post.parent_pillar_slug\n ? {\n slug: post.parent_pillar_slug,\n title: post.parent_pillar_title || '',\n category: post.parent_pillar_category || undefined,\n }\n : null,\n siblings: post.sibling_articles || [],\n is_pillar: isPillar,\n }\n}\n\n/**\n * @deprecated Use getTopicCluster(slug) instead. This naive heuristic picks\n * the longest post as pillar. Real cluster data is now managed in the Sonor dashboard.\n */\nexport async function identifyTopicClusters(categorySlug: string): Promise<{\n pillar: BlogPostRecord\n supportingPosts: BlogPostRecord[]\n internalLinks: Array<{ from: string; to: string; anchor: string }>\n} | null> {\n console.warn(\n '[Blog] identifyTopicClusters() is deprecated. Use getTopicCluster(slug) for real cluster data managed in the Sonor dashboard.'\n )\n const posts = await getPostsByCategory(categorySlug)\n if (posts.length < 3) return null\n\n const sortedByLength = [...posts].sort((a, b) => (b.word_count || 0) - (a.word_count || 0))\n const pillar = sortedByLength[0]\n const supportingPosts = sortedByLength.slice(1)\n\n const internalLinks: Array<{ from: string; to: string; anchor: string }> = []\n for (const support of supportingPosts) {\n internalLinks.push({ from: pillar.slug, to: support.slug, anchor: support.title })\n internalLinks.push({ from: support.slug, to: pillar.slug, anchor: pillar.title })\n }\n\n return { pillar, supportingPosts, internalLinks }\n}\n\n/**\n * Fetch posts by category for topic cluster organization\n */\nexport async function getPostsByCategory(categorySlug: string): Promise<BlogPostRecord[]> {\n const config = resolveServerApiConfig()\n if (!config) return []\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts?category=${encodeURIComponent(categorySlug)}&per_page=50`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n if (!response.ok) return []\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching category posts:', error)\n return []\n }\n}\n\n// ============================================================================\n// CLUSTER SCHEMA GENERATION\n// ============================================================================\n\n/**\n * Generate ItemList schema for a cluster's pillar page.\n * Wraps supporting posts as a structured list Google can parse.\n */\nexport function generateClusterItemListSchema(\n cluster: TopicCluster,\n options: { siteUrl?: string; basePath?: string } = {}\n): object {\n const { siteUrl = '', basePath = '/blog' } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'ItemList',\n name: cluster.cluster_name,\n description: `Articles about ${cluster.core_topic}`,\n numberOfItems: cluster.supports.length,\n itemListElement: cluster.supports.map((post, i) => ({\n '@type': 'ListItem',\n position: i + 1,\n name: post.title,\n url: `${siteUrl}${basePath}/${post.slug}`,\n })),\n }\n}\n\n/**\n * Generate Article schema with cluster relationship (isPartOf / hasPart).\n * - Support articles get `isPartOf` pointing to the pillar.\n * - Pillar articles get `hasPart` listing all supports.\n */\nexport function generateClusterArticleSchema(\n post: BlogPostRecord,\n cluster: TopicCluster,\n options: { siteUrl?: string; basePath?: string; siteName?: string; logoUrl?: string } = {}\n): object {\n const { siteUrl = '', basePath = '/blog', siteName, logoUrl } = options\n const isPillar = post.article_type === 'pillar'\n\n const schema: any = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: post.title,\n description: sanitizeExcerpt(post.excerpt || post.meta_description),\n url: `${siteUrl}${basePath}/${post.slug}`,\n datePublished: post.published_at,\n dateModified: post.updated_at,\n author: {\n '@type': 'Person',\n name: typeof post.author === 'string' ? post.author : (post.author as any)?.name,\n },\n keywords: post.focus_keyphrase || post.keywords,\n }\n\n if (post.featured_image) {\n // A bare URL string is valid schema.org — better than an ImageObject\n // carrying fabricated dimensions (the width/height columns don't exist).\n schema.image = post.featured_image\n }\n\n if (siteName || logoUrl) {\n schema.publisher = {\n '@type': 'Organization',\n name: siteName,\n ...(logoUrl && { logo: { '@type': 'ImageObject', url: logoUrl } }),\n }\n }\n\n // Cluster relationships\n if (isPillar && cluster.supports.length > 0) {\n schema.hasPart = cluster.supports.map((s) => ({\n '@type': 'Article',\n headline: s.title,\n url: `${siteUrl}${basePath}/${s.slug}`,\n }))\n } else if (!isPillar && cluster.pillar) {\n schema.isPartOf = {\n '@type': 'Article',\n headline: cluster.pillar.title,\n url: `${siteUrl}${basePath}/${cluster.pillar.slug}`,\n }\n }\n\n // Geo targeting\n if (cluster.geo_target) {\n schema.spatialCoverage = {\n '@type': 'Place',\n name: cluster.geo_target,\n }\n }\n\n return schema\n}\n\n/**\n * Generate BreadcrumbList schema for a cluster-linked post.\n * Path: Home > Blog > Cluster > Article\n */\nexport function generateClusterBreadcrumbSchema(\n post: BlogPostRecord,\n cluster: TopicCluster,\n options: { siteUrl?: string; siteName?: string; basePath?: string } = {}\n): object {\n const { siteUrl = '', siteName = 'Home', basePath = '/blog' } = options\n\n const items: any[] = [\n { '@type': 'ListItem', position: 1, name: siteName, item: siteUrl },\n { '@type': 'ListItem', position: 2, name: 'Blog', item: `${siteUrl}${basePath}` },\n {\n '@type': 'ListItem',\n position: 3,\n name: cluster.cluster_name,\n item: `${siteUrl}${basePath}/cluster/${cluster.cluster_slug}`,\n },\n {\n '@type': 'ListItem',\n position: 4,\n name: post.title,\n item: `${siteUrl}${basePath}/${post.slug}`,\n },\n ]\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items,\n }\n}\n\n/**\n * Generate CollectionPage schema for a cluster landing page.\n */\nexport function generateClusterLandingSchema(\n cluster: TopicCluster,\n options: { siteUrl?: string; basePath?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', basePath = '/blog', siteName } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'CollectionPage',\n name: cluster.cluster_name,\n description: `Comprehensive guide to ${cluster.core_topic}`,\n url: `${siteUrl}${basePath}/cluster/${cluster.cluster_slug}`,\n ...(siteName && {\n isPartOf: { '@type': 'WebSite', name: siteName, url: siteUrl },\n }),\n mainEntity: cluster.pillar\n ? {\n '@type': 'Article',\n headline: cluster.pillar.title,\n url: `${siteUrl}${basePath}/${cluster.pillar.slug}`,\n }\n : undefined,\n hasPart: cluster.supports.map((s) => ({\n '@type': 'Article',\n headline: s.title,\n url: `${siteUrl}${basePath}/${s.slug}`,\n })),\n }\n}\n\n/**\n * Generate metadata for a cluster landing page (Next.js generateMetadata).\n */\nexport async function generateClusterPageMetadata(\n clusterSlug: string,\n options: { siteName?: string; siteUrl?: string; basePath?: string } = {}\n) {\n const cluster = await getTopicCluster(clusterSlug)\n if (!cluster) return {}\n\n const { siteName = '', siteUrl = '', basePath = '/blog' } = options\n const title = `${cluster.cluster_name}${siteName ? ` | ${siteName}` : ''}`\n const description = `Comprehensive guide to ${cluster.core_topic}. ${cluster.article_count} articles covering everything you need to know.`\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url: `${siteUrl}${basePath}/cluster/${cluster.cluster_slug}`,\n type: 'website',\n },\n }\n}\n\n/**\n * Generate \"Related Insights\" section data\n */\nexport async function getRelatedInsights(\n currentSlug: string,\n options: { limit?: number; category?: string } = {}\n): Promise<BlogPostRecord[]> {\n const config = resolveServerApiConfig()\n if (!config) return []\n const { apiUrl, apiKey } = config\n const { limit = 3 } = options\n // options.category is accepted for compatibility, but the endpoint derives\n // relatedness from the current post's own category server-side; a category\n // field in the body has always been ignored.\n\n // The endpoint takes `current_post_id` and looks the post up by id — it has\n // no slug path. Sending `slug` meant the lookup matched nothing and this\n // returned [] on every call since it shipped. Resolve the slug first (60s\n // cache via getBlogPost), then ask with the id.\n const current = await getBlogPost(currentSlug)\n if (!current?.id) return []\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n current_post_id: current.id,\n limit,\n }),\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching related posts:', error)\n return []\n }\n}\n\n// ============================================================================\n// BREADCRUMB SCHEMA\n// ============================================================================\n\n/**\n * Generate BreadcrumbList schema for blog navigation\n */\nexport function generateBreadcrumbSchema(\n post: BlogPostRecord,\n options: { siteUrl?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', siteName = 'Home' } = options\n\n const items = [\n {\n '@type': 'ListItem',\n position: 1,\n name: siteName,\n item: siteUrl,\n },\n {\n '@type': 'ListItem',\n position: 2,\n name: 'Blog',\n item: `${siteUrl}/blog`,\n },\n ]\n\n if (post.category) {\n const categoryName = typeof post.category === 'string' ? post.category : post.category.name\n const categorySlug = typeof post.category === 'string' \n ? post.category.toLowerCase().replace(/\\s+/g, '-')\n : post.category.slug\n\n items.push({\n '@type': 'ListItem',\n position: 3,\n name: categoryName,\n item: `${siteUrl}/blog/category/${categorySlug}`,\n })\n\n items.push({\n '@type': 'ListItem',\n position: 4,\n name: post.title,\n item: `${siteUrl}/blog/${post.slug}`,\n })\n } else {\n items.push({\n '@type': 'ListItem',\n position: 3,\n name: post.title,\n item: `${siteUrl}/blog/${post.slug}`,\n })\n }\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items,\n }\n}\n\n// ============================================================================\n// COMBINED SCHEMA (Article + FAQ + Breadcrumb)\n// ============================================================================\n\n/**\n * Generate all relevant schemas for a blog post in a single array\n * This is the recommended way to include multiple schemas.\n * When post has E-E-A-T schema (post.schema), use it instead of generating Article/FAQ.\n */\nexport function generateAllBlogSchemas(\n post: BlogPostRecord,\n options: { siteUrl?: string; siteName?: string; logoUrl?: string } = {}\n): object[] {\n const schemas: object[] = []\n\n // E-E-A-T: use pre-built schema from Signal when present. Single source of\n // truth for E-E-A-T schema resolution: the DB column is schema_json, which\n // the public API passes through raw today; `schema` is the mapped name the\n // dashboard serializer (and a future public mapping) uses. Do NOT also\n // normalize in getBlogPost — that would re-fork this rule.\n const eeatSchema = post.schema ?? post.schema_json\n if (eeatSchema) {\n const arr = Array.isArray(eeatSchema) ? eeatSchema : [eeatSchema]\n schemas.push(...arr)\n } else {\n // 1. Article/BlogPosting schema (always)\n schemas.push(generateBlogPostSchema(post, options))\n\n // 3. FAQ schema (if FAQs present)\n const faqItems = post.faq_items ?? (post as any).faqItems\n if (faqItems && faqItems.length > 0) {\n const faqSchema = generateFaqSchema(faqItems)\n if (faqSchema) schemas.push(faqSchema)\n }\n }\n\n // 2. Breadcrumb schema (always)\n schemas.push(generateBreadcrumbSchema(post, options))\n\n return schemas\n}\n\n// ============================================================================\n// AUTHOR PAGE DATA FETCHING\n// ============================================================================\n\n/**\n * Fetch a single author by slug\n */\nexport async function getAuthorBySlug(slug: string): Promise<BlogAuthor | null> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return null\n }\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/authors/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) return null\n\n const data = await response.json()\n return data.author || null\n } catch (error) {\n console.error('[Blog] Error fetching author:', error)\n return null\n }\n}\n\n/**\n * Fetch an author's posts by slug.\n *\n * `offset` pages through the controller's existing offset support. Older API\n * versions return a stripped `{name, slug}` author on this endpoint; when\n * that shape is detected the full author row is hydrated via getAuthorBySlug\n * (both fetches revalidate:60, so the extra hop is cached and disappears once\n * the API returns the full row itself).\n */\nexport async function getAuthorPosts(\n slug: string,\n limit = 20,\n offset = 0\n): Promise<{ author: BlogAuthor | null; posts: BlogPostRecord[]; total: number }> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return { author: null, posts: [], total: 0 }\n }\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(\n `${apiUrl}/public/blog/authors/${slug}/posts?limit=${limit}&offset=${offset}`,\n {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n }\n )\n\n if (!response.ok) return { author: null, posts: [], total: 0 }\n\n const data = await response.json()\n let author: BlogAuthor | null = data.author || null\n if (author && author.id === undefined) {\n try {\n const full = await getAuthorBySlug(slug)\n if (full) author = full\n } catch {\n // keep the stripped {name, slug} object\n }\n }\n return {\n author,\n posts: data.posts || [],\n total: data.total || 0,\n }\n } catch (error) {\n console.error('[Blog] Error fetching author posts:', error)\n return { author: null, posts: [], total: 0 }\n }\n}\n\n/**\n * Fetch all author slugs for static generation\n */\nexport async function getAllAuthorSlugs(): Promise<{ slug: string }[]> {\n const config = resolveServerApiConfig()\n if (!config) {\n console.warn('[Blog] No API key configured')\n return []\n }\n const { apiUrl, apiKey } = config\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/authors`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n const authors: BlogAuthor[] = data.authors || []\n return authors.map((a) => ({ slug: a.slug }))\n } catch (error) {\n console.error('[Blog] Error fetching author slugs:', error)\n return []\n }\n}\n\n/**\n * Generate static params for author pages\n * Usage: export const generateStaticParams = generateAuthorStaticParams\n */\nexport async function generateAuthorStaticParams(): Promise<{ slug: string }[]> {\n return getAllAuthorSlugs()\n}\n\n// ============================================================================\n// AUTHOR METADATA & SCHEMA\n// ============================================================================\n\n/**\n * Generate Next.js Metadata for an author page\n */\nexport function generateAuthorPageMetadata(\n author: BlogAuthor,\n options: { siteUrl?: string; siteName?: string } = {}\n): Metadata {\n const { siteUrl = '', siteName } = options\n const title = `${author.name}${author.title ? ` - ${author.title}` : ''}`\n const description = author.short_bio || author.bio || `Articles by ${author.name}`\n const url = `${siteUrl}/blog/author/${author.slug}`\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url,\n siteName,\n type: 'profile',\n images: author.avatar_url ? [{ url: author.avatar_url }] : undefined,\n },\n twitter: {\n card: 'summary',\n title,\n description,\n images: author.avatar_url ? [author.avatar_url] : undefined,\n },\n alternates: {\n canonical: author.author_page_url || url,\n },\n }\n}\n\n/**\n * Person JSON-LD for an author page.\n *\n * The implementation lives in `./author-schema` because it is pure, and\n * `AuthorPage` — which is exported from the client-stamped `blog` barrel —\n * needs it. Importing it from here instead would drag this entire server module\n * into the browser bundle. Re-exported so `@sonordev/site-kit/blog/server`\n * keeps its existing public API.\n */\nexport { generateAuthorSchema } from './author-schema'\n\n// -----------------------------------------------------------------------------\n// Blog UI (BlogPost, BlogList) lives in `@sonordev/site-kit/blog/server-ui`.\n// This entry must stay free of React components so Next never marks server\n// helpers (e.g. getAllBlogSlugs) as client — see tsup onSuccess \"use client\".\n// -----------------------------------------------------------------------------\n\n/** Portal blog post document shape (alias of `BlogPost` from `./types`) */\nexport type { BlogPost as BlogPostRecord } from './types'\n"]}
|