@sonordev/site-kit 7.1.2 → 7.2.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/AGENTS.md +1 -1
- package/CHANGELOG.md +51 -0
- package/README.md +9 -8
- package/agent-manifest.json +12 -4
- package/dist/{AnalyticsProvider-ZB33W6MC.js → AnalyticsProvider-SLFFBRPE.js} +4 -4
- package/dist/{ArticleViewTracker-GMHYLLLZ.js → ArticleViewTracker-TM5AMGN2.js} +3 -3
- package/dist/{BlocksPopup-EA6LYL25.js → BlocksPopup-YJNJIVPO.js} +5 -5
- package/dist/ChatWidget-XKOSH66S.js +17 -0
- package/dist/{FileField-QKA3JB2Q.js → FileField-CI4UL5SH.js} +3 -3
- package/dist/{FormSpotlight-AQTIA5TP.js → FormSpotlight-F2AAEGBN.js} +20 -6
- package/dist/{FormStage-FDTLTP3B.js → FormStage-BI5R5CNC.js} +27 -7
- package/dist/ManagedForm-G6COGHXL.js +16 -0
- package/dist/{ManagedNewsletterForm-J6QSAGGP.js → ManagedNewsletterForm-BO3WCGXX.js} +7 -5
- package/dist/{SignalCore-JZNXOLNT.js → SignalCore-ZA6WHKBR.js} +3 -3
- package/dist/SiteChat-YJADDTKG.js +5 -0
- package/dist/{SiteDesignReporter-W4EJUSTE.js → SiteDesignReporter-5YAW36AQ.js} +5 -5
- package/dist/SitePopups-ST5PMKZE.js +10 -0
- package/dist/SitemapSync-RJTEBINX.js +8 -0
- package/dist/_client/booking-widget.js +5 -5
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/index.js +4 -4
- package/dist/analytics/send-gate.d.ts +1 -1
- package/dist/articles/index.js +2 -2
- package/dist/articles/server-ui.js +3 -2
- package/dist/articles/server.js +2 -1
- package/dist/{engage → chat}/ChatWidget.d.ts +7 -6
- package/dist/{engage → chat}/EchoUiActions.d.ts +1 -1
- package/dist/chat/SiteChat.d.ts +25 -0
- package/dist/{engage → chat}/brand-color.d.ts +1 -1
- package/dist/{engage → chat}/chat-messages.d.ts +1 -1
- package/dist/{engage → chat}/echo-config.d.ts +1 -1
- package/dist/chat/index.d.ts +10 -6
- package/dist/chat/index.js +14 -8
- package/dist/{engage → chat}/launcher-placement.d.ts +1 -7
- package/dist/{engage → chat}/socket-loader.d.ts +2 -2
- package/dist/chat/types.d.ts +136 -0
- package/dist/chunk-27FISYK4.js +4 -0
- package/dist/{chunk-LUXVWITO.js → chunk-4NTBQNHA.js} +247 -78
- package/dist/{chunk-V3PUVBME.js → chunk-5V2V5C3Y.js} +2 -4
- package/dist/{chunk-Q4W23JYM.js → chunk-5YCEMV2L.js} +1 -1
- package/dist/{chunk-RHNWA34F.js → chunk-64DKGVEI.js} +41 -7
- package/dist/{chunk-GLHQ3LRO.js → chunk-6U3VLV2C.js} +1 -1
- package/dist/{chunk-WWSHFRDL.js → chunk-BC4Y3S3D.js} +1 -1
- package/dist/{chunk-JSZN6LDZ.js → chunk-BF7TZYC3.js} +38 -31
- package/dist/{chunk-M3YEPKP7.js → chunk-BKY2ZNM7.js} +1 -1
- package/dist/{chunk-AQSNPZY4.js → chunk-C2FZBUSS.js} +80 -1
- package/dist/{chunk-NK4CSJNP.js → chunk-CF5QNFYU.js} +2 -2
- package/dist/{chunk-D5EC5KVO.js → chunk-D5DCBD4Y.js} +2 -2
- package/dist/{chunk-3SDOQUUF.js → chunk-D6ZC7XKZ.js} +2 -2
- package/dist/chunk-EJVQJCG5.js +370 -0
- package/dist/{chunk-AH5Q262S.js → chunk-F24FNCTK.js} +1 -1
- package/dist/{chunk-V6FDQLR7.js → chunk-FR6BYFPC.js} +53 -21
- package/dist/{chunk-UXOGCKL6.js → chunk-GEXT7BTE.js} +1 -1
- package/dist/{chunk-JTU2GOM4.js → chunk-GGORNBSC.js} +18 -6
- package/dist/{chunk-ERXXITG4.js → chunk-HGFAEDG3.js} +1 -1
- package/dist/chunk-HODO5BX5.js +28 -0
- package/dist/chunk-HW7B43E5.js +14 -0
- package/dist/{chunk-CSTQDNGK.js → chunk-IAM3D3RL.js} +43 -24
- package/dist/{chunk-PGMVL4AB.js → chunk-JJ3DELUL.js} +2 -2
- package/dist/{chunk-ILU5I6RW.js → chunk-JMLK6MH7.js} +1 -1
- package/dist/{chunk-YEMPUQVU.js → chunk-JWTQS5F5.js} +2 -2
- package/dist/{chunk-VDF5DFWT.js → chunk-K4ZHAURD.js} +1 -1
- package/dist/chunk-NV72HZ4W.js +45 -0
- package/dist/{chunk-4Y5FWDPM.js → chunk-NZ4RXN3G.js} +55 -7
- package/dist/chunk-OWZ7ATLZ.js +187 -0
- package/dist/{chunk-TXBAOEKG.js → chunk-PKGN32AU.js} +5 -4
- package/dist/chunk-Q6E4OPGG.js +40 -0
- package/dist/{chunk-QEDHRBAT.js → chunk-QL6XNPSD.js} +2 -2
- package/dist/{chunk-JBE46QJZ.js → chunk-R46IQIGK.js} +1 -1
- package/dist/{chunk-6WIQCXOO.js → chunk-RPZ7OQGD.js} +1 -1
- package/dist/{chunk-PHYMNUJU.js → chunk-S54ECQGY.js} +1 -1
- package/dist/{chunk-VGH4MDTU.js → chunk-VHKEF5ZB.js} +1 -1
- package/dist/{chunk-HF57LG73.js → chunk-VO3JYRT5.js} +43 -29
- package/dist/chunk-VWWITFWM.js +300 -0
- package/dist/{chunk-CIG5UL2S.js → chunk-ZTLMPUO6.js} +3 -2
- package/dist/client/index.js +3 -3
- package/dist/commerce/index.js +4 -4
- package/dist/contracts/color.d.ts +1 -1
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/error-page.d.ts +183 -0
- package/dist/contracts/llms.d.ts +1 -0
- package/dist/contracts/proposal-sitemap.d.ts +130 -0
- package/dist/contracts/schema-placeholders.d.ts +87 -0
- package/dist/engage/EngageWidget.d.ts +13 -12
- package/dist/engage/index.d.ts +10 -9
- package/dist/engage/index.js +31 -35
- package/dist/engage/types.d.ts +19 -244
- package/dist/fleet/FleetHeartbeat.d.ts +1 -1
- package/dist/fleet/index.js +4 -4
- package/dist/forms/FormEnhancer.d.ts +25 -12
- package/dist/forms/ServerForm.d.ts +11 -10
- package/dist/forms/StaticForm.d.ts +3 -1
- package/dist/forms/field-autocomplete.d.ts +28 -0
- package/dist/forms/form-dom-values.d.ts +42 -0
- package/dist/forms/index.js +11 -9
- package/dist/forms/server.js +6 -4
- package/dist/forms/static.js +3 -2
- package/dist/forms/submitForm.d.ts +8 -1
- package/dist/forms/types.d.ts +41 -2
- package/dist/forms/useForm.d.ts +21 -4
- package/dist/forms/webmcp.d.ts +38 -0
- package/dist/images/index.js +4 -4
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/layout/SiteKitClientProviders.d.ts +3 -3
- package/dist/layout/SiteKitLayout.d.ts +4 -4
- package/dist/layout/client.d.ts +3 -3
- package/dist/layout/client.js +7 -7
- package/dist/layout/index.js +8 -8
- package/dist/layout/types.d.ts +5 -4
- package/dist/llms/contract.js +1 -1
- package/dist/llms/index.js +6 -6
- package/dist/maps/index.js +3 -3
- package/dist/mcp/index.js +2 -14
- package/dist/mcp/sonor.js +14 -11
- package/dist/revalidate/index.js +2 -2
- package/dist/seo/client.js +4 -4
- package/dist/seo/index.js +15 -8
- package/dist/seo/llms/contract.js +1 -1
- package/dist/seo/llms.js +6 -6
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/sitemap.js +4 -4
- package/dist/server/index.js +2 -2
- package/dist/shared/dialog.d.ts +27 -0
- package/dist/shared/identity.d.ts +1 -1
- package/dist/shared/layers.d.ts +7 -0
- package/dist/shared/mid-form.d.ts +53 -0
- package/dist/shared/reporting-gate.d.ts +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/signal/types.d.ts +1 -1
- package/dist/sitemap/index.js +4 -4
- package/dist/{socket-loader-R24ZSRSQ.js → socket-loader-CGIPEG74.js} +1 -1
- package/dist/sync/index.js +5 -5
- package/dist/types.d.ts +3 -1
- package/dist/{web-vitals.attribution-GD6LGLVF.js → web-vitals.attribution-N2PCCF4Q.js} +1 -1
- package/dist/website/BlocksPopup.d.ts +1 -1
- package/dist/website/PopupBlocks.d.ts +5 -2
- package/dist/website/SitePopups.d.ts +25 -0
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +6 -6
- package/dist/website/popup-rules.d.ts +46 -0
- package/dist/website/popup-types.d.ts +113 -0
- package/dist/website/popups.d.ts +2 -6
- package/dist/website/popups.js +6 -14
- package/dist/{writeLLMsTxt-G3JBNBC5.js → writeLLMsTxt-OV24LQVL.js} +3 -3
- package/docs/MIGRATING-TO-7.md +41 -9
- package/docs.json +2 -1
- package/package.json +2 -2
- package/src/analytics/README.md +2 -2
- package/src/articles/README.md +4 -1
- package/src/{engage → chat}/README.md +63 -62
- package/src/forms/README.md +49 -3
- package/src/layout/README.md +8 -5
- package/src/seo/README.md +3 -1
- package/src/sync/README.md +10 -0
- package/src/website/README.md +133 -0
- package/dist/ChatWidget-UCDWMWCW.js +0 -15
- package/dist/EngageWidget-7ZYSK4GE.js +0 -11
- package/dist/ManagedForm-H7BVAH2W.js +0 -14
- package/dist/SitemapSync-XBANGKHZ.js +0 -8
- package/dist/chunk-NDF4A5JM.js +0 -37
- package/dist/chunk-VLARKWZU.js +0 -100
- package/dist/chunk-YCJT4JJG.js +0 -837
- package/dist/engage/DesignRenderer.d.ts +0 -57
- package/dist/engage/element-rules.d.ts +0 -38
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit shared: is the visitor in the middle of a form?
|
|
3
|
+
*
|
|
4
|
+
* SINGLE SOURCE OF TRUTH for whether something may open over the page right
|
|
5
|
+
* now. SitePopups asks before any popup or toast opens on its own (whatever
|
|
6
|
+
* the trigger: immediate, delay, scroll or exit intent) and waits while the
|
|
7
|
+
* answer is yes.
|
|
8
|
+
* Don't write a second check; extend this one.
|
|
9
|
+
*
|
|
10
|
+
* Why it matters: a modal popup takes focus and hides the rest of the page
|
|
11
|
+
* from assistive technology while it's open. Opening one mid-form throws a
|
|
12
|
+
* person out of the field they're typing in, and an agent browser filling the
|
|
13
|
+
* form for someone (they act on the accessibility tree) loses every field it
|
|
14
|
+
* was about to fill.
|
|
15
|
+
*
|
|
16
|
+
* Mid-form means any of:
|
|
17
|
+
* - focus is on a field (input, textarea, select) that belongs to a form, or
|
|
18
|
+
* inside a frame in a form (a payment provider's card field);
|
|
19
|
+
* - a form has a field the visitor filled: a value that isn't empty and isn't
|
|
20
|
+
* the one the page rendered with, or one they typed into (watchFormInput);
|
|
21
|
+
* - a site-kit form is carrying what the visitor typed into its server-rendered
|
|
22
|
+
* shell before it upgraded (FormEnhancer marks its wrapper
|
|
23
|
+
* `data-sk-carried`; the upgraded fields are new elements nobody typed into
|
|
24
|
+
* yet, and React keeps their default equal to their value);
|
|
25
|
+
* - a site-kit form is sending (`data-sk-state="submitting"`).
|
|
26
|
+
*
|
|
27
|
+
* Fields a visitor doesn't fill don't count: hidden inputs, buttons, fields
|
|
28
|
+
* nobody can see or reach (inert or aria-hidden), and site-kit's trap field.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Remember which fields the visitor types into from here on. React keeps a
|
|
32
|
+
* controlled field's default value equal to its current value, so comparing
|
|
33
|
+
* the two can't see what someone typed into one; the input event can.
|
|
34
|
+
* Idempotent: one pair of capture listeners per document, kept for the page's
|
|
35
|
+
* life. SitePopups starts it when it mounts.
|
|
36
|
+
*/
|
|
37
|
+
export declare function watchFormInput(doc?: Document): void;
|
|
38
|
+
/** Whether the visitor is in the middle of a form (see the module comment for what counts). */
|
|
39
|
+
export declare function isVisitorMidForm(doc?: Document): boolean;
|
|
40
|
+
export interface MidFormWaitOptions {
|
|
41
|
+
doc?: Document;
|
|
42
|
+
/** How long after focus leaves a field to look again. Default 1500ms. */
|
|
43
|
+
settleMs?: number;
|
|
44
|
+
/** How often to look again while waiting. Default 5000ms. */
|
|
45
|
+
pollMs?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Run `open` now if the visitor isn't mid-form, otherwise as soon as they
|
|
49
|
+
* aren't: a moment after focus leaves a field, or on the next poll (a form
|
|
50
|
+
* that sent and cleared, or went away). Never gives up on its own; the
|
|
51
|
+
* returned function cancels the wait. `open` runs at most once.
|
|
52
|
+
*/
|
|
53
|
+
export declare function whenNotMidForm(open: () => void, options?: MidFormWaitOptions): () => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Single source of truth for client reporting eligibility and credentials.
|
|
3
|
-
* Analytics, fleet, SitemapSync and
|
|
3
|
+
* Analytics, fleet, SitemapSync, chat and popups all resolve through this gate.
|
|
4
4
|
* Kept separate from transport wrappers so non-analytics modules stay lean.
|
|
5
5
|
*/
|
|
6
6
|
/** Resolved destination for an analytics send. */
|
package/dist/shared/version.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* bottom: calc(24px + env(safe-area-inset-bottom, 0px) + var(--sk-vv-layout-gap, 0px));
|
|
16
16
|
*
|
|
17
17
|
* The Echo launcher and chat popup already include it (see
|
|
18
|
-
*
|
|
18
|
+
* chat/launcher-placement.ts), so mounting the tracker is all a site needs
|
|
19
19
|
* for those; the property is also there for the site's own fixed UI.
|
|
20
20
|
*
|
|
21
21
|
* Opt-in on purpose. The gap also grows to the keyboard's height while a
|
package/dist/signal/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useSignalExperiment, useSignalEvent } from '../chunk-
|
|
3
|
-
export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from '../chunk-
|
|
2
|
+
import { useSignalExperiment, useSignalEvent } from '../chunk-S54ECQGY.js';
|
|
3
|
+
export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from '../chunk-S54ECQGY.js';
|
|
4
4
|
import '../chunk-PKBMQBKP.js';
|
|
5
5
|
import React, { useEffect } from 'react';
|
|
6
6
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
package/dist/signal/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface SignalConfig {
|
|
|
8
8
|
version: string;
|
|
9
9
|
/** Whether Signal is enabled for this project */
|
|
10
10
|
enabled: boolean;
|
|
11
|
-
/** Engage
|
|
11
|
+
/** Popup overrides (the key keeps the retired Engage module's name) */
|
|
12
12
|
engage?: {
|
|
13
13
|
popups?: Record<string, EngageOverride>;
|
|
14
14
|
nudges?: Record<string, EngageOverride>;
|
package/dist/sitemap/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-
|
|
1
|
+
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-R46IQIGK.js';
|
|
2
2
|
import '../chunk-Z22QVHT4.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-QL6XNPSD.js';
|
|
4
|
+
import '../chunk-6U3VLV2C.js';
|
|
5
5
|
import '../chunk-L5UOHS6E.js';
|
|
6
6
|
import '../chunk-WMVK77ND.js';
|
|
7
7
|
import '../chunk-VX5CMNMM.js';
|
|
8
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-NZ4RXN3G.js';
|
|
9
9
|
import '../chunk-MJP63SSS.js';
|
|
10
10
|
import '../chunk-ZEGVKVD5.js';
|
|
11
11
|
import '../chunk-YVKRYQRG.js';
|
package/dist/sync/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { BookingWidget } from '../chunk-
|
|
2
|
-
export { createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, prepareMeeting, releaseSlotHold } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
1
|
+
export { BookingWidget } from '../chunk-GGORNBSC.js';
|
|
2
|
+
export { createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, prepareMeeting, releaseSlotHold } from '../chunk-BKY2ZNM7.js';
|
|
3
|
+
import '../chunk-D6ZC7XKZ.js';
|
|
4
|
+
import '../chunk-K4ZHAURD.js';
|
|
5
|
+
import '../chunk-F24FNCTK.js';
|
|
6
6
|
import '../chunk-PKBMQBKP.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface ProjectScoped {
|
|
|
14
14
|
}
|
|
15
15
|
export * from './seo/types';
|
|
16
16
|
export * from './analytics/types';
|
|
17
|
-
export * from './
|
|
17
|
+
export * from './chat/types';
|
|
18
|
+
export * from './website/popup-types';
|
|
19
|
+
export type { EngageAnalytics, EngageConfig, EngageElement, TargetingRules, TriggerConfig, WidgetConfig, WidgetType } from './engage/types';
|
|
18
20
|
export * from './forms/types';
|
|
19
21
|
export * from './articles/types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __publicField } from './chunk-PKBMQBKP.js';
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// node_modules/.pnpm/web-vitals@6.1.0/node_modules/web-vitals/dist/web-vitals.attribution.js
|
|
4
4
|
var t = class {
|
|
5
5
|
constructor() {
|
|
6
6
|
__publicField(this, "t");
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The site side of a blocks popup: re-checks the blocks, measures the site's
|
|
5
5
|
* design once when the popup opens, and hands both to PopupBlocks.
|
|
6
|
-
*
|
|
6
|
+
* SitePopups loads this with a dynamic import, so the renderer, the
|
|
7
7
|
* contract and the design measurement download only when a blocks popup is
|
|
8
8
|
* actually about to show (most page loads have none).
|
|
9
9
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Draws a popup from its blocks (heading, formatted text, image, button,
|
|
5
5
|
* divider) in the site's own design. SINGLE renderer for both places a popup
|
|
6
|
-
* appears: on the site (
|
|
6
|
+
* appears: on the site (SitePopups, fed the measured tokens) and in Sonor's
|
|
7
7
|
* builder preview (fed the tokens the site reported). React only, no Next
|
|
8
8
|
* imports, so the dashboard can import it as-is.
|
|
9
9
|
*
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
* Accessibility: a centred popup is a modal dialog (labelled by its heading,
|
|
19
19
|
* focus moves in and is kept there, Escape and the overlay close it, focus
|
|
20
20
|
* goes back where it was). A bar is a labelled region, a slide-in a
|
|
21
|
-
* non-modal dialog; both close on Escape.
|
|
21
|
+
* non-modal dialog; both close on Escape. The focus and Escape behavior is
|
|
22
|
+
* usePopupDialog (../shared/dialog), so the builder's copy needs that file
|
|
23
|
+
* beside it. Text HTML is re-sanitized on
|
|
24
|
+
* render.
|
|
22
25
|
*/
|
|
23
26
|
import React from 'react';
|
|
24
27
|
import { type PopupBlock, type SiteDesignTokens } from './contract';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/website/popups - SitePopups: the popups, banners and
|
|
3
|
+
* toasts published for this site (Sonor → Website → Popups & Banners).
|
|
4
|
+
*
|
|
5
|
+
* Each shows where and when Sonor says (pages, devices, trigger, frequency,
|
|
6
|
+
* schedule), drawn from its blocks in the site's own design by PopupBlocks.
|
|
7
|
+
* SiteKitLayout mounts it for you (its `popups` prop); mount it yourself only
|
|
8
|
+
* on a site without SiteKitLayout. A project with nothing published costs one
|
|
9
|
+
* request and draws nothing. The renderer downloads when a popup first opens.
|
|
10
|
+
*/
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import { type AnalyticsGateOptions } from '../shared/reporting-gate';
|
|
13
|
+
export interface SitePopupsProps extends AnalyticsGateOptions {
|
|
14
|
+
apiUrl?: string;
|
|
15
|
+
apiKey?: string;
|
|
16
|
+
/** The layer popups, banners and toasts stack on. Default: 9999. */
|
|
17
|
+
zIndex?: number;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Same gate as analytics (frames, localhost, a key to send with): a popup in
|
|
22
|
+
* a case study's device frame is shown to the agency's visitor, not this
|
|
23
|
+
* site's, and its impressions would count against this site.
|
|
24
|
+
*/
|
|
25
|
+
export declare function SitePopups(props: SitePopupsProps): React.JSX.Element | null;
|
package/dist/website/images.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-
|
|
1
|
+
export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-JMLK6MH7.js';
|
|
2
2
|
export { ManagedFavicon, getManagedFaviconUrl } from '../chunk-GW7GSBO7.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-D6ZC7XKZ.js';
|
|
4
|
+
import '../chunk-K4ZHAURD.js';
|
|
5
|
+
import '../chunk-F24FNCTK.js';
|
|
6
6
|
import '../chunk-PKBMQBKP.js';
|
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-
|
|
4
|
-
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-
|
|
2
|
+
export { SiteDesignReporter } from '../chunk-5YCEMV2L.js';
|
|
3
|
+
export { SITE_DESIGN_PATH, cleanFontStack, colorToHex, getSiteDesignTokens, measureSiteDesign, readDeclaredDesign, sendSiteDesign } from '../chunk-JJ3DELUL.js';
|
|
4
|
+
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-BF7TZYC3.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-D6ZC7XKZ.js';
|
|
11
|
+
import '../chunk-K4ZHAURD.js';
|
|
12
|
+
import '../chunk-F24FNCTK.js';
|
|
13
13
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/website/popups - the rules SitePopups applies to the
|
|
3
|
+
* popups, banners and toasts published for a site, as pure functions (the
|
|
4
|
+
* package's tests have no DOM).
|
|
5
|
+
*/
|
|
6
|
+
import type { SitePopup } from './popup-types';
|
|
7
|
+
import type { PopupPlacement } from './PopupBlocks';
|
|
8
|
+
/** Exact path, or a prefix ending in `*`. The grammar Sonor stores page patterns in. */
|
|
9
|
+
export declare function matchPath(pathname: string, pattern: string): boolean;
|
|
10
|
+
export type DeviceType = 'desktop' | 'mobile' | 'tablet';
|
|
11
|
+
export declare function deviceFromUserAgent(ua: string): DeviceType;
|
|
12
|
+
/**
|
|
13
|
+
* The storage key that remembers a visitor saw (closed or clicked) a popup.
|
|
14
|
+
* The `_engage_` prefix predates the Website module; renaming it would show
|
|
15
|
+
* every "once" popup to visitors who already closed it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function seenKey(popupId: string): string;
|
|
18
|
+
interface SeenStore {
|
|
19
|
+
local: Pick<Storage, 'getItem'> | null;
|
|
20
|
+
session: Pick<Storage, 'getItem'> | null;
|
|
21
|
+
}
|
|
22
|
+
/** Whether a popup's targeting and frequency cap allow it on this page, for this visitor. */
|
|
23
|
+
export declare function isEligible(popup: SitePopup, pathname: string, device: DeviceType, store: SeenStore, now?: number): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* What a popup draws as: centred over a dimmed page, a bar along an edge, or
|
|
26
|
+
* a slide-in (a toast) in a corner. Its `layout` says what it actually is;
|
|
27
|
+
* `type` describes it for older kits. Undefined for a popup without blocks:
|
|
28
|
+
* that's Sonor's Engage Studio `design_json`, which this kit doesn't draw.
|
|
29
|
+
* Single source of truth for which popups SitePopups draws, the
|
|
30
|
+
* one-popup-at-a-time rule and the form wait.
|
|
31
|
+
*/
|
|
32
|
+
export declare function popupPlacement(popup: SitePopup): PopupPlacement | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Whether a popup waits until the visitor isn't mid-form before it opens on
|
|
35
|
+
* its own (shared/mid-form). Popups and toasts do. Banners don't: they
|
|
36
|
+
* neither take focus nor hide the page.
|
|
37
|
+
*/
|
|
38
|
+
export declare function waitsForForms(popup: SitePopup): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* The active list after `id` asks to show. A popup (the kind centred over a
|
|
41
|
+
* dimmed page) waits while another is open, so two never stack; banners and
|
|
42
|
+
* toasts show alongside. Popups arrive from Sonor highest priority first, so
|
|
43
|
+
* the first popup to trigger is the one that wins a tie.
|
|
44
|
+
*/
|
|
45
|
+
export declare function activatePopup(active: string[], id: string, popups: SitePopup[]): string[];
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/website/popups: what a published popup looks like.
|
|
3
|
+
*
|
|
4
|
+
* Sonor → Website → Popups & Banners. The API serves them from
|
|
5
|
+
* `GET /engage/widget/elements` (its route keeps the retired module's name).
|
|
6
|
+
*/
|
|
7
|
+
import type { PopupBlock } from './contract';
|
|
8
|
+
/** What Sonor says a popup is. A blocks popup's `layout` says where it actually sits. */
|
|
9
|
+
export type SitePopupType = 'popup' | 'nudge' | 'bar' | 'chat' | 'slide-in';
|
|
10
|
+
/** A popup, banner or toast published for this site (Sonor → Website → Popups & Banners). */
|
|
11
|
+
export interface SitePopup {
|
|
12
|
+
id: string;
|
|
13
|
+
project_id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
type: SitePopupType;
|
|
16
|
+
config: SitePopupConfig;
|
|
17
|
+
targeting: SitePopupTargeting;
|
|
18
|
+
trigger: SitePopupTrigger;
|
|
19
|
+
is_active: boolean;
|
|
20
|
+
priority: number;
|
|
21
|
+
created_at: string;
|
|
22
|
+
updated_at: string;
|
|
23
|
+
/**
|
|
24
|
+
* The popup as blocks, drawn in the site's own design by PopupBlocks. A
|
|
25
|
+
* popup without blocks isn't drawn: Sonor's older `design_json` (Engage
|
|
26
|
+
* Studio) is for site-kits before 7.2.0, and is ignored here.
|
|
27
|
+
*/
|
|
28
|
+
blocks?: PopupBlock[];
|
|
29
|
+
/**
|
|
30
|
+
* Where a blocks popup sits. `type`/`config` describe it for older kits
|
|
31
|
+
* (which can't pin a bar to the bottom); this says what it actually is.
|
|
32
|
+
*/
|
|
33
|
+
layout?: {
|
|
34
|
+
placement: 'popup' | 'bar' | 'slide-in';
|
|
35
|
+
edge?: 'top' | 'bottom';
|
|
36
|
+
corner?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
37
|
+
/** The popup's own accent, over the site's. */
|
|
38
|
+
accent?: string;
|
|
39
|
+
};
|
|
40
|
+
status?: 'draft' | 'published' | 'archived' | 'paused';
|
|
41
|
+
}
|
|
42
|
+
export interface SitePopupConfig {
|
|
43
|
+
/** Visual style */
|
|
44
|
+
theme?: 'light' | 'dark' | 'custom';
|
|
45
|
+
position?: 'center' | 'top' | 'bottom' | 'left' | 'right' | 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
46
|
+
/** Content */
|
|
47
|
+
title?: string;
|
|
48
|
+
message?: string;
|
|
49
|
+
imageUrl?: string;
|
|
50
|
+
/** CTA */
|
|
51
|
+
ctaText?: string;
|
|
52
|
+
ctaUrl?: string;
|
|
53
|
+
ctaAction?: 'link' | 'close' | 'form' | 'chat';
|
|
54
|
+
/** Form (if ctaAction is 'form') */
|
|
55
|
+
formId?: string;
|
|
56
|
+
/** Styling */
|
|
57
|
+
backgroundColor?: string;
|
|
58
|
+
textColor?: string;
|
|
59
|
+
ctaBackgroundColor?: string;
|
|
60
|
+
ctaTextColor?: string;
|
|
61
|
+
borderRadius?: number;
|
|
62
|
+
/** Behavior */
|
|
63
|
+
closable?: boolean;
|
|
64
|
+
showOverlay?: boolean;
|
|
65
|
+
overlayOpacity?: number;
|
|
66
|
+
}
|
|
67
|
+
export interface SitePopupTargeting {
|
|
68
|
+
/** Page targeting */
|
|
69
|
+
pages?: {
|
|
70
|
+
include?: string[];
|
|
71
|
+
exclude?: string[];
|
|
72
|
+
};
|
|
73
|
+
/** Device targeting */
|
|
74
|
+
devices?: ('desktop' | 'mobile' | 'tablet')[];
|
|
75
|
+
/** Visitor targeting */
|
|
76
|
+
visitor?: {
|
|
77
|
+
type?: 'new' | 'returning' | 'all';
|
|
78
|
+
minSessions?: number;
|
|
79
|
+
maxSessions?: number;
|
|
80
|
+
};
|
|
81
|
+
/** Source targeting */
|
|
82
|
+
source?: {
|
|
83
|
+
utm_source?: string[];
|
|
84
|
+
utm_medium?: string[];
|
|
85
|
+
utm_campaign?: string[];
|
|
86
|
+
referrer?: string[];
|
|
87
|
+
};
|
|
88
|
+
/** Time targeting */
|
|
89
|
+
schedule?: {
|
|
90
|
+
startDate?: string;
|
|
91
|
+
endDate?: string;
|
|
92
|
+
daysOfWeek?: number[];
|
|
93
|
+
startTime?: string;
|
|
94
|
+
endTime?: string;
|
|
95
|
+
timezone?: string;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export interface SitePopupTrigger {
|
|
99
|
+
type: 'immediate' | 'delay' | 'scroll' | 'exit-intent' | 'click' | 'custom';
|
|
100
|
+
/** Delay in seconds (for 'delay' type) */
|
|
101
|
+
delay?: number;
|
|
102
|
+
/** Scroll percentage (for 'scroll' type) */
|
|
103
|
+
scrollPercentage?: number;
|
|
104
|
+
/** CSS selector (for 'click' type) */
|
|
105
|
+
clickSelector?: string;
|
|
106
|
+
/** Custom event name (for 'custom' type) */
|
|
107
|
+
customEvent?: string;
|
|
108
|
+
/** Frequency capping */
|
|
109
|
+
frequency?: {
|
|
110
|
+
type: 'always' | 'once' | 'once-per-session' | 'every-n-days';
|
|
111
|
+
days?: number;
|
|
112
|
+
};
|
|
113
|
+
}
|
package/dist/website/popups.d.ts
CHANGED
|
@@ -7,11 +7,7 @@
|
|
|
7
7
|
* import it to place it yourself. `PopupBlocks` is the renderer, for drawing
|
|
8
8
|
* one popup from its blocks.
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
import { EngageWidget } from '../engage/EngageWidget';
|
|
12
|
-
export type SitePopupsProps = Omit<React.ComponentProps<typeof EngageWidget>, 'chatEnabled'>;
|
|
13
|
-
/** The site's published popups, banners and toasts. No chat launcher (that's `./chat`). */
|
|
14
|
-
export declare function SitePopups(props: SitePopupsProps): React.JSX.Element;
|
|
10
|
+
export { SitePopups, type SitePopupsProps } from './SitePopups';
|
|
15
11
|
export { PopupBlocks, DEFAULT_POPUP_TOKENS, type PopupBlocksProps, type PopupPlacement } from './PopupBlocks';
|
|
16
|
-
export type {
|
|
12
|
+
export type { SitePopup, SitePopupConfig, SitePopupTargeting, SitePopupTrigger, SitePopupType, } from './popup-types';
|
|
17
13
|
export type { PopupBlock, SiteDesignTokens } from './contract';
|
package/dist/website/popups.js
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-
|
|
2
|
+
export { DEFAULT_POPUP_TOKENS, PopupBlocks } from '../chunk-BF7TZYC3.js';
|
|
3
3
|
import '../chunk-IHG36STL.js';
|
|
4
|
-
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-6T6CQVNL.js';
|
|
4
|
+
export { SitePopups } from '../chunk-EJVQJCG5.js';
|
|
5
|
+
import '../chunk-27FISYK4.js';
|
|
7
6
|
import '../chunk-S22FSH7C.js';
|
|
8
7
|
import '../chunk-24QZEO3Q.js';
|
|
9
8
|
import '../chunk-GJWI74ZZ.js';
|
|
10
9
|
import '../chunk-43OCZ3JA.js';
|
|
11
10
|
import '../chunk-EKBEOXTH.js';
|
|
12
|
-
import '../chunk-
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
11
|
+
import '../chunk-D6ZC7XKZ.js';
|
|
12
|
+
import '../chunk-K4ZHAURD.js';
|
|
13
|
+
import '../chunk-F24FNCTK.js';
|
|
15
14
|
import '../chunk-PKBMQBKP.js';
|
|
16
|
-
import { jsx } from 'react/jsx-runtime';
|
|
17
|
-
|
|
18
|
-
function SitePopups(props) {
|
|
19
|
-
return /* @__PURE__ */ jsx(EngageWidget, { ...props, chatEnabled: false });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export { SitePopups };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { writeLLMsTxtToPublic } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { writeLLMsTxtToPublic } from './chunk-QL6XNPSD.js';
|
|
2
|
+
import './chunk-6U3VLV2C.js';
|
|
3
3
|
import './chunk-L5UOHS6E.js';
|
|
4
4
|
import './chunk-WMVK77ND.js';
|
|
5
5
|
import './chunk-VX5CMNMM.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-NZ4RXN3G.js';
|
|
7
7
|
import './chunk-MJP63SSS.js';
|
|
8
8
|
import './chunk-YVKRYQRG.js';
|
|
9
9
|
import './chunk-FESKKJAS.js';
|
package/docs/MIGRATING-TO-7.md
CHANGED
|
@@ -20,6 +20,13 @@ 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
|
+
It leaves nothing in the project but the change. Since sonor-setup 7.1.2 the
|
|
24
|
+
originals of the files it writes go to a folder in your OS temp directory
|
|
25
|
+
(it prints where, and git has them too), not `.bak` files beside them, and
|
|
26
|
+
it never creates or edits `.env.example`: `.env.local` is the one env file.
|
|
27
|
+
An old fallback such as `process.env.SONOR_API_KEY || process.env.UPTRADE_API_KEY`
|
|
28
|
+
becomes `process.env.SONOR_API_KEY`.
|
|
29
|
+
|
|
23
30
|
Requirements: Next 16 and Node 20.19+ or 22.12+
|
|
24
31
|
(Netlify's default is 22).
|
|
25
32
|
|
|
@@ -68,12 +75,17 @@ New homes, each the same module as before:
|
|
|
68
75
|
|
|
69
76
|
- Website: `./website/{popups,images,slots,cms,landing,cta-bar}`
|
|
70
77
|
- SEO: `./seo/{sitemap,robots,indexnow,redirects,og,og/route,llms,llms/client,llms/contract,meta/contract,pages/contract}`
|
|
71
|
-
- Website chat: `./chat` (out of
|
|
78
|
+
- Website chat: `./chat`, and popups: `./website/popups` (both out of
|
|
79
|
+
`./engage`, which Sonor retired with the Engage module)
|
|
72
80
|
|
|
73
81
|
**The old paths keep working through 7.x** and are removed in 8.0. The
|
|
74
|
-
codemod moves them anyway, so a touched site is done in one pass
|
|
75
|
-
|
|
76
|
-
(`
|
|
82
|
+
codemod moves them anyway, so a touched site is done in one pass: chat
|
|
83
|
+
imports go to `./chat`, popup types to `./website/popups` under their new
|
|
84
|
+
names (`EngageElement` is `SitePopup`). It flags `EngageWidget`, which draws
|
|
85
|
+
both and which `SiteKitLayout` already mounts. `SiteKitLayout` gains `chat`
|
|
86
|
+
and `popups` props; `engage` is an alias (`engage={false}` still turns both
|
|
87
|
+
off). Since 7.2.0, popups render only from blocks: one made in Engage Studio
|
|
88
|
+
isn't drawn, so make it again in Sonor (Website → Popups & Banners).
|
|
77
89
|
|
|
78
90
|
### 4. ESM only, Next 16 only
|
|
79
91
|
|
|
@@ -85,10 +97,22 @@ site-side script that `require()`s site-kit on an older Node would break.
|
|
|
85
97
|
The `next` peer is `^16`. Next 16 renamed `middleware.ts` to `proxy.ts`, and
|
|
86
98
|
**the codemod moves it**: the file, a named `middleware` export (to `proxy`),
|
|
87
99
|
and `createMiddleware` from `@sonordev/site-kit/middleware` (to `createProxy`
|
|
88
|
-
from `/proxy`). The old names work through 7.x.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
100
|
+
from `/proxy`). The old names work through 7.x.
|
|
101
|
+
|
|
102
|
+
**The proxy goes beside the app directory.** Next reads it from the project
|
|
103
|
+
root, or from `src/` when the app is `src/app`, and silently ignores one
|
|
104
|
+
anywhere else: the build passes, but the site sends no security headers and
|
|
105
|
+
runs no managed redirects. So on a `src/app` site the codemod writes
|
|
106
|
+
`src/proxy.ts`, with the file's relative imports re-pointed. Before
|
|
107
|
+
sonor-setup 7.1.2 it renamed the file in place, which left a root `proxy.ts`
|
|
108
|
+
on those sites; rerunning the codemod moves it, and `npx sonor-setup doctor`
|
|
109
|
+
warns about any proxy Next doesn't read.
|
|
110
|
+
|
|
111
|
+
It won't move a file that sets `runtime` (a proxy file can't; the build
|
|
112
|
+
throws), and says so: remove the export, check the logic still runs on your
|
|
113
|
+
host, rerun. It never moves onto a proxy Next already runs: with one in each
|
|
114
|
+
place, it reports both and changes neither. `npx sonor-setup next16` runs
|
|
115
|
+
just this part.
|
|
92
116
|
|
|
93
117
|
### 5. Removed (nothing used them)
|
|
94
118
|
|
|
@@ -119,7 +143,7 @@ Still accepted and ignored until 8.0, because sites pass them:
|
|
|
119
143
|
`.env.local`, `.env.production`, `.env`. It used to let `.env.local` beat
|
|
120
144
|
the host.
|
|
121
145
|
|
|
122
|
-
## Optional, and new in 7.
|
|
146
|
+
## Optional, and new in 7.x
|
|
123
147
|
|
|
124
148
|
- **Cache Components.** `cacheComponents: true` in next.config works with
|
|
125
149
|
site-kit now (it failed every page through 6.x). Remove route segment
|
|
@@ -134,6 +158,14 @@ Still accepted and ignored until 8.0, because sites pass them:
|
|
|
134
158
|
`onToolCall: reportToolCallsToSonor()` to its `createMcpHandler`.
|
|
135
159
|
- **`@sonordev/contracts`** is for the APIs and the dashboard; sites keep
|
|
136
160
|
importing `@sonordev/site-kit/*/contract`, which is the same code.
|
|
161
|
+
- **Live updates (7.1).** `npx sonor-setup scaffold` writes the route Sonor
|
|
162
|
+
calls when content changes, `app/api/seo-revalidate/route.ts`, and
|
|
163
|
+
`npx sonor-setup doctor` checks for it. A site with articles gets
|
|
164
|
+
`createRevalidateRoute({ publicationBasePath: '/insights' })` with its own
|
|
165
|
+
path, read from the app directory (a dynamic page that renders site-kit
|
|
166
|
+
articles, or a `[slug]` route under a folder like `/blog` or `/news`).
|
|
167
|
+
When more than one folder looks like the publication, it writes the
|
|
168
|
+
one-line route and lists them.
|
|
137
169
|
|
|
138
170
|
## Kits built on site-kit
|
|
139
171
|
|
package/docs.json
CHANGED
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"title": "Engagement",
|
|
39
39
|
"pages": [
|
|
40
40
|
{ "slug": "forms", "title": "Forms", "file": "src/forms/README.md" },
|
|
41
|
-
{ "slug": "chat", "title": "Website chat", "file": "src/
|
|
41
|
+
{ "slug": "chat", "title": "Website chat", "file": "src/chat/README.md" },
|
|
42
|
+
{ "slug": "popups", "title": "Popups and banners", "file": "src/website/README.md" },
|
|
42
43
|
{ "slug": "cta-bar", "title": "CTA bar", "file": "src/cta-bar/README.md" },
|
|
43
44
|
{ "slug": "signal", "title": "Signal (A/B)", "file": "src/signal/README.md" }
|
|
44
45
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sonordev/site-kit",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"packageManager": "pnpm@11.5.3",
|
|
6
6
|
"description": "Complete client-side integration kit for Sonor - SEO, Analytics, Engage, Forms, Blog",
|
|
@@ -461,7 +461,7 @@
|
|
|
461
461
|
"gsap": "^3.15.0",
|
|
462
462
|
"happy-dom": "^20.14.5",
|
|
463
463
|
"inquirer": "^14.0.2",
|
|
464
|
-
"next": "16.3.
|
|
464
|
+
"next": "16.3.8",
|
|
465
465
|
"open": "11.0.0",
|
|
466
466
|
"ora": "^9.4.1",
|
|
467
467
|
"playwright": "^1.62.1",
|
package/src/analytics/README.md
CHANGED
|
@@ -212,7 +212,7 @@ with `analytics.site` or `NEXT_PUBLIC_SITE_URL` set to a production domain.
|
|
|
212
212
|
`localhost`, its subdomains, `127.0.0.1`, `[::1]`, and `0.0.0.0` report nothing
|
|
213
213
|
by default: page views, events, conversions, sessions, vitals, scroll and
|
|
214
214
|
heatmap data, fleet heartbeats, and client-side sitemap registrations all use
|
|
215
|
-
`resolveAnalyticsTarget`.
|
|
215
|
+
`resolveAnalyticsTarget`. Website chat and popups don't mount at all.
|
|
216
216
|
Public hosts and same-origin frames on public hosts still report normally.
|
|
217
217
|
|
|
218
218
|
For intentional local reporting:
|
|
@@ -222,7 +222,7 @@ For intentional local reporting:
|
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
The layout passes this option to AnalyticsProvider, WebVitals, FleetHeartbeat,
|
|
225
|
-
SitemapSync and
|
|
225
|
+
SitemapSync, SiteChat and SitePopups. Standalone components and `sendFleetHeartbeat`
|
|
226
226
|
accept it too; standalone `trackEvent`/`trackConversion` use their mounted
|
|
227
227
|
AnalyticsProvider's options. A local cross-origin frame needs **both** opt-ins.
|
|
228
228
|
Neither option bypasses authentication. No environment variable or global
|
package/src/articles/README.md
CHANGED
|
@@ -47,7 +47,10 @@ const href = createPublicationRoutes(routing).post({ slug: 'build-first', catego
|
|
|
47
47
|
provide `postPath: post => '/articles/' + encodeURIComponent(post.slug)`.
|
|
48
48
|
Callbacks return local paths; generated metadata, feeds, and sitemaps separately
|
|
49
49
|
honor a valid `canonical_url`. The same routes apply to Atom and generated
|
|
50
|
-
breadcrumb/cluster schemas. Supplied `schema`/`schema_json` objects stay intact
|
|
50
|
+
breadcrumb/cluster schemas. Supplied `schema`/`schema_json` objects stay intact, apart
|
|
51
|
+
from template placeholders (an `Organization` named "Example", `example.com` URLs,
|
|
52
|
+
`{post.title}`), which `generateAllArticleSchemas` drops. When nothing real is left,
|
|
53
|
+
it generates the article's schema from its own fields instead.
|
|
51
54
|
|
|
52
55
|
For custom layouts, `resolveArticleArtwork(post, 'article')` prefers
|
|
53
56
|
`editorial_image`, preserving an empty decorative `editorial_image_alt`.
|