@preprio/toolkit 0.6.0-alpha.2 → 0.6.0-alpha.3
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 +46 -30
- package/dist/astro/{chunk-U7VUQL57.js → chunk-CUDYSNJD.js} +1 -1
- package/dist/astro/graphql.js +1 -1
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/{chunk-DS3QA3HF.js → chunk-3YZANSVY.js} +1 -1
- package/dist/{chunk-7HSMUULV.js → chunk-FC53KN4H.js} +1 -1
- package/dist/{chunk-UYYTYSOD.js → chunk-UH2OK4XC.js} +1 -1
- package/dist/{chunk-VV4PRH7W.js → chunk-VY5D3IED.js} +1 -1
- package/dist/graphql/codegen.js +3 -3
- package/dist/graphql.js +3 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/nextjs/chunk-5XGJJVGX.js +544 -0
- package/dist/nextjs/components.cjs +155 -2
- package/dist/nextjs/components.d.cts +31 -3
- package/dist/nextjs/components.d.ts +31 -3
- package/dist/nextjs/components.js +155 -3
- package/dist/nextjs/graphql.cjs +588 -50
- package/dist/nextjs/graphql.d.cts +95 -28
- package/dist/nextjs/graphql.d.ts +95 -28
- package/dist/nextjs/graphql.js +287 -50
- package/dist/nextjs/index.cjs +3 -1
- package/dist/nextjs/index.d.cts +32 -3
- package/dist/nextjs/index.d.ts +32 -3
- package/dist/nextjs/index.js +8 -313
- package/dist/nextjs/{server-CjpELYvq.d.cts → server-BL-sqZvu.d.cts} +1 -1
- package/dist/nextjs/{server-CjpELYvq.d.ts → server-BL-sqZvu.d.ts} +1 -1
- package/dist/nuxt/{chunk-GMWF6PQ5.js → chunk-KROR7RXW.js} +1 -1
- package/dist/nuxt/graphql.js +1 -1
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/react/components.cjs +1 -1
- package/dist/react/components.js +1 -1
- package/dist/sveltekit/{chunk-5SQUG2L4.js → chunk-INDMNPEM.js} +1 -1
- package/dist/sveltekit/graphql.js +1 -1
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +1 -1
- package/dist/nextjs/chunk-ZIUKEGEN.js +0 -231
package/README.md
CHANGED
|
@@ -345,52 +345,59 @@ Conversions stay your choice: put `data-prepr-variant-event` (or `data-prepr-var
|
|
|
345
345
|
|
|
346
346
|
- A hidden A/B variant never scrolls into view, so it records no impression.
|
|
347
347
|
|
|
348
|
-
#####
|
|
348
|
+
##### The proxy
|
|
349
349
|
|
|
350
|
-
`
|
|
350
|
+
One call in `proxy.ts` gives `PreprStack` what it needs from the request: the visitor's Prepr headers and customer id, the A/B bucket, and the segment variants of the groups at the top of the page. Tell it which query each URL renders; most sites route every page through one query:
|
|
351
351
|
|
|
352
352
|
```ts
|
|
353
353
|
// proxy.ts
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
import { createPreprProxy } from '@preprio/toolkit/nextjs/graphql';
|
|
355
|
+
|
|
356
|
+
const handlePrepr = createPreprProxy({
|
|
357
|
+
client: prepr,
|
|
358
|
+
// URL → the query that page renders with `variants: true`; null for non-CMS URLs.
|
|
359
|
+
page: (url) => ({
|
|
360
|
+
document: PageDocument,
|
|
361
|
+
variables: { slug: url.pathname },
|
|
362
|
+
}),
|
|
363
|
+
preview: process.env.PREPR_ENV === 'preview',
|
|
359
364
|
});
|
|
360
|
-
|
|
365
|
+
|
|
366
|
+
export function proxy(request: NextRequest) {
|
|
367
|
+
return handlePrepr(request); // add your own cookies or headers to this response
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
```tsx
|
|
372
|
+
// app/layout.tsx, once
|
|
373
|
+
import { PreprPersonalizationSwitch } from '@preprio/toolkit/nextjs';
|
|
374
|
+
|
|
375
|
+
<PreprPersonalizationSwitch />;
|
|
361
376
|
```
|
|
362
377
|
|
|
363
|
-
|
|
378
|
+
API routes, `/_next/` and URLs whose last segment has a file extension (`/logo.png`, but also `/docs/v1.2`) are skipped, and so are pages without A/B tests or segment groups at the top (after a cached check). Pass `onlyIf: (request) => boolean` to skip Prepr for some requests, such as crawlers: they carry no cookies, so every crawler request is a first visit that waits for Prepr. In preview it also sends the editor through the [draft route](#preview) first. The pieces it combines stay exported (`createPreprMiddleware`, `resolvePreprBucket`, `prepr.resolveDecisions`, `preprDraftRedirect`) for proxies that need them separately.
|
|
379
|
+
|
|
380
|
+
##### A/B tests
|
|
381
|
+
|
|
382
|
+
`PreprStack` renders both variants of an A/B test in the static shell and shows the visitor's one before first paint; A is the default, also for crawlers. Prepr assigns the bucket once per visitor; the proxy stores it in a cookie, and only on pages that have an A/B test. Under a strict Content-Security-Policy, pass `nonce` to `PreprStack`.
|
|
364
383
|
|
|
365
384
|
##### Personalized content above the fold
|
|
366
385
|
|
|
367
|
-
A segment group streams in: the default variant shows first, then this visitor's variant replaces it. Below the fold nobody sees that.
|
|
386
|
+
A segment group streams in: the default variant shows first, then this visitor's variant replaces it. Below the fold nobody sees that. On the first screen they do, so the first block of a `PreprStack` is decided in the proxy instead: every variant of its segment groups is in the cached page, and the variant the proxy decided shows before first paint. Set `aboveTheFold` to the number of blocks on your first screen (per page; take the larger screen when it differs per device), or `0` to stream everything:
|
|
368
387
|
|
|
369
388
|
```tsx
|
|
370
|
-
<PreprStack items={data.Page.content} decisions={decisions} aboveTheFold={
|
|
389
|
+
<PreprStack items={data.Page.content} decisions={decisions} aboveTheFold={3} render={…} />
|
|
371
390
|
```
|
|
372
391
|
|
|
373
|
-
|
|
374
|
-
// proxy.ts, after createPreprMiddleware
|
|
375
|
-
await prepr.resolveDecisions(
|
|
376
|
-
request,
|
|
377
|
-
response,
|
|
378
|
-
PageDocument,
|
|
379
|
-
{ slug },
|
|
380
|
-
{
|
|
381
|
-
// Only pages whose personalized content is above the fold need it.
|
|
382
|
-
onlyIf: () => slug === '/',
|
|
383
|
-
},
|
|
384
|
-
);
|
|
385
|
-
```
|
|
392
|
+
Decisions stay fresh within a visit, so a visitor who joins a segment (by reading pages, clicking, submitting a form) sees its variant on their next page view, without anything on screen changing:
|
|
386
393
|
|
|
387
|
-
`
|
|
388
|
-
|
|
389
|
-
-
|
|
390
|
-
-
|
|
391
|
-
-
|
|
392
|
-
- The page carries the HTML of every variant of those groups, and images in hidden variants still download.
|
|
394
|
+
- `PreprPersonalizationSwitch` asks the proxy for new decisions in the background: about 3 and 10 seconds after each page view (Prepr needs a few seconds to process the visitor's activity), when the visitor points at a link to a personalized page, and when the tab comes back into view. A refresh is one small request that the proxy answers with cookies and no page.
|
|
395
|
+
- The proxy keeps a decision that covers the page for `freshFor` (default 10 seconds), so most page views, client-side or full, wait for nothing. An older decision, a first visit, UTM parameters and a segment forced in preview make it ask Prepr; the page then waits for the answer, at most `timeoutMs` (default 1000), after which the default variant shows.
|
|
396
|
+
- A decision that arrives while a page is being read applies from the next page view: content never changes under the reader. A visitor who joins a segment and clicks within a few seconds sees it one page view later.
|
|
397
|
+
- Next.js prefetches links as they scroll into view and on hover; a prefetch of a page without a fresh decision gets one, so even the first visit to a personalized page shows its variant at once.
|
|
398
|
+
- The page carries the HTML of every variant of those groups. `render` gets `defaultVariant`: give `priority` images only to the default variant and `loading="lazy"` to the others, or the browser downloads every variant's hero image.
|
|
393
399
|
- An item with a segment group nested inside it keeps streaming; only groups at the top level of the list are decided in the proxy.
|
|
400
|
+
- Decisions are uncached Prepr requests, so their time depends on how far your functions run from Prepr: deploy them in the region closest to your visitors and to Prepr.
|
|
394
401
|
|
|
395
402
|
##### Preview
|
|
396
403
|
|
|
@@ -954,6 +961,15 @@ The toolbar. Takes the props returned by `getToolbarProps`, and renders nothing
|
|
|
954
961
|
<PreprToolbar {...toolbarProps} />
|
|
955
962
|
```
|
|
956
963
|
|
|
964
|
+
#### `PreprPersonalizationSwitch`
|
|
965
|
+
|
|
966
|
+
From `@preprio/toolkit/nextjs`. Shows the segment variants the proxy decided for the groups above the fold before each page paints, and refreshes those decisions in the background (see [Personalized content above the fold](#personalized-content-above-the-fold)). Mount it once in the root layout. The decisions come from `createPreprProxy` or `prepr.resolveDecisions` in `proxy.ts`; the background refreshes only from `createPreprProxy` (with a hand-written `resolveDecisions` proxy, the first refresh gets a page back and refreshing stops for the browser session). Renders nothing.
|
|
967
|
+
|
|
968
|
+
| Prop | Default | Description |
|
|
969
|
+
| ---------- | ------- | ----------------------------------------------- |
|
|
970
|
+
| `refresh` | `true` | Refresh decisions in the background. |
|
|
971
|
+
| `freshFor` | `10000` | Same as `createPreprProxy`'s `freshFor`, in ms. |
|
|
972
|
+
|
|
957
973
|
#### `PreprPreview`
|
|
958
974
|
|
|
959
975
|
From `@preprio/toolkit/react`. The framework-free equivalent of `PreprToolbar`: same preview runtime, with the router binding left to you. Renders nothing.
|
package/dist/astro/graphql.js
CHANGED
package/dist/astro/index.cjs
CHANGED
package/dist/astro/index.js
CHANGED
package/dist/graphql/codegen.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
toDecisionQuery,
|
|
3
3
|
toSchemaInfo,
|
|
4
4
|
toVariantsQuery
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-FC53KN4H.js";
|
|
6
|
+
import "../chunk-UH2OK4XC.js";
|
|
7
|
+
import "../chunk-VY5D3IED.js";
|
|
8
8
|
|
|
9
9
|
// src/codegen/index.ts
|
|
10
10
|
function typeRef(type) {
|
package/dist/graphql.js
CHANGED
|
@@ -21,12 +21,12 @@ import {
|
|
|
21
21
|
toSchemaInfo,
|
|
22
22
|
toVariantsDocument,
|
|
23
23
|
toVariantsQuery
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FC53KN4H.js";
|
|
25
25
|
import {
|
|
26
26
|
PreprError,
|
|
27
27
|
validatePreprToken
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-UH2OK4XC.js";
|
|
29
|
+
import "./chunk-VY5D3IED.js";
|
|
30
30
|
|
|
31
31
|
// src/core/variants/probe-document.ts
|
|
32
32
|
function probeSelectionSet(set, fragments) {
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@ export { P as PreprPixelConfig, l as loadTrackingPixel, s as setTrackingParam, t
|
|
|
7
7
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
8
8
|
* core can import it without cycling through the barrel.
|
|
9
9
|
*/
|
|
10
|
-
declare const VERSION = "0.6.0-alpha.
|
|
10
|
+
declare const VERSION = "0.6.0-alpha.3";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { P as PreprPixelConfig, l as loadTrackingPixel, s as setTrackingParam, t
|
|
|
7
7
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
8
8
|
* core can import it without cycling through the barrel.
|
|
9
9
|
*/
|
|
10
|
-
declare const VERSION = "0.6.0-alpha.
|
|
10
|
+
declare const VERSION = "0.6.0-alpha.3";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
loadTrackingPixel,
|
|
16
16
|
setTrackingParam,
|
|
17
17
|
trackEvent
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-3YZANSVY.js";
|
|
19
19
|
import {
|
|
20
20
|
isPersonalizedResponse
|
|
21
21
|
} from "./chunk-3NCEVJJ3.js";
|
|
@@ -32,11 +32,11 @@ import {
|
|
|
32
32
|
getPreprUUIDFromHeaders,
|
|
33
33
|
getToolbarPropsFromHeaders,
|
|
34
34
|
validatePreprToken
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-UH2OK4XC.js";
|
|
36
36
|
import {
|
|
37
37
|
VERSION,
|
|
38
38
|
resolveFeatures
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-VY5D3IED.js";
|
|
40
40
|
|
|
41
41
|
// src/core/middleware.ts
|
|
42
42
|
var UTM_PARAMS = [
|