@se-studio/ab-testing 18.0.30 → 18.0.32
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/CHANGELOG.md +15 -0
- package/README.md +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +18 -0
- package/dist/utils.js.map +1 -1
- package/docs/llms.md +7 -6
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @se-studio/ab-testing
|
|
2
2
|
|
|
3
|
+
## 18.0.32
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Map page-test homepage canonical paths (`/`) to CMS slug `index` so control `indexed` is used instead of the variant's `noindex`.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @se-studio/core-ui@1.35.1
|
|
10
|
+
|
|
11
|
+
## 18.0.31
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [e746884]
|
|
16
|
+
- @se-studio/core-ui@1.35.0
|
|
17
|
+
|
|
3
18
|
## 18.0.30
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -159,9 +159,9 @@ export const config = {
|
|
|
159
159
|
|
|
160
160
|
#### Page-test route (static rebuild pattern)
|
|
161
161
|
|
|
162
|
-
When using `createStaticAbTestMiddleware` with `variantPathPrefix: '/page-test'`, add a `/page-test/[...slugs]` route that rewrites serve variant content on the control URL. Use `findCanonicalPath(testsByPath, variantSlug)` to resolve the user-facing path, then call the paired handlers from `@se-studio/core-ui/server`:
|
|
162
|
+
When using `createStaticAbTestMiddleware` with `variantPathPrefix: '/page-test'`, add a `/page-test/[...slugs]` route that rewrites serve variant content on the control URL. Use `findCanonicalPath(testsByPath, variantSlug)` to resolve the user-facing path, then `controlSlugFromCanonicalPath(canonicalPath)` for the control CMS slug (`/` → `index`). Do **not** use `canonicalPath.replace(/^\/|\/$/g, '') || variantSlug` — that maps the homepage to the variant (`indexed: false`) and flip-flops robots. Then call the paired handlers from `@se-studio/core-ui/server`:
|
|
163
163
|
|
|
164
|
-
- `generatePageTestMetadata` — control `indexed` and canonical path in `<head>`
|
|
164
|
+
- `generatePageTestMetadata` — control `indexed` and canonical path in `<head>` (re-resolves `/` to `index` even if the caller still passes the variant slug)
|
|
165
165
|
- `generatePageTest` — variant body with control identity for breadcrumbs, `href`, and JSON-LD
|
|
166
166
|
|
|
167
167
|
See the `se-marketing-sites-create-page` skill for the full route template. Direct visits to a variant's own CMS URL (normal page route) should keep using `generatePage`.
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type { AbTestMiddlewareConfig, AbTestResult, CachedAbTest, StaticAbTestMi
|
|
|
11
11
|
export { applyUrlParams, buildVariantId, clearTestCache, computeCachedTest, createAbTestMiddleware, createAssignment, createStaticAbTestMiddleware, DEFAULT_COOKIE_MAX_AGE, DEFAULT_COOKIE_NAME, getActiveTestIds, getAssignment, getCachedTests, getTestCacheState, isValidAssignment, normalizePath, parseCookie, processAbTestRequest, pruneStaleAssignments, readCookieFromDocument, selectVariant, serializeCookie, setAssignment, } from './middleware/index.js';
|
|
12
12
|
export { buildExperimentImpression } from './reporting/buildExperimentImpression.js';
|
|
13
13
|
export type { AbTest, AbTestAssignment, AbTestCookie, AbTestVariant, AbTestVariantConfig, IBlobStore, } from './types.js';
|
|
14
|
-
export { findCanonicalPath } from './utils.js';
|
|
14
|
+
export { CMS_HOMEPAGE_SLUG, controlSlugFromCanonicalPath, findCanonicalPath } from './utils.js';
|
|
15
15
|
export type { RawPageTest, WebhookHandlerConfig, WebhookResult, } from './webhook/index.js';
|
|
16
16
|
export { createWebhookHandler, normalizeVariantConfig, processAbTestWebhook, transformPageTest, } from './webhook/index.js';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,6BAA6B,EAC7B,UAAU,GACX,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,YAAY,EACV,MAAM,EACN,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,6BAA6B,EAC7B,UAAU,GACX,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,YAAY,EACV,MAAM,EACN,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChG,YAAY,EACV,WAAW,EACX,oBAAoB,EACpB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { useAbTestAssignments } from './hooks/index.js';
|
|
|
11
11
|
export { applyUrlParams, buildVariantId, clearTestCache, computeCachedTest, createAbTestMiddleware, createAssignment, createStaticAbTestMiddleware, DEFAULT_COOKIE_MAX_AGE, DEFAULT_COOKIE_NAME, getActiveTestIds, getAssignment, getCachedTests, getTestCacheState, isValidAssignment, normalizePath, parseCookie, processAbTestRequest, pruneStaleAssignments, readCookieFromDocument, selectVariant, serializeCookie, setAssignment, } from './middleware/index.js';
|
|
12
12
|
export { buildExperimentImpression } from './reporting/buildExperimentImpression.js';
|
|
13
13
|
// Utilities
|
|
14
|
-
export { findCanonicalPath } from './utils.js';
|
|
14
|
+
export { CMS_HOMEPAGE_SLUG, controlSlugFromCanonicalPath, findCanonicalPath } from './utils.js';
|
|
15
15
|
// Re-export webhook utilities
|
|
16
16
|
export { createWebhookHandler, normalizeVariantConfig, processAbTestWebhook, transformPageTest, } from './webhook/index.js';
|
|
17
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,kBAAkB;AAClB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAQxD,iCAAiC;AACjC,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAUrF,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,kBAAkB;AAClB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAQxD,iCAAiC;AACjC,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,4BAA4B,EAC5B,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAUrF,YAAY;AACZ,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMhG,8BAA8B;AAC9B,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import type { CachedAbTest } from './middleware/types';
|
|
2
|
+
/** CMS slug for the marketing homepage on SE Studio sites (public URL `/`). */
|
|
3
|
+
export declare const CMS_HOMEPAGE_SLUG = "index";
|
|
4
|
+
/**
|
|
5
|
+
* Map a public canonical path to the Contentful page slug used to fetch the
|
|
6
|
+
* PageTest **control**.
|
|
7
|
+
*
|
|
8
|
+
* Empty / root paths (`/`, `""`) map to {@link CMS_HOMEPAGE_SLUG} (`index`).
|
|
9
|
+
* Do **not** fall back to the variant slug: variants are `indexed: false`, so
|
|
10
|
+
* `canonicalPath.replace(/^\/|\/$/g, '') || variantSlug` noindexes `/`.
|
|
11
|
+
*
|
|
12
|
+
* Sites whose homepage CMS slug is not `index` (e.g. Pedestal `home`) should
|
|
13
|
+
* pass that slug as `homepageSlug`.
|
|
14
|
+
*
|
|
15
|
+
* Keep in sync with `@se-studio/core-ui` `controlSlugFromCanonicalPath`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function controlSlugFromCanonicalPath(canonicalPath: string, homepageSlug?: string): string;
|
|
2
18
|
/**
|
|
3
19
|
* Given a testsByPath map and a variant slug, returns the canonical
|
|
4
20
|
* (user-facing) path that owns the variant.
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAC3C,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CASpB"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,+EAA+E;AAC/E,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,MAAM,EACrB,YAAY,GAAE,MAA0B,GACvC,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAC3C,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CASpB"}
|
package/dist/utils.js
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/** CMS slug for the marketing homepage on SE Studio sites (public URL `/`). */
|
|
2
|
+
export const CMS_HOMEPAGE_SLUG = 'index';
|
|
3
|
+
/**
|
|
4
|
+
* Map a public canonical path to the Contentful page slug used to fetch the
|
|
5
|
+
* PageTest **control**.
|
|
6
|
+
*
|
|
7
|
+
* Empty / root paths (`/`, `""`) map to {@link CMS_HOMEPAGE_SLUG} (`index`).
|
|
8
|
+
* Do **not** fall back to the variant slug: variants are `indexed: false`, so
|
|
9
|
+
* `canonicalPath.replace(/^\/|\/$/g, '') || variantSlug` noindexes `/`.
|
|
10
|
+
*
|
|
11
|
+
* Sites whose homepage CMS slug is not `index` (e.g. Pedestal `home`) should
|
|
12
|
+
* pass that slug as `homepageSlug`.
|
|
13
|
+
*
|
|
14
|
+
* Keep in sync with `@se-studio/core-ui` `controlSlugFromCanonicalPath`.
|
|
15
|
+
*/
|
|
16
|
+
export function controlSlugFromCanonicalPath(canonicalPath, homepageSlug = CMS_HOMEPAGE_SLUG) {
|
|
17
|
+
return canonicalPath.replace(/^\/+|\/+$/g, '') || homepageSlug;
|
|
18
|
+
}
|
|
1
19
|
/**
|
|
2
20
|
* Given a testsByPath map and a variant slug, returns the canonical
|
|
3
21
|
* (user-facing) path that owns the variant.
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAA2C,EAC3C,WAAmB;IAEnB,KAAK,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;gBACtD,OAAO,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAC1C,aAAqB,EACrB,YAAY,GAAW,iBAAiB;IAExC,OAAO,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,WAA2C,EAC3C,WAAmB;IAEnB,KAAK,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;gBACtD,OAAO,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/docs/llms.md
CHANGED
|
@@ -96,11 +96,12 @@ import {
|
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
98
|
import {
|
|
99
|
-
selectVariant,
|
|
100
|
-
getAssignment,
|
|
101
|
-
setAssignment,
|
|
102
|
-
isValidAssignment,
|
|
103
|
-
normalizePath,
|
|
104
|
-
findCanonicalPath,
|
|
99
|
+
selectVariant, // weighted random variant selection
|
|
100
|
+
getAssignment, // read assignment from cookies
|
|
101
|
+
setAssignment, // write assignment to response cookies
|
|
102
|
+
isValidAssignment, // validate an assignment object
|
|
103
|
+
normalizePath, // normalise URL paths for comparison
|
|
104
|
+
findCanonicalPath, // resolve variant path back to canonical
|
|
105
|
+
controlSlugFromCanonicalPath, // `/` → CMS slug `index` (never the variant)
|
|
105
106
|
} from '@se-studio/ab-testing';
|
|
106
107
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/ab-testing",
|
|
3
|
-
"version": "18.0.
|
|
3
|
+
"version": "18.0.32",
|
|
4
4
|
"description": "Server-side A/B testing framework for Next.js applications with Contentful CMS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
"url": "https://github.com/Something-Else-Studio/se-core-product/issues"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@se-studio/core-ui": "1.
|
|
70
|
+
"@se-studio/core-ui": "1.35.1",
|
|
71
71
|
"next": ">=15.5.0 <17",
|
|
72
72
|
"react": "^19.0.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@biomejs/biome": "^2.5.12",
|
|
76
|
-
"@se-studio/core-ui": "1.
|
|
76
|
+
"@se-studio/core-ui": "1.35.1",
|
|
77
77
|
"@types/node": "^24.13.3",
|
|
78
78
|
"@types/react": "^19.2.18",
|
|
79
79
|
"next": "^16.3.4",
|