@sonordev/site-kit 7.4.0 → 8.0.1
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 +40 -12
- package/CHANGELOG.md +72 -0
- package/README.md +44 -18
- package/agent-manifest.json +111 -56
- package/dist/AnalyticsProvider-EGCZ2MVM.js +13 -0
- package/dist/{ArticleViewTracker-3DH53RSB.js → ArticleViewTracker-ATNVMT45.js} +6 -5
- package/dist/{BlocksPopup-FGWYVHCH.js → BlocksPopup-F636XNO4.js} +6 -5
- package/dist/{ChatWidget-CDQZCLVH.js → ChatWidget-EQTLKPJX.js} +8 -5
- package/dist/{FileField-IPJ7L2W6.js → FileField-BUD2YGN5.js} +5 -5
- package/dist/{FormSpotlight-CQI2DBWI.js → FormSpotlight-NGH56TGC.js} +3 -3
- package/dist/{FormStage-4WHD6ED4.js → FormStage-XZRC54SY.js} +3 -3
- package/dist/ManagedForm-CQDQ4CUN.js +19 -0
- package/dist/{ManagedNewsletterForm-3D2BK3KQ.js → ManagedNewsletterForm-KCN3BTKA.js} +9 -6
- package/dist/{SignalCore-HEQYITTM.js → SignalCore-RDQPM2L2.js} +7 -7
- package/dist/SiteChat-QBDOQ5ZZ.js +6 -0
- package/dist/SiteDesignReporter-426TUCUF.js +12 -0
- package/dist/SitePopups-KLUD6XIE.js +13 -0
- package/dist/SitemapSync-QOIMV5GO.js +9 -0
- package/dist/_client/booking-widget.js +6 -5
- package/dist/_client/testimonial-section.js +3 -2
- package/dist/affiliates/index.js +6 -6
- package/dist/analytics/index.js +73 -7
- package/dist/articles/index.js +2 -2
- package/dist/articles/server-ui.js +3 -3
- package/dist/articles/server.js +2 -2
- package/dist/brand.css +1 -1
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +39 -8
- package/dist/{chunk-CSN45MHO.js → chunk-3222QBUS.js} +13 -16
- package/dist/chunk-3G7YABRA.js +25 -0
- package/dist/{chunk-CGWUXUYZ.js → chunk-3RDJKIYO.js} +2 -2
- package/dist/{chunk-J4FSB4OG.js → chunk-3YKQLC7J.js} +5 -2
- package/dist/{chunk-3E3PPSNR.js → chunk-55JLUMAC.js} +2 -2
- package/dist/{chunk-EHR4NIMX.js → chunk-5GB2HHVJ.js} +3 -3
- package/dist/chunk-5ROTTMBL.js +19 -0
- package/dist/chunk-5TM3WPCI.js +7 -0
- package/dist/{chunk-DA5XC7Y6.js → chunk-6BXUSAOJ.js} +1 -1
- package/dist/{chunk-7HPZSWS4.js → chunk-6CJGZFOU.js} +1 -1
- package/dist/{chunk-RYVDGXC2.js → chunk-6KU7STM3.js} +3 -1
- package/dist/{chunk-JRCNUUNG.js → chunk-6KUCA5HG.js} +1 -1
- package/dist/{chunk-MDP7EB4J.js → chunk-7BSC6HF3.js} +5 -5
- package/dist/{chunk-YCFW2OQO.js → chunk-AGJODJ4V.js} +2 -2
- package/dist/{chunk-OOD6GMT4.js → chunk-B7QRRLTU.js} +6 -4
- package/dist/{chunk-X6F6SO4S.js → chunk-C7TLGL3R.js} +21 -1
- package/dist/{chunk-PQDJNIHR.js → chunk-CAF53GKN.js} +2 -2
- package/dist/{chunk-43OCZ3JA.js → chunk-CAH4Y4PY.js} +4 -2
- package/dist/{chunk-XA2BNW5M.js → chunk-DWNS6ZJM.js} +1 -1
- package/dist/{chunk-PXKIGZ2F.js → chunk-EATJPSTS.js} +1 -1
- package/dist/{chunk-XEMHGJEG.js → chunk-EE6IG5GK.js} +10 -10
- package/dist/{chunk-D2RGEWHS.js → chunk-FIGIJK5F.js} +2 -2
- package/dist/{chunk-PF64OEXC.js → chunk-GMXY2OOY.js} +2 -2
- package/dist/{chunk-IE5SSOCN.js → chunk-H3SDOSVU.js} +3 -11
- package/dist/{chunk-GK7TV7EK.js → chunk-IY6G67EF.js} +1 -1
- package/dist/{chunk-CG4ETW5Y.js → chunk-J6N5DCGW.js} +3 -3
- package/dist/{chunk-ATE6IFVK.js → chunk-JCFQGEG7.js} +1 -1
- package/dist/{chunk-4BHRA7TI.js → chunk-JIH32RH2.js} +3 -3
- package/dist/{chunk-ZTLMPUO6.js → chunk-LNSF6BJC.js} +1 -1
- package/dist/{chunk-5O62CER4.js → chunk-M62U7TJF.js} +1 -1
- package/dist/{chunk-EDYHROQ7.js → chunk-NFRJTOTB.js} +3 -3
- package/dist/{chunk-6LLTLLEJ.js → chunk-NKFRW2VB.js} +6 -5
- package/dist/{chunk-CKW4HFJG.js → chunk-OCKGB734.js} +3 -3
- package/dist/{chunk-4DJMJ4V5.js → chunk-OE3NXEOF.js} +1 -1
- package/dist/{chunk-KHQ5GD6T.js → chunk-S5G3A7OZ.js} +1 -1
- package/dist/{chunk-4NTBQNHA.js → chunk-TYAVHRWH.js} +80 -81
- package/dist/{chunk-ZTLU3BSW.js → chunk-TZ5RTANX.js} +2 -2
- package/dist/{chunk-4YTYGG2C.js → chunk-URJN75ZG.js} +29 -16
- package/dist/{chunk-FUQTV5O6.js → chunk-VQQV7FOX.js} +3 -3
- package/dist/{chunk-PKGN32AU.js → chunk-XPTJRVL2.js} +1 -1
- package/dist/{chunk-662ILEZ6.js → chunk-Y35BWW2C.js} +3 -7
- package/dist/{chunk-MHGAZ3LL.js → chunk-YGXWG54S.js} +3 -5
- package/dist/{chunk-AH4AXO4P.js → chunk-Z4MK4VOG.js} +1 -1
- package/dist/{chunk-AV4QAK5F.js → chunk-Z6PVFZRI.js} +5 -4
- package/dist/chunk-ZKADJNR2.js +52 -0
- package/dist/client/index.js +6 -5
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/knowledge.d.ts +84 -0
- package/dist/contracts/sentences.d.ts +46 -0
- package/dist/contracts/site-cache.d.ts +2 -0
- package/dist/cta-bar/index.js +1 -1
- package/dist/fleet/index.js +6 -5
- package/dist/forms/field-autocomplete.d.ts +16 -8
- package/dist/forms/index.d.ts +5 -0
- package/dist/forms/index.js +17 -17
- package/dist/forms/server.js +7 -7
- package/dist/forms/static.js +2 -2
- package/dist/forms/submitForm.d.ts +5 -0
- package/dist/images/index.js +4 -4
- package/dist/index.d.ts +3 -7
- package/dist/index.js +1 -1
- package/dist/layout/SiteKitLayout.d.ts +2 -1
- package/dist/layout/client.js +11 -9
- package/dist/layout/index.js +13 -11
- package/dist/llms/index.js +7 -6
- package/dist/maps/index.js +6 -6
- package/dist/mcp/sonor.d.ts +47 -3
- package/dist/mcp/sonor.js +30 -20
- package/dist/proxy/index.d.ts +3 -3
- package/dist/proxy/index.js +1 -1
- package/dist/reputation/index.js +3 -2
- package/dist/reputation/server.js +2 -1
- package/dist/revalidate/index.js +3 -3
- package/dist/robots/indexnow.js +2 -2
- package/dist/runtime/index.d.ts +32 -0
- package/dist/runtime/index.js +7 -0
- package/dist/seo/api.d.ts +0 -4
- package/dist/seo/client.js +6 -5
- package/dist/seo/getManagedMetadata.d.ts +24 -0
- package/dist/seo/index.d.ts +2 -3
- package/dist/seo/index.js +14 -132
- package/dist/seo/indexnow.js +2 -2
- package/dist/seo/llms.js +7 -6
- package/dist/seo/register-sitemap-cli.js +2 -2
- package/dist/seo/server-api.d.ts +0 -6
- package/dist/seo/server.d.ts +1 -1
- package/dist/seo/server.js +4 -4
- package/dist/seo/sitemap.js +4 -3
- package/dist/seo/types.d.ts +9 -30
- package/dist/server/index.d.ts +8 -1
- package/dist/server/index.js +4 -3
- package/dist/server/mint-site-token.d.ts +0 -11
- package/dist/server/server-fetch.d.ts +19 -0
- package/dist/server-api-EGOKC7Q3.js +9 -0
- package/dist/shared/build-entries.d.ts +21 -9
- package/dist/shared/clientApiConfig.d.ts +56 -0
- package/dist/shared/identity-reader.d.ts +26 -0
- package/dist/shared/identity-storage.d.ts +30 -0
- package/dist/shared/identity.d.ts +13 -13
- package/dist/shared/import-specifiers.d.ts +74 -0
- package/dist/shared/sonorFetch.d.ts +4 -3
- package/dist/shared/source-graph.d.ts +4 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/sitemap/index.js +4 -3
- package/dist/slots/index.js +3 -3
- package/dist/sync/index.js +6 -5
- package/dist/types.d.ts +0 -1
- package/dist/website/cta-bar.js +1 -1
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +7 -6
- package/dist/website/popups.js +10 -7
- package/dist/website/slots.js +3 -3
- package/dist/{writeLLMsTxt-OL4KQERZ.js → writeLLMsTxt-UZGN6IBU.js} +3 -2
- package/docs/MIGRATING-TO-7.md +5 -2
- package/docs/MIGRATING-TO-8.md +183 -0
- package/docs.json +4 -8
- package/package.json +18 -45
- package/skills/site-kit/SKILL.md +41 -11
- package/src/analytics/README.md +14 -14
- package/src/chat/README.md +7 -7
- package/src/forms/README.md +61 -6
- package/src/mcp/README.md +61 -20
- package/src/proxy/README.md +5 -4
- package/src/revalidate/README.md +2 -2
- package/src/runtime/README.md +51 -0
- package/src/seo/README.md +24 -8
- package/src/sync/README.md +2 -2
- package/src/website/README.md +3 -2
- package/dist/AnalyticsProvider-BQXV3ZF3.js +0 -11
- package/dist/ManagedForm-7FZNH4L2.js +0 -16
- package/dist/SiteChat-DMPDXY3W.js +0 -5
- package/dist/SiteDesignReporter-Y2IOJE52.js +0 -11
- package/dist/SitePopups-HD2LDKVU.js +0 -10
- package/dist/SitemapSync-OKPZHRX6.js +0 -8
- package/dist/chunk-24QZEO3Q.js +0 -41
- package/dist/chunk-BU66S5B7.js +0 -1
- package/dist/chunk-G3NHWMP5.js +0 -233
- package/dist/chunk-HODO5BX5.js +0 -28
- package/dist/chunk-L3AQCDCY.js +0 -386
- package/dist/chunk-P5GB6NEO.js +0 -66
- package/dist/chunk-SWKE6FWH.js +0 -47
- package/dist/cms/CmsPage.d.ts +0 -17
- package/dist/cms/CmsPreview.d.ts +0 -37
- package/dist/cms/CmsSection.d.ts +0 -8
- package/dist/cms/PortableTextRenderer.d.ts +0 -7
- package/dist/cms/index.d.ts +0 -37
- package/dist/cms/index.js +0 -5
- package/dist/cms/sanity-image.d.ts +0 -47
- package/dist/cms/sections/CtaSection.d.ts +0 -3
- package/dist/cms/sections/CustomSection.d.ts +0 -7
- package/dist/cms/sections/FaqSection.d.ts +0 -3
- package/dist/cms/sections/FormSection.d.ts +0 -8
- package/dist/cms/sections/GallerySection.d.ts +0 -3
- package/dist/cms/sections/HeroSection.d.ts +0 -3
- package/dist/cms/sections/RichTextSection.d.ts +0 -3
- package/dist/cms/sections/TestimonialsSection.d.ts +0 -3
- package/dist/cms/sections/index.d.ts +0 -8
- package/dist/cms/server-api.d.ts +0 -49
- package/dist/cms/server.d.ts +0 -1
- package/dist/cms/server.js +0 -5
- package/dist/cms/types.d.ts +0 -104
- package/dist/commerce/CalendarView.d.ts +0 -43
- package/dist/commerce/CheckoutForm.d.ts +0 -11
- package/dist/commerce/EventCalendar.d.ts +0 -26
- package/dist/commerce/EventCheckout.d.ts +0 -42
- package/dist/commerce/EventEmbed.d.ts +0 -11
- package/dist/commerce/EventModal.d.ts +0 -43
- package/dist/commerce/EventTile.d.ts +0 -10
- package/dist/commerce/EventsAgenda.d.ts +0 -38
- package/dist/commerce/EventsWidget.d.ts +0 -84
- package/dist/commerce/OfferingCard.d.ts +0 -9
- package/dist/commerce/OfferingList.d.ts +0 -9
- package/dist/commerce/ProductDetail.d.ts +0 -38
- package/dist/commerce/ProductEmbed.d.ts +0 -11
- package/dist/commerce/ProductGrid.d.ts +0 -41
- package/dist/commerce/ProductPage.d.ts +0 -39
- package/dist/commerce/RegistrationForm.d.ts +0 -9
- package/dist/commerce/SizeChart.d.ts +0 -8
- package/dist/commerce/UpcomingEvents.d.ts +0 -9
- package/dist/commerce/api.d.ts +0 -179
- package/dist/commerce/events-extras.d.ts +0 -60
- package/dist/commerce/index.d.ts +0 -33
- package/dist/commerce/index.js +0 -8022
- package/dist/commerce/server.d.ts +0 -161
- package/dist/commerce/server.js +0 -2
- package/dist/commerce/types.d.ts +0 -340
- package/dist/commerce/useEventModal.d.ts +0 -20
- package/dist/commerce/utils.d.ts +0 -17
- package/dist/engage/EngageWidget.d.ts +0 -21
- package/dist/engage/index.d.ts +0 -14
- package/dist/engage/index.js +0 -45
- package/dist/engage/types.d.ts +0 -33
- package/dist/seo/ManagedContent.d.ts +0 -14
- package/dist/server-api-BVCBLJKL.js +0 -9
- package/dist/website/cms/server.d.ts +0 -2
- package/dist/website/cms/server.js +0 -5
- package/dist/website/cms-server.d.ts +0 -2
- package/dist/website/cms.d.ts +0 -2
- package/dist/website/cms.js +0 -5
- package/src/commerce/README.md +0 -109
package/src/mcp/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# `@sonordev/site-kit/mcp
|
|
1
|
+
# `@sonordev/site-kit/mcp`: WebMCP & Model Context Protocol
|
|
2
2
|
|
|
3
3
|
Make a marketing site something an AI agent can **use**, not just read.
|
|
4
4
|
|
|
@@ -8,12 +8,12 @@ definitions:
|
|
|
8
8
|
|
|
9
9
|
| Surface | Who uses it | Entry point |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
| Remote MCP endpoint (Streamable HTTP) | Off-browser agents
|
|
11
|
+
| Remote MCP endpoint (Streamable HTTP) | Off-browser agents: Claude, Cursor, any MCP client | `createMcpHandler` |
|
|
12
12
|
| Server card and experimental AI catalog | Crawlers and clients discovering the endpoint | `createMcpServerCardHandler`, `createMcpAiCatalogHandler` |
|
|
13
13
|
| In-page WebMCP | Browser-driving agents | `<WebMcpTools>`, `declarativeToolForm` |
|
|
14
14
|
|
|
15
|
-
One definition feeding all three is the point. The alternative
|
|
16
|
-
the endpoint and a separate one for the page
|
|
15
|
+
One definition feeding all three is the point. The alternative, a tool list for
|
|
16
|
+
the endpoint and a separate one for the page, drifts, and a stale tool
|
|
17
17
|
definition is worse than none, because the agent believes it.
|
|
18
18
|
|
|
19
19
|
---
|
|
@@ -36,7 +36,7 @@ site's pages use, so an agent gets what a visitor gets.
|
|
|
36
36
|
| `find_pages` | The page that covers a topic |
|
|
37
37
|
| `list_articles`, `get_article` | Its articles (`articles: false` drops them) |
|
|
38
38
|
| `get_reviews` | Reviews verbatim, with who wrote them, and the rating |
|
|
39
|
-
| `list_offerings` | Priced products, services, events (opt-in: `offerings: { path }
|
|
39
|
+
| `list_offerings` | Priced products, services, events (opt-in: `offerings: { path, read }`, see below); private prices are left out |
|
|
40
40
|
| `check_availability` | Open appointment times, read only (opt-in: `booking: { path }`) |
|
|
41
41
|
| `get_inquiry_form`, `send_inquiry` | An inquiry for a person (opt-in: `inquiry: { form }`) |
|
|
42
42
|
|
|
@@ -63,6 +63,47 @@ export const { POST, GET, DELETE, OPTIONS } = createMcpHandler({
|
|
|
63
63
|
})
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
**`list_offerings` needs a reader (8.0).** The catalog it lists belongs to
|
|
67
|
+
[commerce-kit](https://sonor.dev/commerce-kit), so you hand the tool commerce-kit's
|
|
68
|
+
fetcher instead of site-kit importing it:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
// lib/mcp.ts
|
|
72
|
+
import 'server-only'
|
|
73
|
+
import { sonorMcpServer } from '@sonordev/site-kit/mcp/sonor'
|
|
74
|
+
import { getOfferingsResult } from '@sonordev/commerce-kit/commerce/server'
|
|
75
|
+
|
|
76
|
+
export const mcpServer = sonorMcpServer({
|
|
77
|
+
businessName: 'Example Studio',
|
|
78
|
+
offerings: { path: '/shop', read: getOfferingsResult },
|
|
79
|
+
})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`read` is required and is `getOfferingsResult` from
|
|
83
|
+
`@sonordev/commerce-kit/commerce/server`, so the site needs commerce-kit installed
|
|
84
|
+
(`npm install @sonordev/commerce-kit`). When a request fails it tells the agent the
|
|
85
|
+
catalog is unavailable; the plain `getOfferings` from the same entry also works, but
|
|
86
|
+
it reads an outage as an empty catalog. The other tools, `list_services` included,
|
|
87
|
+
don't. `path` is where the offerings' pages live: each offering links to
|
|
88
|
+
`<path>/<slug>` on the site, and `path` defaults to `/shop`. An agent can narrow the
|
|
89
|
+
list with `type` (`product`, `service` or `event`), search it with `query`, and cap
|
|
90
|
+
it with `limit` (at most 20). The tool, how it ranks a query, and its rule that a
|
|
91
|
+
price the business keeps private is never shown all stay in site-kit.
|
|
92
|
+
|
|
93
|
+
`read` is typed `McpOfferingsReader`, and what it returns is a list of `McpOffering`s
|
|
94
|
+
(a name, type, slug, descriptions and a price), or `{ ok, data }` around that list. Both
|
|
95
|
+
types are exported from `@sonordev/site-kit/mcp/sonor`. commerce-kit's fetchers satisfy
|
|
96
|
+
them as they are, so you only meet the types if you supply the catalog from somewhere
|
|
97
|
+
else: write a function that takes `({ apiUrl, apiKey, projectId }, { type, limit })` and
|
|
98
|
+
returns the offerings, and answer `{ ok: false, data: [] }` when the request fails, so
|
|
99
|
+
the agent hears "unavailable" instead of "nothing for sale".
|
|
100
|
+
|
|
101
|
+
Without `read`, `sonorMcpServer` throws when the server is built, with a message that
|
|
102
|
+
names the fix. `npx sonor-setup mcp --offerings /shop` writes this wiring for a new
|
|
103
|
+
site, import included, and tells you to install commerce-kit. Before 8.0 the option
|
|
104
|
+
was `offerings: { path }`; see
|
|
105
|
+
[Moving a site to site-kit 8](../../docs/MIGRATING-TO-8.md#the-mcp-change).
|
|
106
|
+
|
|
66
107
|
**`send_inquiry` has a person behind it.** It refuses unless
|
|
67
108
|
`person_confirmed` is true (the person asked to be contacted and agreed to
|
|
68
109
|
share their details), files through Sonor's agent-inquiry door with the
|
|
@@ -205,7 +246,7 @@ aliases for clients that already use them. The card handler's default remains
|
|
|
205
246
|
### 4. Register in-page (optional, for browser agents)
|
|
206
247
|
|
|
207
248
|
```tsx
|
|
208
|
-
// app/layout.tsx
|
|
249
|
+
// app/layout.tsx: a CHILDLESS SIBLING, never a wrapper
|
|
209
250
|
<SiteKitLayout>{children}</SiteKitLayout>
|
|
210
251
|
<WebMcpTools endpoint="/api/mcp" />
|
|
211
252
|
```
|
|
@@ -290,13 +331,13 @@ The header and label default to `x-site-mcp-transport` and
|
|
|
290
331
|
`{ header, label }` to all three factories (for example
|
|
291
332
|
`x-example-mcp-transport` / `example-mcp-transport-v1`). This entry is Node
|
|
292
333
|
only and imports no `server-only`, so the plain-Node function can load it. It
|
|
293
|
-
|
|
334
|
+
isn't re-exported from `@sonordev/site-kit/mcp`, which stays runtime-neutral.
|
|
294
335
|
|
|
295
336
|
---
|
|
296
337
|
|
|
297
338
|
## Design notes
|
|
298
339
|
|
|
299
|
-
### The card
|
|
340
|
+
### The card doesn't list tools, on purpose
|
|
300
341
|
|
|
301
342
|
The card's discovery shape omits primitives: what a server exposes can
|
|
302
343
|
vary with auth state and configuration, so the authoritative list is whatever
|
|
@@ -306,8 +347,8 @@ source of truth that goes stale silently.
|
|
|
306
347
|
We still publish a **summary** (name + description + read-only flag) under
|
|
307
348
|
`_meta['io.sonor.site-kit/tools']`. `_meta` is the spec's sanctioned extension
|
|
308
349
|
point and requires a reverse-DNS prefix, so the hint rides along without
|
|
309
|
-
pretending to be standard
|
|
310
|
-
connect.
|
|
350
|
+
pretending to be standard. That's useful for crawlers that index the card and
|
|
351
|
+
never connect.
|
|
311
352
|
|
|
312
353
|
### Experimental discovery and compatibility paths
|
|
313
354
|
|
|
@@ -323,21 +364,21 @@ URLs working while adding the catalog.
|
|
|
323
364
|
|
|
324
365
|
`dispatch()` answers both protocol eras on one endpoint:
|
|
325
366
|
|
|
326
|
-
- **Modern (`2026-07-28`)
|
|
367
|
+
- **Modern (`2026-07-28`)**: stateless, per-request `_meta` carrying the
|
|
327
368
|
protocol version, mirrored into `MCP-Protocol-Version`. `server/discover`
|
|
328
369
|
replaces the handshake. No sessions, no GET stream (both return `405`).
|
|
329
|
-
- **Legacy (`≤ 2025-11-25`)
|
|
370
|
+
- **Legacy (`≤ 2025-11-25`)**: the `initialize` handshake, which is what most
|
|
330
371
|
shipped clients and SDKs still speak.
|
|
331
372
|
|
|
332
373
|
Supporting only the current revision would be spec-correct and unusable today.
|
|
333
374
|
|
|
334
|
-
### Header mirroring: mismatch is fatal, absence
|
|
375
|
+
### Header mirroring: mismatch is fatal, absence isn't
|
|
335
376
|
|
|
336
377
|
The modern revision mirrors `method` and `params.name` into `Mcp-Method` and
|
|
337
378
|
`Mcp-Name` so intermediaries can route without parsing bodies, and requires
|
|
338
379
|
servers to reject disagreements (`-32020`).
|
|
339
380
|
|
|
340
|
-
We always reject a **mismatch
|
|
381
|
+
We always reject a **mismatch**; that's the real security property, stopping
|
|
341
382
|
a load balancer and the server from acting on different values. A merely
|
|
342
383
|
**absent** header is tolerated unless you set `strictHeaders: true`, because a
|
|
343
384
|
public marketing endpoint exists to be reachable and today's clients frequently
|
|
@@ -360,13 +401,13 @@ one or the other makes you invisible to a large slice of the ecosystem.
|
|
|
360
401
|
|
|
361
402
|
`<WebMcpTools>` does nothing at all unless `document.modelContext` exists. That
|
|
362
403
|
gate comes before the `tools/list` fetch, so the cost for a human visitor is a
|
|
363
|
-
single property check
|
|
404
|
+
single property check: not a request, and not a byte of page weight.
|
|
364
405
|
|
|
365
406
|
### In-page tools are proxied, not re-implemented
|
|
366
407
|
|
|
367
408
|
`<WebMcpTools>` registers thin wrappers that POST `tools/call` to this site's
|
|
368
409
|
own endpoint, so the in-page tool and the remote tool run the same server-side
|
|
369
|
-
handler. It also keeps `SONOR_API_KEY` out of the client bundle
|
|
410
|
+
handler. It also keeps `SONOR_API_KEY` out of the client bundle: registering
|
|
370
411
|
real handlers client-side would pull server code, and the key with it, into a
|
|
371
412
|
`'use client'` graph and a public chunk.
|
|
372
413
|
|
|
@@ -376,13 +417,13 @@ Tools that genuinely need live DOM state go in `localTools` and run in-page.
|
|
|
376
417
|
|
|
377
418
|
`<WebMcpTools>` waits for the page to go quiet (`useDeferredActivation`) before
|
|
378
419
|
touching `document.modelContext`. Agents poll or listen for `toolchange`, so a
|
|
379
|
-
few hundred milliseconds costs nothing
|
|
420
|
+
few hundred milliseconds costs nothing, while a blocked LCP costs a lot.
|
|
380
421
|
|
|
381
422
|
---
|
|
382
423
|
|
|
383
424
|
## Writing good tools
|
|
384
425
|
|
|
385
|
-
The `description` is the highest-leverage field in this module. It
|
|
426
|
+
The `description` is the highest-leverage field in this module. It's the only
|
|
386
427
|
thing a model reads when deciding whether to call the tool.
|
|
387
428
|
|
|
388
429
|
- **Verb-led `snake_case` names**: `get_services`, `request_site_audit`.
|
|
@@ -391,10 +432,10 @@ thing a model reads when deciding whether to call the tool.
|
|
|
391
432
|
- **Set `annotations` honestly.** `readOnlyHint` on lookups; `destructiveHint`
|
|
392
433
|
on anything creating a record. Good agents use these to decide what needs a
|
|
393
434
|
human.
|
|
394
|
-
- **Never `toolautosubmit` a lead form.** That
|
|
435
|
+
- **Never `toolautosubmit` a lead form.** That's how an agent files fifty
|
|
395
436
|
audit requests by accident.
|
|
396
437
|
- **Return the caveat with the data.** A pricing tool should return the ranges
|
|
397
|
-
*and* the fact that they
|
|
438
|
+
*and* the fact that they're ranges; otherwise the model quotes a number as
|
|
398
439
|
a commitment.
|
|
399
440
|
|
|
400
441
|
## Testing an endpoint by hand
|
package/src/proxy/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Composable Next.js Proxy factory. Zero-config redirects + security headers. Opt-in AI discovery headers.
|
|
4
4
|
|
|
5
|
-
Next 16 renamed the `middleware` file convention to `proxy`.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Next 16 renamed the `middleware` file convention to `proxy`. This module is
|
|
6
|
+
also served on `@sonordev/site-kit/middleware`, with `createMiddleware` as an
|
|
7
|
+
alias of `createProxy`. Both are deprecated and still work in 8; they'll go in a
|
|
8
|
+
later major, so move off them when you next touch the file.
|
|
9
|
+
`npx sonor-setup codemod --write` moves a site over (the file too).
|
|
9
10
|
|
|
10
11
|
## Usage
|
|
11
12
|
|
package/src/revalidate/README.md
CHANGED
|
@@ -15,7 +15,7 @@ tells you when it's missing.
|
|
|
15
15
|
|
|
16
16
|
Everything site-kit fetches from Sonor is cached, and pages built from those
|
|
17
17
|
fetches are served from your host's CDN. When content changes in Sonor
|
|
18
|
-
(managed copy, a page's title or description, an article, a portfolio item),
|
|
18
|
+
(managed copy, a page's title or description, an article, a portfolio item, a product or event),
|
|
19
19
|
Sonor sends this route the paths and cache tags that changed. The route checks
|
|
20
20
|
the call was signed with your project's API key, then expires only those
|
|
21
21
|
pages and tags. The next visitor gets the new version, and every other page
|
|
@@ -60,7 +60,7 @@ A POST with `Authorization: Bearer <SONOR_API_KEY>` and a JSON body:
|
|
|
60
60
|
| Field | Meaning |
|
|
61
61
|
|---|---|
|
|
62
62
|
| `paths` | Local paths to regenerate. `/sitemap.xml`, `/llms.txt` and `/llms-full.txt` are always refreshed too. |
|
|
63
|
-
| `tags` | Cache tags to expire. The ones Sonor uses are `SITE_CACHE_TAGS`: `sonor-slots` (managed copy), `seo` (metadata, schema, FAQs), `blog` (articles), `editorial-taxonomy` and `
|
|
63
|
+
| `tags` | Cache tags to expire. The ones Sonor uses are `SITE_CACHE_TAGS`: `sonor-slots` (managed copy), `seo` (metadata, schema, FAQs), `blog` (articles), `editorial-taxonomy`, `portfolio` and `commerce` (products, services, events and membership plans, from [commerce-kit](https://sonor.dev/commerce-kit)). |
|
|
64
64
|
| `revalidateAll` | Regenerate every page. |
|
|
65
65
|
| `ping` | `{ "ping": true }` on its own regenerates nothing and answers `{ "ok": true, "ping": true, "version": "…" }`. Sonor uses it to confirm the route is installed. |
|
|
66
66
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Runtime
|
|
2
|
+
|
|
3
|
+
`@sonordev/site-kit/runtime` is how a package that builds on site-kit talks to Sonor from the browser, so it never needs a transport of its own. [commerce-kit](https://sonor.dev/commerce-kit) is built on it.
|
|
4
|
+
|
|
5
|
+
Building a site? You don't need this entry. Forms, analytics, articles and the rest of site-kit already use the same transport.
|
|
6
|
+
|
|
7
|
+
## What it gives a kit
|
|
8
|
+
|
|
9
|
+
| Export | Use it to |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `sonorFetch(url, init?, options?)` | Call the Sonor API from the browser. It sends the site credential you pass as `apiKey`, retries transient failures with a timeout, refreshes an expired site token once, and pauses for a few minutes after an authentication failure, so a misconfigured site doesn't hammer the API. |
|
|
12
|
+
| `getClientApiConfig(options?)` | Find the API origin and credential. In the browser that's what `SiteKitLayout` published. During server rendering it's the server's `SONOR_API_URL`, and with `{ serverKey: true }` its `SONOR_API_KEY`. |
|
|
13
|
+
| `readPublishedApiConfig()` | Exactly what `SiteKitLayout` published, with no fallbacks. For code that must stay quiet on a page without the layout. |
|
|
14
|
+
| `DEFAULT_SONOR_API_URL` | `https://api.sonor.io`. |
|
|
15
|
+
| `readAnalyticsIdentity()` | Get the visitor's analytics ids, `{ sessionId, visitorId }`, so what you send to Sonor ties to the visit analytics recorded. It only reads: either id is `null` during server rendering and before analytics has started a session in the tab. It never throws, including when the browser blocks site storage. |
|
|
16
|
+
|
|
17
|
+
The types `SonorFetchOptions`, `FetchRetryOptions`, `ClientApiConfigOptions` and `AnalyticsIdentity` come with them.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { getClientApiConfig, sonorFetch } from '@sonordev/site-kit/runtime'
|
|
21
|
+
|
|
22
|
+
export async function startCheckout(payload: unknown) {
|
|
23
|
+
const { apiUrl, apiKey } = getClientApiConfig()
|
|
24
|
+
// Anything that isn't safe to repeat (checkout, payments, uploads) passes retries: 0.
|
|
25
|
+
const response = await sonorFetch(
|
|
26
|
+
`${apiUrl}/api/public/example/checkout`,
|
|
27
|
+
{ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) },
|
|
28
|
+
{ apiKey, retries: 0 },
|
|
29
|
+
)
|
|
30
|
+
return response.json()
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Pass `apiKey` from `getClientApiConfig()` and `sonorFetch` sets the `x-api-key` header itself, using the site's freshest token when the site uses one. Don't set `x-api-key` or `Authorization` yourself: on a site that uses tokens, a stale header you set is replaced by the fresh one.
|
|
35
|
+
|
|
36
|
+
## Rules for kits
|
|
37
|
+
|
|
38
|
+
- **Use this entry for browser calls.** Don't read `window.__SITE_KIT_*` and don't call `fetch` on the Sonor API directly. A second transport is a second copy of the credential, retry and breaker logic, and it drifts.
|
|
39
|
+
- **Get the visitor's ids from `readAnalyticsIdentity()`.** Where site-kit keeps them is its own business and can change.
|
|
40
|
+
- **Server data goes through `@sonordev/site-kit/server`.** `serverApiFetch` sends the key, bounds each call in time and retries transient failures. Tag what you fetch with your content's entry in `SITE_CACHE_TAGS` so an edit in Sonor refreshes it, and if you catch errors around your own server calls, rethrow the ones `isNextControlFlow` recognizes: they're Next steering the render (a page turning dynamic, `redirect()`, `notFound()`), not failures.
|
|
41
|
+
- **Events go through `trackEvent` and `trackConversion`** from `@sonordev/site-kit/analytics` (`@sonordev/site-kit/client` exports them too). They wait for the analytics provider, which mounts after the page. Don't use the `useAnalytics` hooks in a kit: under `SiteKitLayout` your components sit outside the provider, so the hooks have nothing to return.
|
|
42
|
+
- **Lead capture goes through `ManagedForm`** from `@sonordev/site-kit/forms`.
|
|
43
|
+
- **List site-kit as a peer dependency** and mark it external in your bundler, so every kit shares the site's one copy.
|
|
44
|
+
|
|
45
|
+
## Why it's its own entry
|
|
46
|
+
|
|
47
|
+
`@sonordev/site-kit/client` is stamped `'use client'`. A function imported from a stamped module into a server component becomes a client reference there and can't be called, and `getClientApiConfig` is built to run during server rendering. So `runtime` isn't stamped, imports neither React nor Next, and works the same from a server component, a route handler or a client component.
|
|
48
|
+
|
|
49
|
+
## Stability
|
|
50
|
+
|
|
51
|
+
This entry is public API under semver. New exports arrive in minor releases; nothing in the list above is removed or changed in a minor or patch release.
|
package/src/seo/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SEO: `@sonordev/site-kit/seo`
|
|
2
2
|
|
|
3
|
-
Server Components and server helpers that render what you manage in the SEO module at [app.sonor.io](https://app.sonor.io): page metadata, JSON-LD, FAQs, internal links,
|
|
3
|
+
Server Components and server helpers that render what you manage in the SEO module at [app.sonor.io](https://app.sonor.io): page metadata, JSON-LD, FAQs, internal links, redirects and robots directives.
|
|
4
4
|
|
|
5
5
|
The project comes from `SONOR_API_KEY`. Nothing in this module takes a project ID. A few option types and props still carry an optional `projectId` from older versions; it's ignored, so leave it out.
|
|
6
6
|
|
|
@@ -55,6 +55,7 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
|
|
|
55
55
|
| `fallback` | `Metadata` | Fills any field Sonor has no managed value for. Used in full when the page isn't in Sonor at all. |
|
|
56
56
|
| `overrides` | `Partial<Metadata>` | Applied last, so it wins over managed values. |
|
|
57
57
|
| `favicon` | `'metadata' \| 'component'` | `'metadata'` (default) adds `icons` from the project logo. Pass `'component'` when your layout already renders the favicon, which `SiteKitLayout` does by default, so icons aren't emitted twice. |
|
|
58
|
+
| `scope` | `'page' \| 'layout'` | `'page'` (default) applies Sonor's managed canonical and hreflang for `path`. Pass `'layout'` when you call this from a root or shared layout, whose metadata every route beneath it inherits. See [Canonical URLs](#canonical-urls). |
|
|
58
59
|
|
|
59
60
|
It returns a Next.js `Metadata` object with two extra flags, `_managed` and `_source`. Managed fields map like this:
|
|
60
61
|
|
|
@@ -70,6 +71,27 @@ It returns a Next.js `Metadata` object with two extra flags, `_managed` and `_so
|
|
|
70
71
|
|
|
71
72
|
When the page exists in Sonor but has neither a title nor a description, the call asks Signal to write them in the background and returns your fallback for now. The generated copy shows up once the cached response refreshes (see [Caching](#caching)).
|
|
72
73
|
|
|
74
|
+
### Canonical URLs
|
|
75
|
+
|
|
76
|
+
Every page gets a canonical, so you never have to set one by hand. When Sonor has no `managed_canonical` for the page, `getManagedMetadata` returns `alternates.canonical: './'`. Next resolves that against your `metadataBase` and the route being rendered, so each page names itself (`https://example.com/about` for `/about`). Without a `metadataBase`, Next emits the path alone (`/about`), which is still valid. Set `metadataBase` in your root layout for absolute URLs.
|
|
77
|
+
|
|
78
|
+
The order, lowest to highest: the self-referencing default, then Sonor's managed canonical and hreflang, then your `fallback`, then your `overrides`. `alternates` merges key by key, so passing only `languages` keeps the canonical, and `canonical: null` opts out.
|
|
79
|
+
|
|
80
|
+
**Calling it from a layout.** A layout's metadata is inherited by every page under it. If your root layout calls `getManagedMetadata({ path: '/' })`, pass `scope: 'layout'`. Otherwise a managed canonical set for the homepage in Sonor is stamped on every page without its own, and each one tells search engines it's a copy of the homepage:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
// app/layout.tsx
|
|
84
|
+
export async function generateMetadata() {
|
|
85
|
+
return getManagedMetadata({
|
|
86
|
+
path: '/',
|
|
87
|
+
scope: 'layout',
|
|
88
|
+
fallback: { title: 'Example Co', description: 'Plumbing in Cincinnati.' },
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Don't set an absolute `alternates.canonical` in a layout for the same reason. Use `'./'`, or leave it to this helper.
|
|
94
|
+
|
|
73
95
|
**Title templates.** The managed title comes back as a plain string, so a root-layout `title.template` still applies to it. If your managed titles already include the brand, you'll get it twice. Mark the title absolute:
|
|
74
96
|
|
|
75
97
|
```ts
|
|
@@ -100,7 +122,7 @@ export const generateMetadata = withManagedMetadata('/about', async () => ({
|
|
|
100
122
|
}))
|
|
101
123
|
```
|
|
102
124
|
|
|
103
|
-
Whatever `pageMetadata` returns wins over Sonor's values. `openGraph` and `
|
|
125
|
+
Whatever `pageMetadata` returns wins over Sonor's values. `openGraph`, `twitter` and `alternates` merge one level deep, so a page that returns only `alternates.languages` keeps its canonical. It calls `getManagedMetadata` with the default `favicon: 'metadata'`.
|
|
104
126
|
|
|
105
127
|
### A/B-tested titles and descriptions
|
|
106
128
|
|
|
@@ -221,10 +243,6 @@ Renders the internal links Sonor has for `path` at that position, or nothing whe
|
|
|
221
243
|
|
|
222
244
|
`limit` defaults to 5. `renderLink(link)` replaces the default `<a>`, and `className` replaces the default `sk-internal-links sk-internal-links--{position}`. `site` pins the sub-site host (see [Multi-site projects](#multi-site-projects)).
|
|
223
245
|
|
|
224
|
-
## Content blocks: `<ManagedContent>` (deprecated)
|
|
225
|
-
|
|
226
|
-
Deprecated in 7.1 and removed in 8.0. Page copy is [managed copy](../slots/README.md) now: wrap the text in `<ManagedSlot>` or `<ManagedRichText>` and edit it in Sonor under Website → Content, with drafts, history and Edit on page. Sonor no longer creates content blocks, so `ManagedContent` renders its `fallback`.
|
|
227
|
-
|
|
228
246
|
## Multi-site projects
|
|
229
247
|
|
|
230
248
|
One Sonor project can serve many domains (example.com plus its city microsites). Managed FAQs and internal links can be project-wide (every host) or tagged with one host (that host only). `ManagedFAQ` and `ManagedInternalLinks` send the site host with every read, so each microsite gets its own rows plus the project-wide ones, never a sibling's.
|
|
@@ -235,7 +253,6 @@ The host resolves from `NEXT_PUBLIC_SITE_URL`, which every microsite already set
|
|
|
235
253
|
<ManagedFAQ path="/contact" site="charlotte.example.com" />
|
|
236
254
|
await getFAQData('/contact', 'charlotte.example.com')
|
|
237
255
|
await getInternalLinks('/contact', { position: 'bottom', site: 'charlotte.example.com' })
|
|
238
|
-
await getContentBlock('/contact', 'hero', 'charlotte.example.com')
|
|
239
256
|
```
|
|
240
257
|
|
|
241
258
|
When no host resolves, `site` is left off and the API answers for the project's primary domain. Single-site projects and older API servers ignore it.
|
|
@@ -288,7 +305,6 @@ Every component above is built on these. They're server-only, take paths rather
|
|
|
288
305
|
| `getSchemaMarkups(path, { includeTypes?, excludeTypes? })` | Schema rows (`schema_type`, `schema_json`, ...). `excludeTypes` also prunes matching nodes inside each row. |
|
|
289
306
|
| `getFAQData(path, site?)` | The FAQ (`title`, `description`, `items`, `include_schema`), or `null` |
|
|
290
307
|
| `getInternalLinks(path, { position?, limit?, site? })` | Link rows |
|
|
291
|
-
| `getContentBlock(path, section, site?)` | The content block, or `null` |
|
|
292
308
|
| `getABTest(path, field)` | The running test for that field, or `null` |
|
|
293
309
|
| `recordABImpression(testId, variant, sessionId?)` | `void` |
|
|
294
310
|
| `getRedirectData(path)` | The raw redirect row, or `null` |
|
package/src/sync/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Sync (Booking)
|
|
1
|
+
# Sync (Booking): `@sonordev/site-kit/sync`
|
|
2
2
|
|
|
3
|
-
Embeddable booking/scheduling widget
|
|
3
|
+
Embeddable booking/scheduling widget, like Calendly, built into Sonor. Appointments, consultations, classes.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
package/src/website/README.md
CHANGED
|
@@ -129,5 +129,6 @@ import { PopupBlocks } from '@sonordev/site-kit/website/popups'
|
|
|
129
129
|
Engage was retired in Sonor, and its popups with it. Popups made in Engage
|
|
130
130
|
Studio (a `design_json` without blocks) aren't drawn by site-kit 7.2 or later;
|
|
131
131
|
make them again in Website → Popups & Banners. `@sonordev/site-kit/engage`
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
was removed in site-kit 8: `SiteKitLayout` mounts `SitePopups` and the website
|
|
133
|
+
chat for you, and `npx sonor-setup codemod --write` moves the names that have
|
|
134
|
+
a home.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export { AnalyticsProvider, useAnalytics, useAnalyticsOptional, useTrackEvent } from './chunk-CKW4HFJG.js';
|
|
2
|
-
import './chunk-LCDVPAMR.js';
|
|
3
|
-
import './chunk-24QZEO3Q.js';
|
|
4
|
-
import './chunk-L2V5PUFN.js';
|
|
5
|
-
import './chunk-GJWI74ZZ.js';
|
|
6
|
-
import './chunk-43OCZ3JA.js';
|
|
7
|
-
import './chunk-EKBEOXTH.js';
|
|
8
|
-
import './chunk-3E3PPSNR.js';
|
|
9
|
-
import './chunk-GK7TV7EK.js';
|
|
10
|
-
import './chunk-KHQ5GD6T.js';
|
|
11
|
-
import './chunk-PKBMQBKP.js';
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export { ManagedForm } from './chunk-MDP7EB4J.js';
|
|
2
|
-
import './chunk-ATE6IFVK.js';
|
|
3
|
-
import './chunk-DXO6SBMD.js';
|
|
4
|
-
import './chunk-4NTBQNHA.js';
|
|
5
|
-
import './chunk-CSN45MHO.js';
|
|
6
|
-
import './chunk-Q6E4OPGG.js';
|
|
7
|
-
import './chunk-C2FZBUSS.js';
|
|
8
|
-
import './chunk-5SQK3D53.js';
|
|
9
|
-
import './chunk-HW7B43E5.js';
|
|
10
|
-
import './chunk-NJCTQH2P.js';
|
|
11
|
-
import './chunk-L2V5PUFN.js';
|
|
12
|
-
import './chunk-GJWI74ZZ.js';
|
|
13
|
-
import './chunk-3E3PPSNR.js';
|
|
14
|
-
import './chunk-GK7TV7EK.js';
|
|
15
|
-
import './chunk-KHQ5GD6T.js';
|
|
16
|
-
import './chunk-PKBMQBKP.js';
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export { SiteDesignReporter } from './chunk-PQDJNIHR.js';
|
|
2
|
-
import './chunk-CG4ETW5Y.js';
|
|
3
|
-
import './chunk-IHG36STL.js';
|
|
4
|
-
import './chunk-YC7ELZS3.js';
|
|
5
|
-
import './chunk-S22FSH7C.js';
|
|
6
|
-
import './chunk-43OCZ3JA.js';
|
|
7
|
-
import './chunk-EKBEOXTH.js';
|
|
8
|
-
import './chunk-3E3PPSNR.js';
|
|
9
|
-
import './chunk-GK7TV7EK.js';
|
|
10
|
-
import './chunk-KHQ5GD6T.js';
|
|
11
|
-
import './chunk-PKBMQBKP.js';
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { SitePopups } from './chunk-6LLTLLEJ.js';
|
|
2
|
-
import './chunk-27FISYK4.js';
|
|
3
|
-
import './chunk-24QZEO3Q.js';
|
|
4
|
-
import './chunk-GJWI74ZZ.js';
|
|
5
|
-
import './chunk-43OCZ3JA.js';
|
|
6
|
-
import './chunk-EKBEOXTH.js';
|
|
7
|
-
import './chunk-3E3PPSNR.js';
|
|
8
|
-
import './chunk-GK7TV7EK.js';
|
|
9
|
-
import './chunk-KHQ5GD6T.js';
|
|
10
|
-
import './chunk-PKBMQBKP.js';
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { SitemapSync } from './chunk-D2RGEWHS.js';
|
|
2
|
-
import './chunk-YVKRYQRG.js';
|
|
3
|
-
import './chunk-43OCZ3JA.js';
|
|
4
|
-
import './chunk-EKBEOXTH.js';
|
|
5
|
-
import './chunk-3E3PPSNR.js';
|
|
6
|
-
import './chunk-GK7TV7EK.js';
|
|
7
|
-
import './chunk-KHQ5GD6T.js';
|
|
8
|
-
import './chunk-PKBMQBKP.js';
|
package/dist/chunk-24QZEO3Q.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { uuid } from './chunk-GJWI74ZZ.js';
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
|
|
5
|
-
function getOrCreateVisitorId() {
|
|
6
|
-
if (typeof window === "undefined") return "";
|
|
7
|
-
let visitorId = localStorage.getItem("_sk_vid");
|
|
8
|
-
if (!visitorId) {
|
|
9
|
-
visitorId = uuid();
|
|
10
|
-
}
|
|
11
|
-
localStorage.setItem("_sk_vid", visitorId);
|
|
12
|
-
return visitorId;
|
|
13
|
-
}
|
|
14
|
-
function getOrCreateSessionId(timeoutMinutes = 30) {
|
|
15
|
-
if (typeof window === "undefined") return "";
|
|
16
|
-
const now = Date.now();
|
|
17
|
-
const timeoutMs = timeoutMinutes * 60 * 1e3;
|
|
18
|
-
const existingSession = sessionStorage.getItem("_sk_sid");
|
|
19
|
-
const lastActivity = sessionStorage.getItem("_sk_stime");
|
|
20
|
-
if (existingSession && lastActivity) {
|
|
21
|
-
const elapsed = now - parseInt(lastActivity, 10);
|
|
22
|
-
if (elapsed < timeoutMs) {
|
|
23
|
-
sessionStorage.setItem("_sk_stime", now.toString());
|
|
24
|
-
sessionStorage.setItem("_sk_sid", existingSession);
|
|
25
|
-
return existingSession;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
const newSession = uuid();
|
|
29
|
-
sessionStorage.setItem("_sk_sid", newSession);
|
|
30
|
-
sessionStorage.setItem("_sk_stime", now.toString());
|
|
31
|
-
return newSession;
|
|
32
|
-
}
|
|
33
|
-
function useSiteKitIdentity() {
|
|
34
|
-
const [identity] = useState(() => ({
|
|
35
|
-
visitorId: getOrCreateVisitorId(),
|
|
36
|
-
sessionId: getOrCreateSessionId()
|
|
37
|
-
}));
|
|
38
|
-
return identity;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export { getOrCreateSessionId, getOrCreateVisitorId, useSiteKitIdentity };
|
package/dist/chunk-BU66S5B7.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|