@liiift-studio/sanity-visitor-insights 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +360 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +361 -36
- package/dist/index.mjs.map +1 -1
- package/dist/{ranges-YGStz1nR.d.mts → ranges-CiTnQEnz.d.mts} +158 -1
- package/dist/{ranges-YGStz1nR.d.ts → ranges-CiTnQEnz.d.ts} +158 -1
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +362 -83
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +359 -82
- package/dist/server.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{vercel-C597eCC_.d.mts → vercel-CwILuQVm.d.mts} +14 -1
- package/dist/{vercel-C597eCC_.d.ts → vercel-CwILuQVm.d.ts} +14 -1
- package/package.json +1 -1
- package/src/core/core.test.ts +72 -0
- package/src/core/ranges.ts +59 -0
- package/src/core/siteConfig.ts +79 -0
- package/src/reportData.ts +57 -0
- package/src/server/createHandler.ts +31 -6
- package/src/server/diagnostics.ts +22 -5
- package/src/server/ga4.ts +71 -8
- package/src/server/orders.ts +233 -47
- package/src/server/reports/acquisition.ts +54 -10
- package/src/server/reports/journey.ts +94 -10
- package/src/server/reports/measurementHealth.ts +55 -26
- package/src/server/reports/reports.test.ts +263 -9
- package/src/server/reports/typefaceInterest.ts +58 -12
- package/src/studio/Figure.tsx +316 -13
- package/src/studio/VisitorInsightsTool.tsx +15 -2
- package/src/studio/panels.test.tsx +109 -10
- package/src/studio/panels.tsx +171 -8
- package/src/types.ts +10 -0
package/README.md
CHANGED
|
@@ -192,6 +192,56 @@ empty charts — pasting a measurement id here is caught by name.
|
|
|
192
192
|
The service account needs **Viewer** on each GA4 property. Nothing here is `NEXT_PUBLIC_`; none of
|
|
193
193
|
it reaches the browser.
|
|
194
194
|
|
|
195
|
+
#### Scoping to your own hostnames
|
|
196
|
+
|
|
197
|
+
`ga4.hostnames` restricts every GA4 report to the hosts you name. A GA4 property is not necessarily
|
|
198
|
+
one website — Darden's also receives `impactsport.ca`, an unrelated business, which was inside the
|
|
199
|
+
headline session count, both percentages computed from it, and the funnel's entry rung. Omit the
|
|
200
|
+
field to accept every hostname, which is the old behaviour.
|
|
201
|
+
|
|
202
|
+
```js
|
|
203
|
+
ga4: {
|
|
204
|
+
propertyId: '123456789',
|
|
205
|
+
timezone: 'America/Los_Angeles',
|
|
206
|
+
hostnames: ['www.dardenstudio.com', 'dardenstudio.com'],
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Orders: status and revenue
|
|
211
|
+
|
|
212
|
+
`orders.countedStatuses` names the statuses that count as a real sale; everything else is excluded
|
|
213
|
+
and reported separately. Leave it unset and test, failed, pending and refunded orders all count as
|
|
214
|
+
sales — at seven orders a quarter, one test order is a 14% error. The status breakdown is always
|
|
215
|
+
reported so you can see what vocabulary your own orders use before configuring this.
|
|
216
|
+
|
|
217
|
+
`orders.totalField` turns on revenue. Without it a $30 web licence and a $400 multi-seat desktop
|
|
218
|
+
licence are the same integer, so nothing can be ranked by what it is worth. An order total is not a
|
|
219
|
+
customer field; the PII projection allow-list is unchanged.
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
orders: {
|
|
223
|
+
documentType: 'order',
|
|
224
|
+
typefacesField: 'typefaces',
|
|
225
|
+
statusField: 'orderStatus',
|
|
226
|
+
countedStatuses: ['complete', 'paid'],
|
|
227
|
+
totalField: 'total',
|
|
228
|
+
currency: 'USD',
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### Conversions that are not a sale
|
|
233
|
+
|
|
234
|
+
`eventNames.enquiry`, `.subscribe` and `.assetDownload` surface outcomes the funnel used to score as
|
|
235
|
+
drop-offs. A custom commission is worth many multiples of a licence, and the funnel ended at
|
|
236
|
+
`purchase` — so the visitor who read three typeface pages and emailed was counted as a leak.
|
|
237
|
+
|
|
238
|
+
```js
|
|
239
|
+
eventNames: {
|
|
240
|
+
enquiry: ['enquiry_submit'],
|
|
241
|
+
subscribe: ['subscribe'],
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
195
245
|
#### The master switch
|
|
196
246
|
|
|
197
247
|
`VISITOR_INSIGHTS_ENABLED` is an explicit opt-in. Unset, the route answers `503` with
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as Coverage, d as DateRange, E as EventCutover, P as PREEXISTING, e as REPORT_NAMES, f as ReportError, S as SiteAnalyticsConfig, g as SourceName, h as SourceStatus, U as UnavailableReason, i as coverageForRange, j as isReportName, o as ok, p as partial, k as previousRange, r as resolveRange, u as unavailable, v as validateSiteConfig, l as valueOrNull } from './ranges-
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-CiTnQEnz.mjs';
|
|
4
|
+
export { C as Coverage, d as DateRange, E as EventCutover, P as PREEXISTING, e as REPORT_NAMES, f as ReportError, S as SiteAnalyticsConfig, g as SourceName, h as SourceStatus, U as UnavailableReason, i as coverageForRange, j as isReportName, o as ok, p as partial, k as previousRange, r as resolveRange, u as unavailable, v as validateSiteConfig, l as valueOrNull } from './ranges-CiTnQEnz.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The Visitor Insights Studio tool.
|
|
@@ -93,7 +93,6 @@ declare function useReport<T>({ apiBaseUrl, report, range, custom }: UseReportOp
|
|
|
93
93
|
declare function formatCount(value: number): string;
|
|
94
94
|
/** Format a 0–1 ratio as a percentage. */
|
|
95
95
|
declare function formatPercent(ratio: number, digits?: number): string;
|
|
96
|
-
/** Props for MetricFigure. */
|
|
97
96
|
interface MetricFigureProps {
|
|
98
97
|
metric: MetricValue;
|
|
99
98
|
/** Accessible label describing what this number counts. */
|
|
@@ -168,8 +167,9 @@ declare function MeasurementHealthPanel({ data }: {
|
|
|
168
167
|
data: MeasurementHealthData;
|
|
169
168
|
}): React.ReactElement;
|
|
170
169
|
/** Acquisition — where visitors came from, with design-industry referrers called out. */
|
|
171
|
-
declare function AcquisitionPanel({ data }: {
|
|
170
|
+
declare function AcquisitionPanel({ data, previous }: {
|
|
172
171
|
data: AcquisitionData;
|
|
172
|
+
previous?: AcquisitionData;
|
|
173
173
|
}): React.ReactElement;
|
|
174
174
|
/** Journey — a funnel, drawn as a tracked sequence or as independent totals, whichever the report used. */
|
|
175
175
|
declare function JourneyPanel({ data }: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as Coverage, d as DateRange, E as EventCutover, P as PREEXISTING, e as REPORT_NAMES, f as ReportError, S as SiteAnalyticsConfig, g as SourceName, h as SourceStatus, U as UnavailableReason, i as coverageForRange, j as isReportName, o as ok, p as partial, k as previousRange, r as resolveRange, u as unavailable, v as validateSiteConfig, l as valueOrNull } from './ranges-
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-CiTnQEnz.js';
|
|
4
|
+
export { C as Coverage, d as DateRange, E as EventCutover, P as PREEXISTING, e as REPORT_NAMES, f as ReportError, S as SiteAnalyticsConfig, g as SourceName, h as SourceStatus, U as UnavailableReason, i as coverageForRange, j as isReportName, o as ok, p as partial, k as previousRange, r as resolveRange, u as unavailable, v as validateSiteConfig, l as valueOrNull } from './ranges-CiTnQEnz.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The Visitor Insights Studio tool.
|
|
@@ -93,7 +93,6 @@ declare function useReport<T>({ apiBaseUrl, report, range, custom }: UseReportOp
|
|
|
93
93
|
declare function formatCount(value: number): string;
|
|
94
94
|
/** Format a 0–1 ratio as a percentage. */
|
|
95
95
|
declare function formatPercent(ratio: number, digits?: number): string;
|
|
96
|
-
/** Props for MetricFigure. */
|
|
97
96
|
interface MetricFigureProps {
|
|
98
97
|
metric: MetricValue;
|
|
99
98
|
/** Accessible label describing what this number counts. */
|
|
@@ -168,8 +167,9 @@ declare function MeasurementHealthPanel({ data }: {
|
|
|
168
167
|
data: MeasurementHealthData;
|
|
169
168
|
}): React.ReactElement;
|
|
170
169
|
/** Acquisition — where visitors came from, with design-industry referrers called out. */
|
|
171
|
-
declare function AcquisitionPanel({ data }: {
|
|
170
|
+
declare function AcquisitionPanel({ data, previous }: {
|
|
172
171
|
data: AcquisitionData;
|
|
172
|
+
previous?: AcquisitionData;
|
|
173
173
|
}): React.ReactElement;
|
|
174
174
|
/** Journey — a funnel, drawn as a tracked sequence or as independent totals, whichever the report used. */
|
|
175
175
|
declare function JourneyPanel({ data }: {
|