@sonordev/site-kit 7.1.0 → 7.1.2
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/AGENTS.md +2 -2
- package/CHANGELOG.md +21 -3426
- package/agent-manifest.json +1 -1
- package/dist/{AnalyticsProvider-ZMQUV33M.js → AnalyticsProvider-ZB33W6MC.js} +4 -4
- package/dist/{ArticleViewTracker-V7NUXYBY.js → ArticleViewTracker-GMHYLLLZ.js} +3 -3
- package/dist/{BlocksPopup-52EU7OUY.js → BlocksPopup-EA6LYL25.js} +4 -4
- package/dist/{ChatWidget-5BHMNR57.js → ChatWidget-UCDWMWCW.js} +5 -5
- package/dist/{EngageWidget-PCGLX7SO.js → EngageWidget-7ZYSK4GE.js} +4 -4
- package/dist/{FileField-TSFGNAMY.js → FileField-QKA3JB2Q.js} +3 -3
- package/dist/{FormSpotlight-XLBWEOTE.js → FormSpotlight-AQTIA5TP.js} +2 -2
- package/dist/{FormStage-IJQ5Q2X6.js → FormStage-FDTLTP3B.js} +2 -2
- package/dist/ManagedForm-H7BVAH2W.js +14 -0
- package/dist/{ManagedNewsletterForm-QAO3POLC.js → ManagedNewsletterForm-J6QSAGGP.js} +4 -4
- package/dist/{SignalCore-RBA3VDBL.js → SignalCore-JZNXOLNT.js} +3 -3
- package/dist/{SiteDesignReporter-C4LR5X2V.js → SiteDesignReporter-W4EJUSTE.js} +5 -5
- package/dist/SitemapSync-XBANGKHZ.js +8 -0
- package/dist/SitemapSync.d.ts +1 -1
- package/dist/_client/booking-widget.js +5 -5
- package/dist/_client/testimonial-section.d.ts +1 -1
- package/dist/affiliates/api.d.ts +1 -1
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/AnalyticsProvider.d.ts +1 -1
- package/dist/analytics/index.js +4 -4
- package/dist/analytics/send-gate.d.ts +12 -25
- package/dist/articles/Article.d.ts +1 -1
- package/dist/articles/ArticleList.d.ts +1 -1
- package/dist/articles/ClusterLandingPage.d.ts +2 -2
- package/dist/articles/PublicationLayout.d.ts +1 -1
- package/dist/articles/PublicationSidebar.d.ts +1 -1
- package/dist/articles/RelatedPosts.d.ts +1 -1
- package/dist/articles/author-schema.d.ts +1 -1
- package/dist/articles/excerpt.d.ts +3 -4
- package/dist/articles/index.d.ts +2 -2
- package/dist/articles/index.js +1 -1
- package/dist/articles/news-sitemap.d.ts +1 -1
- package/dist/articles/processArticleHtml.d.ts +1 -1
- package/dist/articles/server-core.d.ts +4 -4
- package/dist/articles/server-ui.js +1 -1
- package/dist/articles/server.d.ts +4 -4
- package/dist/articles/types.d.ts +1 -1
- package/dist/chat/index.js +5 -5
- package/dist/{chunk-U35H2JIQ.js → chunk-3SDOQUUF.js} +2 -2
- package/dist/{chunk-F42R35NV.js → chunk-6WIQCXOO.js} +1 -1
- package/dist/{chunk-4JQQDCMO.js → chunk-AH5Q262S.js} +1 -1
- package/dist/{chunk-OPRBF7VE.js → chunk-CIG5UL2S.js} +1 -1
- package/dist/{chunk-EIULXXUJ.js → chunk-CSTQDNGK.js} +4 -4
- package/dist/{chunk-YLSEB32F.js → chunk-D5EC5KVO.js} +1 -1
- package/dist/{chunk-L2DJD5Y4.js → chunk-ERXXITG4.js} +1 -1
- package/dist/{chunk-3XPJKZ6D.js → chunk-HF57LG73.js} +7 -7
- package/dist/{chunk-GWUKQ26F.js → chunk-ILU5I6RW.js} +1 -1
- package/dist/{chunk-HAG4YIZY.js → chunk-JBE46QJZ.js} +6 -6
- package/dist/{chunk-3G2SE2J4.js → chunk-JTU2GOM4.js} +9 -5
- package/dist/{chunk-QPEEKFCA.js → chunk-LUXVWITO.js} +2 -2
- package/dist/{chunk-7QTMMHUO.js → chunk-M3YEPKP7.js} +1 -1
- package/dist/{chunk-XNVSCQ2O.js → chunk-NK4CSJNP.js} +2 -2
- package/dist/{chunk-W2CL2DB3.js → chunk-PGMVL4AB.js} +2 -2
- package/dist/{chunk-HVH37YPX.js → chunk-PHYMNUJU.js} +1 -1
- package/dist/{chunk-GIAOPEN6.js → chunk-Q4W23JYM.js} +1 -1
- package/dist/{chunk-J4D6ZXRW.js → chunk-QEDHRBAT.js} +1 -1
- package/dist/{chunk-DUAO4Q75.js → chunk-RHNWA34F.js} +2 -2
- package/dist/{chunk-LFXVE32I.js → chunk-UXOGCKL6.js} +1 -1
- package/dist/{chunk-PLUP2KN5.js → chunk-V3PUVBME.js} +2 -2
- package/dist/{chunk-XD3ZQET6.js → chunk-V6FDQLR7.js} +1 -1
- package/dist/{chunk-EVFZ7KEW.js → chunk-VDF5DFWT.js} +1 -1
- package/dist/{chunk-7MHHWZKC.js → chunk-VGH4MDTU.js} +1 -1
- package/dist/{chunk-FLR3EMK6.js → chunk-VLARKWZU.js} +1 -1
- package/dist/{chunk-ZETJTCMV.js → chunk-WWSHFRDL.js} +1 -1
- package/dist/{chunk-ZIMFQWGJ.js → chunk-YCJT4JJG.js} +3 -3
- package/dist/{chunk-3J2ERO3I.js → chunk-YEMPUQVU.js} +2 -2
- package/dist/client/index.js +3 -3
- package/dist/cms/CmsPreview.d.ts +2 -2
- package/dist/cms/index.d.ts +3 -3
- package/dist/cms/server-api.d.ts +1 -1
- package/dist/cms/types.d.ts +1 -1
- package/dist/commerce/EventCheckout.d.ts +1 -1
- package/dist/commerce/EventsAgenda.d.ts +3 -3
- package/dist/commerce/api.d.ts +1 -1
- package/dist/commerce/index.js +4 -4
- package/dist/commerce/server.d.ts +3 -4
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/fleet.d.ts +9 -9
- package/dist/contracts/forms.d.ts +4 -10
- package/dist/contracts/llms.d.ts +1 -1
- package/dist/contracts/portfolio.d.ts +11 -15
- package/dist/contracts/seo-meta.d.ts +11 -12
- package/dist/contracts/seo-pages.d.ts +12 -18
- package/dist/contracts/site-cache.d.ts +4 -4
- package/dist/contracts/sites-normalize.d.ts +2 -4
- package/dist/contracts/sites.d.ts +3 -5
- package/dist/contracts/slot-content.d.ts +2 -2
- package/dist/contracts/slots.d.ts +6 -6
- package/dist/contracts/voice.d.ts +56 -0
- package/dist/contracts/website.d.ts +2 -2
- package/dist/engage/ChatWidget.d.ts +2 -2
- package/dist/engage/EchoUiActions.d.ts +3 -3
- package/dist/engage/EngageWidget.d.ts +1 -1
- package/dist/engage/brand-color.d.ts +1 -1
- package/dist/engage/element-rules.d.ts +2 -2
- package/dist/engage/index.js +6 -6
- package/dist/engage/types.d.ts +3 -3
- package/dist/fleet/FleetHeartbeat.d.ts +2 -2
- package/dist/fleet/index.js +4 -4
- package/dist/forms/FormSpotlight.d.ts +2 -2
- package/dist/forms/ManagedForm.d.ts +1 -1
- package/dist/forms/StaticForm.d.ts +1 -1
- package/dist/forms/field-interactions.d.ts +2 -2
- package/dist/forms/form-loaded-at.d.ts +2 -2
- package/dist/forms/formsApi.d.ts +2 -2
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +8 -8
- package/dist/forms/server.d.ts +1 -1
- package/dist/forms/server.js +4 -4
- package/dist/forms/static.js +2 -2
- package/dist/forms/submitForm.d.ts +1 -1
- package/dist/forms/types.d.ts +3 -3
- package/dist/images/ManagedFavicon.d.ts +1 -1
- package/dist/images/ManagedImage.d.ts +4 -4
- package/dist/images/api.d.ts +1 -1
- package/dist/images/index.d.ts +2 -2
- package/dist/images/index.js +4 -4
- package/dist/index.js +1 -1
- package/dist/landing/contract.d.ts +3 -4
- package/dist/layout/SiteKitClientProviders.d.ts +1 -1
- package/dist/layout/SiteKitLayout.d.ts +7 -7
- package/dist/layout/client.d.ts +1 -1
- package/dist/layout/client.js +7 -7
- package/dist/layout/index.js +8 -8
- package/dist/layout/types.d.ts +2 -2
- package/dist/llms/SpeakableSchema.d.ts +2 -2
- package/dist/llms/agent-access.d.ts +2 -2
- package/dist/llms/aiRobots.d.ts +4 -4
- package/dist/llms/api.d.ts +2 -2
- package/dist/llms/generateLLMsTxt.d.ts +1 -1
- package/dist/llms/index.js +4 -4
- package/dist/llms/links.d.ts +1 -1
- package/dist/llms/revalidate.d.ts +1 -1
- package/dist/llms/seo-revalidate.d.ts +2 -3
- package/dist/llms/types.d.ts +6 -6
- package/dist/llms/writeLLMsTxt.d.ts +10 -10
- package/dist/manifest/index.d.ts +8 -8
- package/dist/maps/index.js +3 -3
- package/dist/mcp/WebMcpTools.d.ts +1 -1
- package/dist/mcp/report.d.ts +2 -2
- package/dist/mcp/serverCard.d.ts +1 -1
- package/dist/mcp/sonor.d.ts +5 -6
- package/dist/mcp/sonor.js +8 -8
- package/dist/mcp/transport.d.ts +1 -2
- package/dist/mcp/types.d.ts +4 -5
- package/dist/motion/engine.d.ts +2 -3
- package/dist/motion/failsafe.d.ts +1 -2
- package/dist/motion/gsap.d.ts +2 -2
- package/dist/motion/three.d.ts +1 -1
- package/dist/og/config.d.ts +4 -4
- package/dist/og/contrast.d.ts +2 -2
- package/dist/og/pages.d.ts +5 -5
- package/dist/og/route-fit.d.ts +2 -2
- package/dist/og/route.d.ts +1 -2
- package/dist/og/template.d.ts +1 -1
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/securityHeaders.d.ts +10 -12
- package/dist/redirects/index.d.ts +7 -7
- package/dist/reputation/TestimonialSection.d.ts +1 -1
- package/dist/reputation/api.d.ts +1 -1
- package/dist/revalidate/index.js +2 -2
- package/dist/robots/index.d.ts +5 -5
- package/dist/robots/indexnow.d.ts +2 -3
- package/dist/seo/ManagedScripts.d.ts +2 -2
- package/dist/seo/client.js +4 -4
- package/dist/seo/getManagedMetadata.d.ts +1 -1
- package/dist/seo/groundingSchema.d.ts +2 -2
- package/dist/seo/index.js +4 -4
- package/dist/seo/llms.js +4 -4
- package/dist/seo/register-sitemap-cli-impl.d.ts +1 -1
- package/dist/seo/register-sitemap-cli.d.ts +1 -1
- package/dist/seo/register-sitemap-cli.js +2 -2
- package/dist/seo/schema-filter.d.ts +5 -6
- package/dist/seo/server-api.d.ts +1 -1
- package/dist/seo/sitemap.js +2 -2
- package/dist/seo/types.d.ts +4 -4
- package/dist/seo/withManagedMetadata.d.ts +4 -4
- package/dist/server/index.js +2 -2
- package/dist/server/mint-site-token.d.ts +1 -2
- package/dist/server/server-fetch.d.ts +5 -5
- package/dist/shared/build-entries.d.ts +4 -4
- package/dist/shared/frame.d.ts +8 -9
- package/dist/shared/fresh-fetch.d.ts +1 -2
- package/dist/shared/next-files.d.ts +1 -1
- package/dist/shared/publishCredential.d.ts +1 -1
- package/dist/shared/uuid.d.ts +1 -2
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +2 -2
- package/dist/signal/index.js +2 -2
- package/dist/site-config/index.d.ts +2 -2
- package/dist/sitemap/index.d.ts +13 -13
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/shared.d.ts +3 -3
- package/dist/sites/site-param.d.ts +2 -2
- package/dist/slots/ManagedRichText.d.ts +1 -1
- package/dist/slots/ManagedSlot.d.ts +1 -1
- package/dist/slots/index.d.ts +1 -3
- package/dist/sync/index.js +5 -5
- package/dist/types.d.ts +1 -1
- package/dist/{web-vitals.attribution-N2PCCF4Q.js → web-vitals.attribution-GD6LGLVF.js} +1 -1
- package/dist/website/PopupBlocks.d.ts +3 -4
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +5 -5
- package/dist/website/popups.js +4 -4
- package/dist/{writeLLMsTxt-QR23OQUE.js → writeLLMsTxt-G3JBNBC5.js} +1 -1
- package/docs/MIGRATING-TO-7.md +9 -13
- package/package.json +1 -1
- package/src/admin-auth/README.md +3 -3
- package/src/analytics/README.md +7 -9
- package/src/articles/README.md +6 -6
- package/src/cta-bar/README.md +11 -11
- package/src/forms/README.md +10 -8
- package/src/llms/README.md +3 -3
- package/src/mcp/README.md +7 -7
- package/src/motion/README.md +1 -1
- package/src/og/README.md +26 -27
- package/src/proxy/README.md +14 -14
- package/src/seo/README.md +1 -1
- package/src/slots/README.md +1 -1
- package/src/sync/README.md +1 -1
- package/dist/ManagedForm-Z3PKOPIZ.js +0 -14
- package/dist/SitemapSync-XVMGKCF3.js +0 -8
package/dist/website/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { SiteDesignReporter } from '../chunk-
|
|
3
|
-
export { SITE_DESIGN_PATH, cleanFontStack, colorToHex, getSiteDesignTokens, measureSiteDesign, readDeclaredDesign, sendSiteDesign } from '../chunk-
|
|
2
|
+
export { SiteDesignReporter } from '../chunk-Q4W23JYM.js';
|
|
3
|
+
export { SITE_DESIGN_PATH, cleanFontStack, colorToHex, getSiteDesignTokens, measureSiteDesign, readDeclaredDesign, sendSiteDesign } from '../chunk-PGMVL4AB.js';
|
|
4
4
|
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-JSZN6LDZ.js';
|
|
5
5
|
import '../chunk-IHG36STL.js';
|
|
6
6
|
import '../chunk-YC7ELZS3.js';
|
|
7
7
|
import '../chunk-S22FSH7C.js';
|
|
8
8
|
import '../chunk-43OCZ3JA.js';
|
|
9
9
|
import '../chunk-EKBEOXTH.js';
|
|
10
|
-
import '../chunk-
|
|
11
|
-
import '../chunk-
|
|
12
|
-
import '../chunk-
|
|
10
|
+
import '../chunk-3SDOQUUF.js';
|
|
11
|
+
import '../chunk-VDF5DFWT.js';
|
|
12
|
+
import '../chunk-AH5Q262S.js';
|
|
13
13
|
import '../chunk-PKBMQBKP.js';
|
package/dist/website/popups.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-JSZN6LDZ.js';
|
|
3
3
|
import '../chunk-IHG36STL.js';
|
|
4
|
-
import { EngageWidget } from '../chunk-
|
|
4
|
+
import { EngageWidget } from '../chunk-YCJT4JJG.js';
|
|
5
5
|
import '../chunk-NDF4A5JM.js';
|
|
6
6
|
import '../chunk-6T6CQVNL.js';
|
|
7
7
|
import '../chunk-S22FSH7C.js';
|
|
@@ -9,9 +9,9 @@ import '../chunk-24QZEO3Q.js';
|
|
|
9
9
|
import '../chunk-GJWI74ZZ.js';
|
|
10
10
|
import '../chunk-43OCZ3JA.js';
|
|
11
11
|
import '../chunk-EKBEOXTH.js';
|
|
12
|
-
import '../chunk-
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
12
|
+
import '../chunk-3SDOQUUF.js';
|
|
13
|
+
import '../chunk-VDF5DFWT.js';
|
|
14
|
+
import '../chunk-AH5Q262S.js';
|
|
15
15
|
import '../chunk-PKBMQBKP.js';
|
|
16
16
|
import { jsx } from 'react/jsx-runtime';
|
|
17
17
|
|
package/docs/MIGRATING-TO-7.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Moving a site to site-kit 7
|
|
2
2
|
|
|
3
3
|
site-kit 7 is organised the way Sonor's dashboard is: one entry per module.
|
|
4
|
-
Most sites need no changes at all. Move a site when you next touch it
|
|
5
|
-
|
|
4
|
+
Most sites need no changes at all. Move a site when you next touch it;
|
|
5
|
+
nothing forces it before then, because a
|
|
6
6
|
site's `^6` range never picks up 7.
|
|
7
7
|
|
|
8
8
|
## The short version
|
|
@@ -20,7 +20,7 @@ idempotent: running it twice changes nothing the second time. It works from
|
|
|
20
20
|
any 2.x-6.x site: copies of sites on 4.2, 5.8 and 6.5 were migrated with it
|
|
21
21
|
and built.
|
|
22
22
|
|
|
23
|
-
Requirements: Next 16
|
|
23
|
+
Requirements: Next 16 and Node 20.19+ or 22.12+
|
|
24
24
|
(Netlify's default is 22).
|
|
25
25
|
|
|
26
26
|
## What changed, and what the codemod does about it
|
|
@@ -48,9 +48,6 @@ keeps type imports on the root. It flags, rather than rewrites, a namespace
|
|
|
48
48
|
import (`import * as SK`), a `require`, or a re-export from the root. The full
|
|
49
49
|
list is `src/shared/module-map.json` (`rootRuntime`).
|
|
50
50
|
|
|
51
|
-
Across our own sites on 2026-09-26 this touched three repos: one for
|
|
52
|
-
`affiliates`, two for `BookingWidget`.
|
|
53
|
-
|
|
54
51
|
### 2. The setup CLI is its own package: `sonor-setup`
|
|
55
52
|
|
|
56
53
|
The CLI (init, scaffold, codemods, OG cards, GEO wiring, verify) was 3 MB of
|
|
@@ -58,10 +55,10 @@ every site's install and forced a site-kit release for every setup-only fix.
|
|
|
58
55
|
It's now [`sonor-setup`](../packages/sonor-setup).
|
|
59
56
|
|
|
60
57
|
- **`npx sonor-setup …` keeps working unchanged:** npx fetches the package.
|
|
61
|
-
- **A site whose package.json scripts run `sonor-setup`** (
|
|
62
|
-
|
|
58
|
+
- **A site whose package.json scripts run `sonor-setup`** (an OG step that
|
|
59
|
+
runs `sonor-setup og`, say) needs it as a dev dependency. The codemod adds
|
|
63
60
|
`"sonor-setup": "^7.0.0"` for you.
|
|
64
|
-
- **`sonor-register-sitemap` stays in site-kit**, since
|
|
61
|
+
- **`sonor-register-sitemap` stays in site-kit**, since sites run it from
|
|
65
62
|
their postbuild. Nothing to change.
|
|
66
63
|
- The `site-kit` bin alias for the CLI is gone (no site used it).
|
|
67
64
|
|
|
@@ -83,8 +80,7 @@ codemod moves them anyway, so a touched site is done in one pass.
|
|
|
83
80
|
site-kit ships ES modules alone (`"type": "module"`). Next, Turbopack and the
|
|
84
81
|
kits don't notice. Node 20.19+/22.12+ can `require()` it too, so a
|
|
85
82
|
`next.config.ts` that imports `@sonordev/site-kit/config` keeps working. A
|
|
86
|
-
site-side script that `require()`s site-kit on an older Node would break
|
|
87
|
-
in the fleet does.
|
|
83
|
+
site-side script that `require()`s site-kit on an older Node would break.
|
|
88
84
|
|
|
89
85
|
The `next` peer is `^16`. Next 16 renamed `middleware.ts` to `proxy.ts`, and
|
|
90
86
|
**the codemod moves it**: the file, a named `middleware` export (to `proxy`),
|
|
@@ -94,7 +90,7 @@ sets `runtime` (a proxy file can't; the build throws), and says so: remove
|
|
|
94
90
|
the export, check the logic still runs on your host, rerun. It never moves
|
|
95
91
|
onto an existing `proxy.ts`. `npx sonor-setup next16` runs just this part.
|
|
96
92
|
|
|
97
|
-
### 5. Removed (
|
|
93
|
+
### 5. Removed (nothing used them)
|
|
98
94
|
|
|
99
95
|
- `@sonordev/site-kit/search` and `/search/contract`
|
|
100
96
|
- `@sonordev/site-kit/redirects/not-found` (`resolveManagedRedirect`), and
|
|
@@ -133,7 +129,7 @@ Still accepted and ignored until 8.0, because sites pass them:
|
|
|
133
129
|
reviews; inquiries, availability and offerings when you ask), the server
|
|
134
130
|
card, and on Netlify the rate-limited relay. Sonor's AI Visibility tab then
|
|
135
131
|
shows which agents used them. A site that already runs its own MCP server
|
|
136
|
-
(
|
|
132
|
+
(a hand-written one) is left exactly as it is:
|
|
137
133
|
nothing in 7.0 turns anything on for it. To have Sonor see its calls, add
|
|
138
134
|
`onToolCall: reportToolCallsToSonor()` to its `createMcpHandler`.
|
|
139
135
|
- **`@sonordev/contracts`** is for the APIs and the dashboard; sites keep
|
package/package.json
CHANGED
package/src/admin-auth/README.md
CHANGED
|
@@ -11,7 +11,7 @@ admins) can sign in; nobody else can. There are no passwords on the site.
|
|
|
11
11
|
import { createSonorSso } from '@sonordev/site-kit/admin-auth'
|
|
12
12
|
|
|
13
13
|
export const sso = createSonorSso({
|
|
14
|
-
paths: '/admin', // or ['/
|
|
14
|
+
paths: '/admin', // or ['/admin', '/staff'] for several areas
|
|
15
15
|
// loginPath: '/admin/login' (default: `${paths[0]}/login`)
|
|
16
16
|
// adminEmails: process.env.ADMIN_EMAILS,
|
|
17
17
|
})
|
|
@@ -62,8 +62,8 @@ const session = await sso.getSession()
|
|
|
62
62
|
if (!session) return new Response('Unauthorized', { status: 401 })
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
JSON endpoints can be guarded in the middleware too: pass
|
|
66
|
+
`apiPaths: ['/api/admin']` and include them in the matcher. They get a
|
|
67
67
|
401 JSON response instead of a redirect.
|
|
68
68
|
|
|
69
69
|
## Env
|
package/src/analytics/README.md
CHANGED
|
@@ -178,14 +178,12 @@ events or conversions. The visitor is on whoever framed the page, not on this
|
|
|
178
178
|
site, so every metric the frame produces is phantom traffic in the analytics
|
|
179
179
|
its owner reads.
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
study. The screenshot overlay in those frames hides the pixels, not the
|
|
188
|
-
JavaScript.
|
|
181
|
+
A portfolio page that shows a live site in desktop, tablet and mobile frames
|
|
182
|
+
is the common case, and `securityHeaders`' `DEFAULT_FRAME_ANCESTORS` permits
|
|
183
|
+
it. Without the guard, one visit to that page would record three views of `/`
|
|
184
|
+
on the framed site, milliseconds apart, sharing one session and visitor id,
|
|
185
|
+
with the portfolio as the referrer. A screenshot laid over the frames hides
|
|
186
|
+
the pixels, not the JavaScript.
|
|
189
187
|
|
|
190
188
|
**Same-origin frames still report.** A site embedding itself (a preview pane,
|
|
191
189
|
a print view, an on-domain booking frame) has a real visitor really on that
|
|
@@ -241,7 +239,7 @@ Uses `SONOR_API_KEY` (injected by `SiteKitLayout`) or `window.__SITE_KIT_API_KEY
|
|
|
241
239
|
## Multi-site projects (`analytics.site`)
|
|
242
240
|
|
|
243
241
|
A single Sonor project can host many sub-sites (e.g. one project hosting
|
|
244
|
-
example.com +
|
|
242
|
+
example.com + a dozen regional microsites). Every analytics event is
|
|
245
243
|
tagged with the sub-site host so the dashboard can roll up + filter per
|
|
246
244
|
site without forcing each microsite into its own Sonor project.
|
|
247
245
|
|
package/src/articles/README.md
CHANGED
|
@@ -17,12 +17,12 @@ import type { PublicationRoutingOptions } from '@sonordev/site-kit/articles/serv
|
|
|
17
17
|
|
|
18
18
|
const siteUrl = 'https://example.com'
|
|
19
19
|
const routing = {
|
|
20
|
-
basePath: '/
|
|
20
|
+
basePath: '/journal',
|
|
21
21
|
includeCategoryInPath: true,
|
|
22
|
-
categoryPath: (slug: string) => `/
|
|
22
|
+
categoryPath: (slug: string) => `/journal?category=${encodeURIComponent(slug)}`,
|
|
23
23
|
} satisfies PublicationRoutingOptions
|
|
24
24
|
|
|
25
|
-
// Cards, related stories and cluster links now use /
|
|
25
|
+
// Cards, related stories and cluster links now use /journal/category/slug.
|
|
26
26
|
const article = <Article slug="build-first" routing={routing} />
|
|
27
27
|
const archive = <ArticleList routing={routing} />
|
|
28
28
|
|
|
@@ -30,7 +30,7 @@ const archive = <ArticleList routing={routing} />
|
|
|
30
30
|
const metadata = await generateArticleMetadata('build-first', { siteUrl, ...routing })
|
|
31
31
|
const post = await getArticle('build-first')
|
|
32
32
|
const schema = post ? generateArticleSchema(post, { siteUrl, ...routing }) : null
|
|
33
|
-
// In app/
|
|
33
|
+
// In app/journal/[category]/[slug]/page.tsx, wrap it to pass the routing:
|
|
34
34
|
// export function generateStaticParams() { return generateArticleStaticParams(routing) }
|
|
35
35
|
const params = await generateArticleStaticParams(routing) // { category, slug }[]
|
|
36
36
|
const sitemap = await generateArticleSitemap(siteUrl, {
|
|
@@ -38,7 +38,7 @@ const sitemap = await generateArticleSitemap(siteUrl, {
|
|
|
38
38
|
includeCategories: false, // category filters don't need separate sitemap entries
|
|
39
39
|
includeClusters: false, // enable when your site implements cluster routes
|
|
40
40
|
})
|
|
41
|
-
const rss = await generateRssFeed({ siteUrl, siteName: 'The
|
|
41
|
+
const rss = await generateRssFeed({ siteUrl, siteName: 'The Journal', ...routing })
|
|
42
42
|
const href = createPublicationRoutes(routing).post({ slug: 'build-first', category: 'guides' })
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -107,7 +107,7 @@ export async function generateMetadata() {
|
|
|
107
107
|
|
|
108
108
|
export default function PublicationPage() {
|
|
109
109
|
return (
|
|
110
|
-
<PublicationLayout hero={{ title: 'The
|
|
110
|
+
<PublicationLayout hero={{ title: 'The Journal', subtitle: 'Latest articles' }}>
|
|
111
111
|
<ArticleList showCategoryFilter showPagination />
|
|
112
112
|
</PublicationLayout>
|
|
113
113
|
)
|
package/src/cta-bar/README.md
CHANGED
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
The Liquid Glass mobile CTA bar (6.1.0). A floating frosted capsule that
|
|
4
4
|
keeps a site's one or two highest-intent actions a thumb away on phones.
|
|
5
5
|
|
|
6
|
-
It replaces
|
|
7
|
-
|
|
6
|
+
It replaces a hand-rolled sticky mobile bar, and handles what each of those
|
|
7
|
+
ends up solving on its own:
|
|
8
8
|
|
|
9
|
-
| Behaviour |
|
|
10
|
-
|
|
11
|
-
| Hide while the form it points at is on screen |
|
|
12
|
-
| Stay off the hero until the hero CTA scrolls away |
|
|
13
|
-
| Get out from under the Echo launcher |
|
|
14
|
-
| Ride out the iOS toolbar collapsing |
|
|
15
|
-
| Get out of the way of the keyboard |
|
|
16
|
-
| Tell Sonor which action converts |
|
|
9
|
+
| Behaviour | How |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Hide while the form it points at is on screen | `hideOver` |
|
|
12
|
+
| Stay off the hero until the hero CTA scrolls away | `showAfter` |
|
|
13
|
+
| Get out from under the Echo launcher | automatic |
|
|
14
|
+
| Ride out the iOS toolbar collapsing | `--sk-vv-layout-gap` |
|
|
15
|
+
| Get out of the way of the keyboard | `hideWhileTyping` |
|
|
16
|
+
| Tell Sonor which action converts | `cta_click` event |
|
|
17
17
|
|
|
18
18
|
## Use it
|
|
19
19
|
|
|
@@ -28,7 +28,7 @@ import { CtaBar, CtaBarAction } from '@sonordev/site-kit/cta-bar'
|
|
|
28
28
|
<main>{children}</main>
|
|
29
29
|
<Footer />
|
|
30
30
|
<CtaBar label="Call or request a quote" hideOver="#quote">
|
|
31
|
-
<CtaBarAction href="tel:+
|
|
31
|
+
<CtaBarAction href="tel:+15555550100" variant="secondary" icon={<Phone />}>
|
|
32
32
|
Call now
|
|
33
33
|
</CtaBarAction>
|
|
34
34
|
<CtaBarAction as={Link} href="/quote" icon={<ClipboardCheck />}>
|
package/src/forms/README.md
CHANGED
|
@@ -47,8 +47,8 @@ Three things hold for every experience:
|
|
|
47
47
|
the form still works and still submits.
|
|
48
48
|
- **Nobody pays for what they don't use.** Experience code is loaded on
|
|
49
49
|
demand, so a `classic` form downloads none of it.
|
|
50
|
-
- **Same engine.** Identical validation,
|
|
51
|
-
|
|
50
|
+
- **Same engine.** Identical validation, spam protection and CRM routing.
|
|
51
|
+
An experience is a rendering, not a fork.
|
|
52
52
|
|
|
53
53
|
### Editing what the form says back
|
|
54
54
|
|
|
@@ -202,13 +202,15 @@ Submissions auto-route based on `form_type`:
|
|
|
202
202
|
| `newsletter` | Email Subscribers | Newsletter signups |
|
|
203
203
|
| `custom` | Form Submissions only | Custom handling |
|
|
204
204
|
|
|
205
|
-
##
|
|
205
|
+
## Spam protection
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
Sonor screens every submission on its side, and there's nothing to configure.
|
|
208
|
+
It only accepts a submission with evidence that a real browser rendered the
|
|
209
|
+
page, which `<ManagedForm>` and `useForm` send automatically. A hand-rolled
|
|
210
|
+
`fetch` to the forms API, or a proxy through your own API route, can't send
|
|
211
|
+
it, so Sonor refuses those before anything is written: the visitor sees an
|
|
212
|
+
error and you get no lead. Submit through site-kit, and define the form's
|
|
213
|
+
fields in Sonor so both can render and validate them.
|
|
212
214
|
|
|
213
215
|
## Styles
|
|
214
216
|
|
package/src/llms/README.md
CHANGED
|
@@ -315,7 +315,7 @@ Business description...
|
|
|
315
315
|
|
|
316
316
|
## Portfolio & Case Studies
|
|
317
317
|
|
|
318
|
-
### [Project Title](https://
|
|
318
|
+
### [Project Title](https://example.com/work/project)
|
|
319
319
|
|
|
320
320
|
Description of the project.
|
|
321
321
|
|
|
@@ -355,7 +355,7 @@ We follow a proven process...
|
|
|
355
355
|
|
|
356
356
|
### Family Law Basics
|
|
357
357
|
Topic: Family Law
|
|
358
|
-
Area:
|
|
358
|
+
Area: Springfield
|
|
359
359
|
Articles: 8
|
|
360
360
|
Service page: https://example.com/services/family-law
|
|
361
361
|
Pillar: [Complete Guide to Family Law](/article/family-law-guide)
|
|
@@ -515,7 +515,7 @@ export default function DivorcePage() {
|
|
|
515
515
|
title="Key Facts"
|
|
516
516
|
points={[
|
|
517
517
|
'25+ years of family law experience',
|
|
518
|
-
'Serving
|
|
518
|
+
'Serving Springfield and the surrounding counties',
|
|
519
519
|
'Free initial consultation available',
|
|
520
520
|
]}
|
|
521
521
|
speakable
|
package/src/mcp/README.md
CHANGED
|
@@ -82,11 +82,11 @@ endpoint and card (automatic in the build-time file once `/api/mcp` exists),
|
|
|
82
82
|
and `createProxy({ llmsDiscovery: { siteUrl, mcpServerCard: true } })` adds
|
|
83
83
|
`Link: <.../.well-known/mcp-server-card>; rel="service-desc"`.
|
|
84
84
|
|
|
85
|
-
### A custom MCP server
|
|
85
|
+
### A custom MCP server is left alone
|
|
86
86
|
|
|
87
87
|
The built-in tools are opt-in, never automatic. A site that runs its own MCP
|
|
88
|
-
server (its own tools, transport names or llms.txt section, like
|
|
89
|
-
|
|
88
|
+
server (its own tools, transport names or llms.txt section, like a
|
|
89
|
+
re-site-kit site) is a **custom implementation**, and site-kit keeps its
|
|
90
90
|
hands off:
|
|
91
91
|
|
|
92
92
|
| What | Built-in server | Custom server |
|
|
@@ -257,8 +257,8 @@ What the relay does, so you don't have to re-derive it:
|
|
|
257
257
|
|
|
258
258
|
The header and label default to `x-site-mcp-transport` and
|
|
259
259
|
`site-mcp-transport-v1`. A site with names already live passes the same
|
|
260
|
-
`{ header, label }` to all three factories (
|
|
261
|
-
`x-
|
|
260
|
+
`{ header, label }` to all three factories (for example
|
|
261
|
+
`x-example-mcp-transport` / `example-mcp-transport-v1`). This entry is Node
|
|
262
262
|
only and imports no `server-only`, so the plain-Node function can load it. It
|
|
263
263
|
is not re-exported from `@sonordev/site-kit/mcp`, which stays runtime-neutral.
|
|
264
264
|
|
|
@@ -333,8 +333,8 @@ single property check — not a request, and not a byte of page weight.
|
|
|
333
333
|
`<WebMcpTools>` registers thin wrappers that POST `tools/call` to this site's
|
|
334
334
|
own endpoint, so the in-page tool and the remote tool run the same server-side
|
|
335
335
|
handler. It also keeps `SONOR_API_KEY` out of the client bundle — registering
|
|
336
|
-
real handlers client-side would pull server code
|
|
337
|
-
|
|
336
|
+
real handlers client-side would pull server code, and the key with it, into a
|
|
337
|
+
`'use client'` graph and a public chunk.
|
|
338
338
|
|
|
339
339
|
Tools that genuinely need live DOM state go in `localTools` and run in-page.
|
|
340
340
|
|
package/src/motion/README.md
CHANGED
|
@@ -348,7 +348,7 @@ Per-site components map onto `<Reveal>` almost one to one:
|
|
|
348
348
|
| Site prop | `<Reveal>` |
|
|
349
349
|
|-----------|-----------|
|
|
350
350
|
| `from="up"`, `direction="up"` | `from="up"` |
|
|
351
|
-
| `y={30}`
|
|
351
|
+
| `y={30}` | `distance={30}` |
|
|
352
352
|
| `stagger` (boolean) | `stagger` |
|
|
353
353
|
| `delay`, `duration` | same, in seconds |
|
|
354
354
|
| `threshold`, `rootMargin` | `threshold` |
|
package/src/og/README.md
CHANGED
|
@@ -47,8 +47,8 @@ to child segments.** A card at `services/` is not inherited by
|
|
|
47
47
|
param), which the generator does automatically.
|
|
48
48
|
|
|
49
49
|
`sonor-setup og` and `sonor-setup doctor` both check this through one shared
|
|
50
|
-
rule (`og/wiring.ts`)
|
|
51
|
-
|
|
50
|
+
rule (`og/wiring.ts`), so the two never disagree. The rule reads the site's
|
|
51
|
+
code through
|
|
52
52
|
`shared/source-graph.ts`, which follows imports into `lib/` helpers and monorepo
|
|
53
53
|
workspace packages, so `twitter.card` set in a metadata helper counts. It used
|
|
54
54
|
to read the root layout alone.
|
|
@@ -62,16 +62,16 @@ zero-config seed for sites that have no config yet.
|
|
|
62
62
|
import { defineOgCard } from '@sonordev/site-kit/og'
|
|
63
63
|
|
|
64
64
|
export default defineOgCard({
|
|
65
|
-
theme: { bg: '#
|
|
66
|
-
fonts: [{ family: '
|
|
65
|
+
theme: { bg: '#0F172A', text: '#F8FAFC', accent: '#F59E0B', surface: '#1E293B' },
|
|
66
|
+
fonts: [{ family: 'Fraunces', weights: [800] }],
|
|
67
67
|
logo: '/logo-white.svg',
|
|
68
68
|
layout: 'split',
|
|
69
|
-
photo: { src: '/
|
|
69
|
+
photo: { src: '/crew.jpg' },
|
|
70
70
|
content: {
|
|
71
|
-
kicker: '
|
|
72
|
-
title: 'Built by\
|
|
73
|
-
subtitle: 'Designed, built
|
|
74
|
-
bar: ['Free
|
|
71
|
+
kicker: 'Remodeling · Springfield',
|
|
72
|
+
title: 'Built by\nneighbors',
|
|
73
|
+
subtitle: 'Designed, built and installed by one local crew.',
|
|
74
|
+
bar: ['Free estimate', 'example.com'],
|
|
75
75
|
},
|
|
76
76
|
})
|
|
77
77
|
```
|
|
@@ -86,10 +86,10 @@ The title opens at 104px and the renderer steps it down until it fits **both**
|
|
|
86
86
|
axes, stopping at a 56px legibility floor — below that a headline stops reading
|
|
87
87
|
at the ~300px thumbnail width platforms actually show.
|
|
88
88
|
|
|
89
|
-
If copy still
|
|
90
|
-
element and the overflow in pixels. That
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
If copy still doesn't fit at the floor, the command **fails** and names the
|
|
90
|
+
element and the overflow in pixels. That's deliberate: otherwise a card can ship
|
|
91
|
+
with the kicker off-canvas and the subtitle buried under the bottom bar while
|
|
92
|
+
the CLI prints a tick.
|
|
93
93
|
|
|
94
94
|
Rules of thumb: about 10 uppercase characters per title line, and about 29 for
|
|
95
95
|
the kicker. `\n` in a title is a hard break, so choose the wrap yourself rather
|
|
@@ -106,8 +106,8 @@ Hand-write the few that deserve it:
|
|
|
106
106
|
|
|
107
107
|
```ts
|
|
108
108
|
cards: {
|
|
109
|
-
'/free-
|
|
110
|
-
content: { kicker: 'Free
|
|
109
|
+
'/free-estimate': {
|
|
110
|
+
content: { kicker: 'Free estimate', title: 'Know the\ncost first' },
|
|
111
111
|
photo: { src: '/lp/hero.jpg' },
|
|
112
112
|
},
|
|
113
113
|
},
|
|
@@ -119,8 +119,8 @@ so an entry only states what differs.
|
|
|
119
119
|
Managed titles carry the brand for the SERP (`About Us | Acme`); the card drops
|
|
120
120
|
it. It also drops the two broken suffixes managed titles turn up with: a dangling
|
|
121
121
|
separator with no brand after it (`About Us |`) and a domain after a comma
|
|
122
|
-
(`Privacy Policy,
|
|
123
|
-
separator (`Walk-In
|
|
122
|
+
(`Privacy Policy, example.com`). A hyphen inside a word is never a
|
|
123
|
+
separator (`Walk-In Showers` stays whole).
|
|
124
124
|
|
|
125
125
|
### Dynamic routes are keyed by pattern, one `*` per level
|
|
126
126
|
|
|
@@ -141,23 +141,22 @@ cards: {
|
|
|
141
141
|
},
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
service-by-metro pages
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
The generator keys each depth separately, so a `/services/*/*` entry reaches
|
|
145
|
+
the service-by-metro pages and nothing else. A `cards` key that matches no
|
|
146
|
+
rendered route is reported by `sonor-setup og` (`og.cards`, a warning), since
|
|
147
|
+
otherwise it would match nothing, silently.
|
|
148
148
|
|
|
149
149
|
> **Writing a nested pattern in a comment.** `/services/*/*` contains `*/`,
|
|
150
150
|
> which **closes a `/* */` block comment early**. In TypeScript put it in a
|
|
151
|
-
> string, a `//` line comment, or spell the depth out in prose
|
|
152
|
-
>
|
|
151
|
+
> string, a `//` line comment, or spell the depth out in prose. It's an easy
|
|
152
|
+
> slip in exactly the comment that explains the pattern.
|
|
153
153
|
|
|
154
154
|
### Static routes under a dynamic segment get a card too
|
|
155
155
|
|
|
156
156
|
`properties/[slug]/about` is a static route under a dynamic one. It gets its
|
|
157
157
|
own card, keyed `/properties/*/about` and titled from its own name ("About",
|
|
158
158
|
kicker "properties"). The generator used to stop at the first dynamic segment,
|
|
159
|
-
|
|
160
|
-
property sites.
|
|
159
|
+
which left these pages with no og:image at all.
|
|
161
160
|
|
|
162
161
|
### Per-URL cards: one per floor plan, one per community
|
|
163
162
|
|
|
@@ -213,7 +212,7 @@ The URL ends in `.jpg`, so a `trailingSlash: true` site never redirects it.
|
|
|
213
212
|
Per-URL cards need `sharp` (they have to be `.jpg`); without it the command
|
|
214
213
|
fails those cards and says so. Their copy comes from Sonor's managed title for
|
|
215
214
|
that URL, like any route card. A per-URL key matches a pattern one segment per
|
|
216
|
-
`*`, so `/properties/
|
|
215
|
+
`*`, so `/properties/maple-court/about` falls under `/properties/*/about`.
|
|
217
216
|
|
|
218
217
|
Cards are re-encoded to JPEG when `sharp` resolves — on a real 18-card site that
|
|
219
218
|
was 5.6 MB → 1.4 MB. Without sharp they stay PNG, which is correct, just heavier.
|
|
@@ -249,7 +248,7 @@ export default createOgImage<{ slug: string }>(async ({ slug }) => {
|
|
|
249
248
|
kicker: 'From the publication',
|
|
250
249
|
title: post.title,
|
|
251
250
|
photoUrl: post.featured_image, // must be absolute
|
|
252
|
-
bar: '
|
|
251
|
+
bar: 'example.com',
|
|
253
252
|
}
|
|
254
253
|
})
|
|
255
254
|
```
|
package/src/proxy/README.md
CHANGED
|
@@ -114,7 +114,7 @@ into a dynamic one. The resolver is deprecated.
|
|
|
114
114
|
| Header | Value |
|
|
115
115
|
|--------|-------|
|
|
116
116
|
| X-DNS-Prefetch-Control | `on` |
|
|
117
|
-
| Content-Security-Policy | `frame-ancestors
|
|
117
|
+
| Content-Security-Policy | `frame-ancestors` from `DEFAULT_FRAME_ANCESTORS` (below) |
|
|
118
118
|
| X-Content-Type-Options | `nosniff` |
|
|
119
119
|
| X-XSS-Protection | `1; mode=block` |
|
|
120
120
|
| Referrer-Policy | `strict-origin-when-cross-origin` |
|
|
@@ -124,23 +124,23 @@ Note there is no `X-Frame-Options` row — that is deliberate, see below.
|
|
|
124
124
|
|
|
125
125
|
### Framing / `frame-ancestors`
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
Managed sites ship a CSP `frame-ancestors` allowlist instead of
|
|
128
|
+
`X-Frame-Options`. The default, `DEFAULT_FRAME_ANCESTORS`, is `'self'`,
|
|
129
|
+
Sonor's dashboard (`https://app.sonor.io`, for Edit on page) and the Upforge
|
|
130
|
+
showcase origins (`upforge.io`, `upforgelabs.com` and their subdomains), where
|
|
131
|
+
live client sites appear in portfolio frames. XFO has no allowlist form
|
|
132
|
+
(`ALLOW-FROM` is dead), and emitting both would let a stray `DENY` silently
|
|
133
|
+
re-block the embed, so `X-Frame-Options` is **omitted** whenever
|
|
134
|
+
`frameAncestors` is active. Every origin not on the list is still blocked.
|
|
135
|
+
|
|
136
|
+
`frameAncestors` replaces the default, so spread it to add an origin:
|
|
133
137
|
|
|
134
138
|
```ts
|
|
139
|
+
import { createProxy, DEFAULT_FRAME_ANCESTORS } from '@sonordev/site-kit/proxy'
|
|
140
|
+
|
|
135
141
|
createProxy({
|
|
136
|
-
// extend the allowlist
|
|
137
142
|
securityHeaders: {
|
|
138
|
-
frameAncestors: [
|
|
139
|
-
"'self'",
|
|
140
|
-
'https://upforge.io',
|
|
141
|
-
'https://*.upforge.io',
|
|
142
|
-
'https://partner.example.com',
|
|
143
|
-
],
|
|
143
|
+
frameAncestors: [...DEFAULT_FRAME_ANCESTORS, 'https://partner.example.com'],
|
|
144
144
|
},
|
|
145
145
|
})
|
|
146
146
|
|
package/src/seo/README.md
CHANGED
|
@@ -268,7 +268,7 @@ The SEO module keeps a few lower-level helpers:
|
|
|
268
268
|
|
|
269
269
|
It skips itself when an `app/sitemap` route exists, and it only adds or updates pages unless you pass `--full-replace`.
|
|
270
270
|
|
|
271
|
-
On a multi-site project, each page is tagged with the host it belongs to. The CLI takes it from `NEXT_PUBLIC_SITE_URL` (it loads `.env` and `.env.local`), or from `--site
|
|
271
|
+
On a multi-site project, each page is tagged with the host it belongs to. The CLI takes it from `NEXT_PUBLIC_SITE_URL` (it loads `.env` and `.env.local`), or from `--site ohio.example.com`. It used to send no host at all, so a microsite's pages synced as unattributed.
|
|
272
272
|
|
|
273
273
|
From code, `registerLocalSitemap({ entries?, autoDiscover?, mode?, site? })` on `@sonordev/site-kit/seo/server` does the same and is additive by default.
|
|
274
274
|
|
package/src/slots/README.md
CHANGED
|
@@ -10,7 +10,7 @@ import { ManagedSlot, ManagedRichText, ManagedLink, ManagedList } from '@sonorde
|
|
|
10
10
|
|
|
11
11
|
<h1 className="hero-title">
|
|
12
12
|
<ManagedSlot id="home-hero-headline" page="/">
|
|
13
|
-
New homes in
|
|
13
|
+
New homes in Springfield and beyond
|
|
14
14
|
</ManagedSlot>
|
|
15
15
|
</h1>
|
|
16
16
|
```
|
package/src/sync/README.md
CHANGED
|
@@ -50,7 +50,7 @@ interface BookingWidgetProps {
|
|
|
50
50
|
1. **Type selector:** choose a booking type, unless a specific `bookingTypeSlug` is provided.
|
|
51
51
|
2. **Meeting format:** when the booking type enables meeting options, choose virtual, office, or a visit to the guest's location. Travel meetings validate the address before showing availability.
|
|
52
52
|
3. **Calendar and times:** choose an available time and reserve it while completing contact details.
|
|
53
|
-
4. **Guest info:** name, email, phone, and notes.
|
|
53
|
+
4. **Guest info:** name, email, phone, and notes. Every booking requires a phone number.
|
|
54
54
|
5. **Result:** a confirmed booking shows calendar links when Sonor sends the guest's invitation. When the host's Google Calendar sends it, the widget says who the invite is coming from instead (see [Calendar invitations](#calendar-invitations)). Meetings that require review show a pending request without calendar links.
|
|
55
55
|
|
|
56
56
|
Changing a meeting format restores the selected format, address, and access notes. Guests can return to the service selector when it's available. Contact details survive changes to the format or reserved time.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export { ManagedForm } from './chunk-EIULXXUJ.js';
|
|
2
|
-
import './chunk-YLSEB32F.js';
|
|
3
|
-
import './chunk-DXO6SBMD.js';
|
|
4
|
-
import './chunk-QPEEKFCA.js';
|
|
5
|
-
import './chunk-XD3ZQET6.js';
|
|
6
|
-
import './chunk-AQSNPZY4.js';
|
|
7
|
-
import './chunk-5SQK3D53.js';
|
|
8
|
-
import './chunk-NJCTQH2P.js';
|
|
9
|
-
import './chunk-L2V5PUFN.js';
|
|
10
|
-
import './chunk-GJWI74ZZ.js';
|
|
11
|
-
import './chunk-U35H2JIQ.js';
|
|
12
|
-
import './chunk-EVFZ7KEW.js';
|
|
13
|
-
import './chunk-4JQQDCMO.js';
|
|
14
|
-
import './chunk-PKBMQBKP.js';
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { SitemapSync } from './chunk-LFXVE32I.js';
|
|
2
|
-
import './chunk-YVKRYQRG.js';
|
|
3
|
-
import './chunk-43OCZ3JA.js';
|
|
4
|
-
import './chunk-EKBEOXTH.js';
|
|
5
|
-
import './chunk-U35H2JIQ.js';
|
|
6
|
-
import './chunk-EVFZ7KEW.js';
|
|
7
|
-
import './chunk-4JQQDCMO.js';
|
|
8
|
-
import './chunk-PKBMQBKP.js';
|