@picked/client 0.0.70 → 0.0.71-next.2
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/dist/.tsbuildinfo +1 -0
- package/dist/api-B0ydpQBE.js +38 -0
- package/dist/api-CObostrU.cjs +1 -0
- package/dist/cjs/form/index.js +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/plugins/dom-observer/index.js +1 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/docs/explanation/conditions-and-the-logic-engine.md +94 -0
- package/dist/docs/explanation/feature-flag-allocation.md +176 -0
- package/dist/docs/explanation/how-picked-works.md +102 -0
- package/dist/docs/explanation/how-pickedql-works.md +76 -0
- package/dist/docs/explanation/pages-and-flows.md +64 -0
- package/dist/docs/explanation/the-content-model.md +77 -0
- package/dist/docs/explanation/the-two-apis.md +68 -0
- package/dist/docs/explanation/why-server-side-rendering.md +76 -0
- package/dist/docs/explanation/workspaces-and-versions.md +71 -0
- package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
- package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +19 -6
- package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
- package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
- package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
- package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
- package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
- package/dist/docs/{flow-builder/building-flows.md → how-to/build-a-flow.md} +13 -9
- package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
- package/dist/docs/how-to/create-a-project.md +29 -0
- package/dist/docs/how-to/create-an-experience.md +42 -0
- package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
- package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
- package/dist/docs/how-to/define-a-page-layout.md +39 -0
- package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
- package/dist/docs/{gtm-template.md → how-to/install-the-gtm-template.md} +9 -3
- package/dist/docs/how-to/install-the-sdk.md +68 -0
- package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
- package/dist/docs/how-to/invite-and-remove-members.md +34 -0
- package/dist/docs/how-to/preview-a-workspace.md +28 -0
- package/dist/docs/how-to/publish-a-workspace.md +30 -0
- package/dist/docs/how-to/read-a-feature-flag.md +101 -0
- package/dist/docs/how-to/register-a-component.md +55 -0
- package/dist/docs/how-to/register-an-action-handler.md +67 -0
- package/dist/docs/how-to/render-a-step-form.md +132 -0
- package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
- package/dist/docs/how-to/reuse-a-section.md +37 -0
- package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
- package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
- package/dist/docs/how-to/run-an-ab-test.md +49 -0
- package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
- package/dist/docs/how-to/server-render-a-page.md +81 -0
- package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
- package/dist/docs/how-to/set-up-mfa.md +69 -0
- package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
- package/dist/docs/how-to/validate-a-field.md +52 -0
- package/dist/docs/how-to/write-a-condition.md +45 -0
- package/dist/docs/how-to/write-a-predicate.md +60 -0
- package/dist/docs/index.md +41 -70
- package/dist/docs/reference/dashboard/actions.mdx +53 -0
- package/dist/docs/{api-keys.mdx → reference/dashboard/api-keys.mdx} +7 -15
- package/dist/docs/reference/dashboard/conditions.mdx +42 -0
- package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
- package/dist/docs/{content → reference/dashboard/content}/content-entries.mdx +11 -3
- package/dist/docs/{content → reference/dashboard/content}/layouts.mdx +11 -35
- package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
- package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
- package/dist/docs/{experiences.mdx → reference/dashboard/experiences.mdx} +9 -16
- package/dist/docs/{features.mdx → reference/dashboard/features.mdx} +26 -41
- package/dist/docs/{fields.mdx → reference/dashboard/fields.mdx} +26 -20
- package/dist/docs/{flow-builder/overview.mdx → reference/dashboard/flow-builder/canvas.mdx} +8 -13
- package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/condition-builder.md +5 -13
- package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/keyboard-shortcuts.md +7 -1
- package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/nodes.md +10 -3
- package/dist/docs/reference/dashboard/projects.mdx +44 -0
- package/dist/docs/reference/dashboard/reports.mdx +43 -0
- package/dist/docs/reference/dashboard/steps.mdx +37 -0
- package/dist/docs/{team-management.md → reference/dashboard/team-management.md} +5 -22
- package/dist/docs/{workspace-versioning.mdx → reference/dashboard/workspace-versioning.mdx} +6 -10
- package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +11 -4
- package/dist/docs/reference/delivery-api/index.md +45 -0
- package/dist/docs/{delivery-api → reference/delivery-api}/preview-caching-crawling.md +12 -5
- package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +11 -4
- package/dist/docs/reference/glossary.md +173 -0
- package/dist/docs/reference/management-api/authentication.md +74 -0
- package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +10 -3
- package/dist/docs/{api → reference/management-api}/error-handling.md +9 -3
- package/dist/docs/{api → reference/management-api}/pagination.md +6 -0
- package/dist/docs/{pickedql → reference/pickedql}/data-sources.md +16 -9
- package/dist/docs/{pickedql → reference/pickedql}/dimensions.md +7 -0
- package/dist/docs/{pickedql → reference/pickedql}/filtering.md +7 -0
- package/dist/docs/reference/pickedql/index.md +18 -0
- package/dist/docs/{pickedql → reference/pickedql}/schema.md +13 -6
- package/dist/docs/{pickedql → reference/pickedql}/virtual-functions.md +7 -0
- package/dist/docs/reference/sdk/actions.md +30 -0
- package/dist/docs/{sdk → reference/sdk}/conditions.md +8 -1
- package/dist/docs/reference/sdk/content-security-policy.md +21 -0
- package/dist/docs/reference/sdk/experiences.md +51 -0
- package/dist/docs/{sdk → reference/sdk}/features.md +30 -117
- package/dist/docs/{sdk → reference/sdk}/fields.md +10 -88
- package/dist/docs/reference/sdk/index.md +68 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +10 -22
- package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +26 -0
- package/dist/docs/reference/sdk/plugins/index.md +29 -0
- package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
- package/dist/docs/reference/sdk/predicates.md +43 -0
- package/dist/docs/reference/sdk/ssr/index.md +33 -0
- package/dist/docs/{sdk → reference/sdk}/ssr/rendering-and-hydration.md +4 -63
- package/dist/docs/{sdk → reference/sdk}/ssr/serialize.md +6 -33
- package/dist/docs/{sdk → reference/sdk}/ssr/slots-and-placements.md +7 -1
- package/dist/docs/reference/sdk/steps.md +87 -0
- package/dist/docs/reference/tools/chrome-extension.md +16 -0
- package/dist/docs/{image-optimisation-service.md → reference/tools/image-optimisation-service.md} +8 -0
- package/dist/docs/{mcp.md → reference/tools/mcp.md} +5 -45
- package/dist/docs/{vite-plugin.md → reference/tools/vite-plugin.md} +8 -38
- package/dist/docs/{api/index.md → tutorials/first-api-call.md} +27 -15
- package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
- package/dist/docs/tutorials/first-experience.mdx +255 -0
- package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
- package/dist/{dom-BwmTHeT7.js → dom-BqcToNL0.js} +1 -3
- package/dist/{dom-CDrHc_j9.cjs → dom-DlLH3FxV.cjs} +1 -1
- package/dist/esm/form/index.js +2 -4
- package/dist/esm/index.js +306 -298
- package/dist/esm/plugins/dom-observer/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
- package/dist/esm/preview/index.js +1 -1
- package/dist/esm/server/index.js +12 -10
- package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
- package/dist/experience-instance-Dej3P1sE.cjs +1 -0
- package/dist/plugin-CNna0UjB.cjs +1 -0
- package/dist/{plugin-ChPkTj__.js → plugin-DUOJpHaq.js} +2 -2
- package/dist/{preview-channel-DW9J8t4B.js → preview-channel-CSr96XAo.js} +1 -1
- package/dist/{protocol-DSqOlW2r.js → protocol-C5KkkiZc.js} +1 -1
- package/dist/types/client.d.ts +7 -6
- package/dist/types/entities/action/action.d.ts +5 -4
- package/dist/types/entities/action/action.d.ts.map +1 -1
- package/dist/types/entities/component/component.d.ts +6 -5
- package/dist/types/entities/component/component.d.ts.map +1 -1
- package/dist/types/entities/condition/condition.d.ts +5 -5
- package/dist/types/entities/content/content.d.ts +4 -3
- package/dist/types/entities/experience/experience.d.ts +11 -10
- package/dist/types/entities/experience/experience.d.ts.map +1 -1
- package/dist/types/entities/experience-instance/experience-instance.d.ts +10 -9
- package/dist/types/entities/feature/feature.d.ts +19 -2
- package/dist/types/entities/feature/feature.d.ts.map +1 -1
- package/dist/types/entities/field/field.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts +7 -6
- package/dist/types/entities/framework/framework.d.ts.map +1 -1
- package/dist/types/entities/history/history.d.ts +6 -6
- package/dist/types/entities/plugin/plugin.d.ts +3 -2
- package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
- package/dist/types/entities/predicate/predicate.d.ts +4 -3
- package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
- package/dist/types/entities/response/response-validation.d.ts +3 -2
- package/dist/types/entities/response/response.d.ts +12 -11
- package/dist/types/entities/session/session.d.ts +2 -1
- package/dist/types/entities/step/step.d.ts +6 -5
- package/dist/types/exports.d.ts +2 -1
- package/dist/types/exports.d.ts.map +1 -1
- package/dist/types/form/build-responses.d.ts +2 -1
- package/dist/types/form/create-field-evaluator.d.ts +4 -3
- package/dist/types/form/create-field-validation.d.ts +5 -4
- package/dist/types/form/create-form.d.ts +7 -6
- package/dist/types/form/create-submit-pipeline.d.ts +7 -6
- package/dist/types/form/get-step-fields.d.ts +3 -2
- package/dist/types/lifecycle/condition-selection.d.ts +14 -4
- package/dist/types/lifecycle/lifecycle.d.ts +4 -3
- package/dist/types/lifecycle/rules-logic.d.ts +4 -3
- package/dist/types/lifecycle/state-snapshot.d.ts +4 -3
- package/dist/types/picked.d.ts +64 -62
- package/dist/types/picked.d.ts.map +1 -1
- package/dist/types/ping.d.ts +1 -1
- package/dist/types/ping.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/create-experience.d.ts +9 -8
- package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/plugin.d.ts +3 -2
- package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
- package/dist/types/plugins/dom-observer/plugin.d.ts +1 -1
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts +3 -3
- package/dist/types/plugins/dynamic-experiences/types.d.ts +8 -5
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts +1 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +1 -1
- package/dist/types/plugins/responses-indexeddb/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts +1 -1
- package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
- package/dist/types/plugins/web-components/plugin.d.ts +2 -1
- package/dist/types/plugins/window-object/plugin.d.ts +2 -2
- package/dist/types/preview-channel.d.ts +5 -1
- package/dist/types/preview-receiver/index.d.ts +18 -1
- package/dist/types/preview-receiver/protocol.d.ts +10 -1
- package/dist/types/server/index.d.ts +3 -3
- package/dist/types/server/serialize.d.ts +2 -2
- package/dist/types/utils/dom.d.ts +2 -1
- package/dist/types/utils/events.d.ts +6 -6
- package/dist/types/utils/events.d.ts.map +1 -1
- package/dist/types/utils/global-obj.d.ts +1 -1
- package/dist/types/utils/global-obj.d.ts.map +1 -1
- package/dist/types/utils/id.d.ts.map +1 -1
- package/dist/types/utils/logger.d.ts +2 -1
- package/dist/types/utils/logger.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +2 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
- package/dist/types/utils/nodes.d.ts +1 -1
- package/dist/types/utils/picked-config.d.ts +2 -1
- package/dist/types/utils/rules-logic.d.ts +6 -2
- package/dist/types/utils/storage.d.ts +1 -1
- package/dist/types/utils/storage.d.ts.map +1 -1
- package/package.json +22 -23
- package/dist/api-CPy9G49C.js +0 -40
- package/dist/api-Ce6xYI--.cjs +0 -1
- package/dist/docs/actions.mdx +0 -98
- package/dist/docs/api/authentication.md +0 -403
- package/dist/docs/chrome-extension.md +0 -68
- package/dist/docs/conditions.mdx +0 -72
- package/dist/docs/content/asset-library.mdx +0 -124
- package/dist/docs/content/pages.mdx +0 -82
- package/dist/docs/content/sections.mdx +0 -44
- package/dist/docs/delivery-api/index.md +0 -53
- package/dist/docs/guides/build-a-personalized-page.mdx +0 -161
- package/dist/docs/pickedql/index.md +0 -54
- package/dist/docs/projects.mdx +0 -44
- package/dist/docs/reports.mdx +0 -20
- package/dist/docs/sdk/actions.md +0 -82
- package/dist/docs/sdk/content-security-policy.md +0 -33
- package/dist/docs/sdk/experiences.md +0 -64
- package/dist/docs/sdk/feature-allocation.md +0 -161
- package/dist/docs/sdk/index.md +0 -98
- package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -84
- package/dist/docs/sdk/plugins/index.md +0 -9
- package/dist/docs/sdk/predicates.md +0 -128
- package/dist/docs/sdk/ssr/index.md +0 -79
- package/dist/docs/sdk/steps.md +0 -479
- package/dist/docs/steps.mdx +0 -53
- package/dist/docs/workspaces.mdx +0 -133
- package/dist/experience-instance-DurC3pE-.cjs +0 -1
- package/dist/plugin-DHn11gn6.cjs +0 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
layout: docs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Predicates
|
|
7
|
+
|
|
8
|
+
A predicate holds reusable condition logic that reads the current state of your
|
|
9
|
+
application. Each predicate is a pure function. It takes a state snapshot, and that
|
|
10
|
+
snapshot holds the responses, the fields, the browser context, and optional
|
|
11
|
+
arguments.
|
|
12
|
+
|
|
13
|
+
## Use the state snapshot
|
|
14
|
+
|
|
15
|
+
Each predicate takes a `StateSnapshot` object with these properties:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
interface StateSnapshot {
|
|
19
|
+
client: Picked // The Picked client.
|
|
20
|
+
responses?: Array<{
|
|
21
|
+
// Every response from the user.
|
|
22
|
+
fieldId: string
|
|
23
|
+
value: FieldValue | undefined
|
|
24
|
+
}>
|
|
25
|
+
args?: unknown[]
|
|
26
|
+
fields?: Field[] // Every registered field.
|
|
27
|
+
location?: Location // The browser location: URL, pathname, search, and more.
|
|
28
|
+
document?: Document // The browser document object.
|
|
29
|
+
sessionStorage?: Storage // The browser sessionStorage API.
|
|
30
|
+
localStorage?: Storage // The browser localStorage API.
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
:::warning
|
|
35
|
+
In server-side rendering, and in any environment that is not a browser, `location`,
|
|
36
|
+
`document`, `sessionStorage`, and `localStorage` are `undefined`.
|
|
37
|
+
:::
|
|
38
|
+
|
|
39
|
+
## Related
|
|
40
|
+
|
|
41
|
+
- [How to write a predicate](/how-to/write-a-predicate)
|
|
42
|
+
- [About conditions and the logic engine](/explanation/conditions-and-the-logic-engine) —
|
|
43
|
+
why predicates exist.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
layout: docs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Server-Side Rendering
|
|
7
|
+
|
|
8
|
+
Render a Picked Page on your server so that search engines can read it. Then hydrate
|
|
9
|
+
the page on the client. This page shows the whole shape. The pages after it cover
|
|
10
|
+
each part.
|
|
11
|
+
|
|
12
|
+
## The server entry point
|
|
13
|
+
|
|
14
|
+
The server helpers live in a dedicated entry point, so a browser bundle never holds
|
|
15
|
+
them:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { serialize, registerProjectConfig } from '@picked/client/server'
|
|
19
|
+
import type { PickedSnapshot } from '@picked/client/server'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Go to [Server Snapshot](/reference/sdk/ssr/serialize) for the `serialize()` reference. Go to
|
|
23
|
+
[Rendering and Hydration](/reference/sdk/ssr/rendering-and-hydration) to connect React and
|
|
24
|
+
Svelte. Go to [Slots and Placements](/reference/sdk/ssr/slots-and-placements) for how a slot
|
|
25
|
+
chooses an experience. If the SDK is new to you, read
|
|
26
|
+
[Installation](/reference/sdk) first.
|
|
27
|
+
|
|
28
|
+
## Related
|
|
29
|
+
|
|
30
|
+
- [About server-side rendering](/explanation/why-server-side-rendering) — why the snapshot
|
|
31
|
+
exists.
|
|
32
|
+
- [How to server-render a page](/how-to/server-render-a-page)
|
|
33
|
+
- [Server snapshot](/reference/sdk/ssr/serialize)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -46,13 +47,6 @@ top of the `<script>` block of a component. It takes the same two modes,
|
|
|
46
47
|
<ExperienceSlot name="page" />
|
|
47
48
|
```
|
|
48
49
|
|
|
49
|
-
## Place the slot
|
|
50
|
-
|
|
51
|
-
Put `<ExperienceSlot name="page" />` where the Page must render. The slot renders
|
|
52
|
-
every experience that points at it and whose condition is active. See
|
|
53
|
-
[Slots and Placements](/sdk/ssr/slots-and-placements) for how a slot chooses and
|
|
54
|
-
orders your experiences.
|
|
55
|
-
|
|
56
50
|
## Render the page component
|
|
57
51
|
|
|
58
52
|
The SDK does not connect content to a component. You own the component that a Page
|
|
@@ -103,60 +97,7 @@ export function CMSPage() {
|
|
|
103
97
|
while no content is registered. `getStepContent()` returns a store, and you read it
|
|
104
98
|
with `$content`.
|
|
105
99
|
|
|
106
|
-
##
|
|
107
|
-
|
|
108
|
-
This is the page-slot setup that we tested. The page client reads the project options
|
|
109
|
-
and renders the Page experience that points at `.picked-slot-page` and matches the
|
|
110
|
-
current URL.
|
|
111
|
-
|
|
112
|
-
:::code-group
|
|
113
|
-
|
|
114
|
-
```tsx [React]
|
|
115
|
-
import type { CreateClientOptions } from '@picked/client'
|
|
116
|
-
import type { PickedSnapshot } from '@picked/client/server'
|
|
117
|
-
import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
|
|
118
|
-
import { adaptReactComponent, ExperienceSlot, PickedProvider } from '@picked/react'
|
|
119
|
-
import { reactFrameworkPlugin } from '@picked/react/plugins/framework'
|
|
120
|
-
import { CMSPage } from './CMSPage'
|
|
121
|
-
|
|
122
|
-
const options = {
|
|
123
|
-
projectId: 'sdk-cvly-x',
|
|
124
|
-
components: { CMSPage: adaptReactComponent(CMSPage) },
|
|
125
|
-
plugins: [reactFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
|
|
126
|
-
} satisfies CreateClientOptions
|
|
127
|
-
|
|
128
|
-
export function PageSlot({ snapshot }: { snapshot?: PickedSnapshot }) {
|
|
129
|
-
return (
|
|
130
|
-
<PickedProvider options={options} snapshot={snapshot}>
|
|
131
|
-
<ExperienceSlot name="page" />
|
|
132
|
-
</PickedProvider>
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
```svelte [Svelte]
|
|
138
|
-
<script lang="ts">
|
|
139
|
-
import type { CreateClientOptions } from '@picked/client'
|
|
140
|
-
import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
|
|
141
|
-
import { adaptSvelteComponent, ExperienceSlot, setPickedContext } from '@picked/svelte'
|
|
142
|
-
import { svelteFrameworkPlugin } from '@picked/svelte/plugins/framework'
|
|
143
|
-
import CMSPage from './CMSPage.svelte'
|
|
144
|
-
|
|
145
|
-
const options = {
|
|
146
|
-
projectId: 'sdk-cvly-x',
|
|
147
|
-
components: { CMSPage: adaptSvelteComponent(CMSPage) },
|
|
148
|
-
plugins: [svelteFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
|
|
149
|
-
} satisfies CreateClientOptions
|
|
150
|
-
|
|
151
|
-
setPickedContext({ options })
|
|
152
|
-
</script>
|
|
153
|
-
|
|
154
|
-
<ExperienceSlot name="page" />
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
:::
|
|
100
|
+
## Related
|
|
158
101
|
|
|
159
|
-
|
|
160
|
-
[
|
|
161
|
-
reference, see [Server Snapshot](/sdk/ssr/serialize). For how an experience
|
|
162
|
-
registers, see [SDK Experiences](/sdk/experiences).
|
|
102
|
+
- [How to server-render a page](/how-to/server-render-a-page) — the full example.
|
|
103
|
+
- [Slots and placements](/reference/sdk/ssr/slots-and-placements)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -22,7 +23,7 @@ const snapshot = await serialize(client, {
|
|
|
22
23
|
})
|
|
23
24
|
```
|
|
24
25
|
|
|
25
|
-
`serialize()` does this. It registers the project
|
|
26
|
+
`serialize()` does this. It registers the project configuration on the client at once. It
|
|
26
27
|
evaluates the condition of each experience against `attributes.location`. It reads
|
|
27
28
|
the content for each experience whose steps point at layout content. It removes the
|
|
28
29
|
duplicate content blobs, which it finds by their IDs. It then returns a
|
|
@@ -39,7 +40,7 @@ serialize(client: Picked, params: SerializeParams): Promise<PickedSnapshot>
|
|
|
39
40
|
|
|
40
41
|
| Parameter | Type | Default | Description |
|
|
41
42
|
| --- | --- | --- | --- |
|
|
42
|
-
| `projectConfig` | `ProjectConfig` | required | The published
|
|
43
|
+
| `projectConfig` | `ProjectConfig` | required | The published configuration, or the preview configuration, to register and choose against. |
|
|
43
44
|
| `attributes.location` | `Partial<SerializeLocation>` | none | The URL fields that go into the selection context, such as `pathname`. |
|
|
44
45
|
| `getContent` | `SerializeGetContent` | runtime API | Your own function to read content, in place of the runtime API. |
|
|
45
46
|
| `previewToken` | `string` | none | The SDK sends this with the content request, so that preview content resolves during a preview render. |
|
|
@@ -70,35 +71,7 @@ interface PickedSnapshot {
|
|
|
70
71
|
The snapshot is plain JSON. Write it into your HTML response with `JSON.stringify`
|
|
71
72
|
and read it back on the client.
|
|
72
73
|
|
|
73
|
-
##
|
|
74
|
+
## Related
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
const html = `
|
|
80
|
-
<div id="root">${appHtml}</div>
|
|
81
|
-
<script>window.__PICKED__ = ${JSON.stringify(snapshot)}</script>
|
|
82
|
-
`
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
On the client, read `window.__PICKED__` and pass it as the `snapshot` prop. See
|
|
86
|
-
[Rendering and Hydration](/sdk/ssr/rendering-and-hydration).
|
|
87
|
-
|
|
88
|
-
## Render a preview
|
|
89
|
-
|
|
90
|
-
Pass `previewToken`, so that unpublished content resolves during a preview render.
|
|
91
|
-
The server cannot read the query string of the request, so there is no other way to
|
|
92
|
-
give it the token:
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
const snapshot = await serialize(client, {
|
|
96
|
-
projectConfig,
|
|
97
|
-
attributes: { location: { pathname: '/promo' } },
|
|
98
|
-
previewToken,
|
|
99
|
-
})
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Use the same token when you read `projectConfig` from the
|
|
103
|
-
[Delivery API](/delivery-api). The options and the content then come from the same
|
|
104
|
-
preview.
|
|
76
|
+
- [How to server-render a page](/how-to/server-render-a-page)
|
|
77
|
+
- [How to render an unpublished preview](/how-to/render-an-unpublished-preview)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -50,4 +51,9 @@ experience is among the active ones, only that experience renders. With no activ
|
|
|
50
51
|
|
|
51
52
|
One Page can therefore take a whole slot with `replace`, while another slot holds
|
|
52
53
|
several experiences that use the other placements. A condition decides which
|
|
53
|
-
experiences are active. See [Conditions](/conditions).
|
|
54
|
+
experiences are active. See [Conditions](/reference/dashboard/conditions).
|
|
55
|
+
|
|
56
|
+
## Related
|
|
57
|
+
|
|
58
|
+
- [About server-side rendering](/explanation/why-server-side-rendering) — why placements
|
|
59
|
+
have an order.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
layout: docs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Steps
|
|
7
|
+
|
|
8
|
+
Render your steps with `<StepRouter>` and `<Step>` from `@picked/react` or
|
|
9
|
+
`@picked/svelte`. Reach the active step through `useStep()` or `getStep()`.
|
|
10
|
+
|
|
11
|
+
## Reach the step context
|
|
12
|
+
|
|
13
|
+
Inside a `Step` component, or inside any component that a `Step` renders, call
|
|
14
|
+
`getStep()` or `useStep()` to reach the reactive context of the step:
|
|
15
|
+
|
|
16
|
+
:::code-group
|
|
17
|
+
|
|
18
|
+
```tsx [React]
|
|
19
|
+
import { useStep } from '@picked/react/hooks'
|
|
20
|
+
import { useUnit } from 'effector-react'
|
|
21
|
+
|
|
22
|
+
function ContactForm() {
|
|
23
|
+
const { step, fields } = useStep()
|
|
24
|
+
const currentStep = useUnit(step)
|
|
25
|
+
const currentFields = useUnit(fields)
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<>
|
|
29
|
+
<h1>{currentStep.label}</h1>
|
|
30
|
+
|
|
31
|
+
{currentFields.map((field) => (
|
|
32
|
+
<div key={field.id}>
|
|
33
|
+
<label>{field.label}</label>
|
|
34
|
+
<input
|
|
35
|
+
name={field.id}
|
|
36
|
+
value={field.value ?? ''}
|
|
37
|
+
onChange={field.onChange}
|
|
38
|
+
onBlur={field.onBlur}
|
|
39
|
+
/>
|
|
40
|
+
{field.error && field.touched && <p className="error">{field.error.userMessage}</p>}
|
|
41
|
+
</div>
|
|
42
|
+
))}
|
|
43
|
+
</>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```svelte [Svelte]
|
|
49
|
+
<script lang="ts">
|
|
50
|
+
import { getStep } from '@picked/svelte/hooks'
|
|
51
|
+
|
|
52
|
+
const { step, fields } = getStep()
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<h1>{$step.label}</h1>
|
|
56
|
+
|
|
57
|
+
{#each $fields as field}
|
|
58
|
+
<label>{field.label}</label>
|
|
59
|
+
<input
|
|
60
|
+
name={field.id}
|
|
61
|
+
value={field.value ?? ''}
|
|
62
|
+
onchange={field.onChange}
|
|
63
|
+
onblur={field.onBlur}
|
|
64
|
+
/>
|
|
65
|
+
{#if field.error && field.touched}
|
|
66
|
+
<p class="error">{field.error.userMessage}</p>
|
|
67
|
+
{/if}
|
|
68
|
+
{/each}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
:::
|
|
72
|
+
|
|
73
|
+
`getStep()` in Svelte, and `useStep()` in React, return a `StepContext` with these
|
|
74
|
+
properties:
|
|
75
|
+
|
|
76
|
+
| Property | Type | Description |
|
|
77
|
+
| ---------- | --------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
78
|
+
| `step` | `Store<ExperienceStep>` | A reactive store that holds the `id` and the `label` of the step |
|
|
79
|
+
| `fields` | `Store<FormField[]>` | A reactive store of the fields, with their current values, errors, and handlers |
|
|
80
|
+
| `isActive` | `Store<boolean>` (Svelte) / `boolean` (React) | Whether the router holds this step as the active one |
|
|
81
|
+
| `form` | Object | The handlers for a form submission. See [Forms](#forms). |
|
|
82
|
+
|
|
83
|
+
## Related
|
|
84
|
+
|
|
85
|
+
- [How to render a step form](/how-to/render-a-step-form)
|
|
86
|
+
- [How to run code on a form submission](/how-to/run-code-on-a-form-submission)
|
|
87
|
+
- [About how Picked works](/explanation/how-picked-works) — why a flow is a graph.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
layout: docs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chrome Extension
|
|
7
|
+
|
|
8
|
+
The extension for the Picked Developer Tools adds a Picked panel to Chrome DevTools.
|
|
9
|
+
Use the panel to check and debug your Picked integration on any page that runs the
|
|
10
|
+
SDK.
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
## Related
|
|
15
|
+
|
|
16
|
+
- [How to debug with the Chrome extension](/how-to/debug-with-the-chrome-extension)
|
package/dist/docs/{image-optimisation-service.md → reference/tools/image-optimisation-service.md}
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -94,3 +95,10 @@ that time.
|
|
|
94
95
|
(`default-src *; script-src 'none'; sandbox;`). A compromised source therefore
|
|
95
96
|
cannot run a script in the browser that shows the image.
|
|
96
97
|
- The response uses `Content-Disposition: inline`, and never `attachment`.
|
|
98
|
+
|
|
99
|
+
## Related
|
|
100
|
+
|
|
101
|
+
- [Asset library](/reference/dashboard/content/asset-library) — where the images come
|
|
102
|
+
from.
|
|
103
|
+
- [Content Security Policy](/reference/sdk/content-security-policy) — the `img-src`
|
|
104
|
+
entry this service needs.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -7,51 +8,6 @@ layout: docs
|
|
|
7
8
|
Control your Picked workspace from an AI tool that writes code, with the Model
|
|
8
9
|
Context Protocol (MCP).
|
|
9
10
|
|
|
10
|
-
## Connect
|
|
11
|
-
|
|
12
|
-
The server URL is `https://api.picked.app/mcp`.
|
|
13
|
-
|
|
14
|
-
### Claude Desktop
|
|
15
|
-
|
|
16
|
-
1. Open **Settings > Connectors > Add custom connector**.
|
|
17
|
-
2. Set **Name** to `Picked` and **URL** to `https://api.picked.app/mcp`.
|
|
18
|
-
3. Click **Connect** and answer the authorization prompt.
|
|
19
|
-
|
|
20
|
-
### Project configuration in `.mcp.json`
|
|
21
|
-
|
|
22
|
-
Add this file to the root of your repository. It works with Claude Code, Cursor,
|
|
23
|
-
Windsurf, and other tools that support MCP.
|
|
24
|
-
|
|
25
|
-
:::code-group
|
|
26
|
-
|
|
27
|
-
```json [.mcp.json]
|
|
28
|
-
{
|
|
29
|
-
"mcpServers": {
|
|
30
|
-
"picked": {
|
|
31
|
-
"type": "http",
|
|
32
|
-
"url": "https://api.picked.app/mcp"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
:::
|
|
39
|
-
|
|
40
|
-
### Cursor
|
|
41
|
-
|
|
42
|
-
Add this file to `.cursor/mcp.json` in the root of your project:
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"mcpServers": {
|
|
47
|
-
"picked": {
|
|
48
|
-
"type": "http",
|
|
49
|
-
"url": "https://api.picked.app/mcp"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
11
|
## Tools
|
|
56
12
|
|
|
57
13
|
### Discovery
|
|
@@ -126,3 +82,7 @@ functions, and the dimension columns before you write a query.
|
|
|
126
82
|
is correct.
|
|
127
83
|
- Ask your agent to run a PickedQL query on your analytics data. The agent can read
|
|
128
84
|
the schema, write the SQL, and explain the rows.
|
|
85
|
+
|
|
86
|
+
## Related
|
|
87
|
+
|
|
88
|
+
- [How to connect the MCP server](/how-to/connect-the-mcp-server)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: reference
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
@@ -10,52 +11,17 @@ option, so the SDK makes no API request at runtime. In development it also serve
|
|
|
10
11
|
launcher page. On that page you can see a preview of an experience with your own
|
|
11
12
|
feature flag values.
|
|
12
13
|
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
:::code-group
|
|
16
|
-
|
|
17
|
-
```bash [npm]
|
|
18
|
-
npm install @picked/vite-plugin-picked
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
```bash [pnpm]
|
|
22
|
-
pnpm add @picked/vite-plugin-picked
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
```bash [yarn]
|
|
26
|
-
yarn add @picked/vite-plugin-picked
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
:::
|
|
30
|
-
|
|
31
|
-
## Setup
|
|
32
|
-
|
|
33
|
-
Add the plugin to your `vite.config.ts`:
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { defineConfig } from 'vite'
|
|
37
|
-
import { picked } from '@picked/vite-plugin-picked'
|
|
38
|
-
|
|
39
|
-
export default defineConfig({
|
|
40
|
-
plugins: [
|
|
41
|
-
picked({
|
|
42
|
-
projectId: 'your-project-id',
|
|
43
|
-
}),
|
|
44
|
-
],
|
|
45
|
-
})
|
|
46
|
-
```
|
|
47
|
-
|
|
48
14
|
## How it works
|
|
49
15
|
|
|
50
16
|
### Build-time config injection
|
|
51
17
|
|
|
52
18
|
When Vite starts, in both `dev` and `build`, the plugin does this:
|
|
53
19
|
|
|
54
|
-
1. It reads the
|
|
20
|
+
1. It reads the configuration of your project from the Picked API.
|
|
55
21
|
2. It embeds those options in your bundle.
|
|
56
|
-
3. The SDK reads the embedded
|
|
22
|
+
3. The SDK reads the embedded configuration at runtime and makes no network request.
|
|
57
23
|
|
|
58
|
-
When a preview token is there at runtime, the SDK ignores the embedded
|
|
24
|
+
When a preview token is there at runtime, the SDK ignores the embedded configuration and
|
|
59
25
|
reads fresh data from the API.
|
|
60
26
|
|
|
61
27
|
### Dev launcher
|
|
@@ -87,3 +53,7 @@ After the dev server starts, the launcher URL appears next to the Vite output:
|
|
|
87
53
|
For a production build, `vite build`, the plugin writes an `index.html` file that
|
|
88
54
|
holds the launcher page. Set `disableLauncher` to stop this. The file lets you deploy
|
|
89
55
|
the launcher next to your application, so that a stakeholder can see a preview.
|
|
56
|
+
|
|
57
|
+
## Related
|
|
58
|
+
|
|
59
|
+
- [How to install the Vite plugin](/how-to/install-the-vite-plugin)
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
+
type: tutorial
|
|
2
3
|
layout: docs
|
|
3
4
|
---
|
|
4
5
|
|
|
5
|
-
#
|
|
6
|
+
# Your first API call
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
In this tutorial we make your first calls to the Picked management API. We start with a
|
|
9
|
+
ping, then authenticate, then read your user and make an organization.
|
|
10
|
+
|
|
11
|
+
At the end you have an access token and two answers from the API.
|
|
12
|
+
|
|
13
|
+
## Before you start
|
|
14
|
+
|
|
15
|
+
- A Picked account, with an email address and a password.
|
|
16
|
+
- `curl`, or any HTTP client.
|
|
9
17
|
|
|
10
18
|
:::note
|
|
11
|
-
This
|
|
12
|
-
published
|
|
13
|
-
[Delivery API](/delivery-api)
|
|
19
|
+
This tutorial covers the GraphQL management API, which needs authentication. To serve
|
|
20
|
+
published configuration and page content to your application, use the read-only
|
|
21
|
+
[Delivery API](/reference/delivery-api) instead.
|
|
14
22
|
:::
|
|
15
23
|
|
|
16
24
|
## Playground
|
|
@@ -107,10 +115,10 @@ A successful response returns a `Session` with an `accessToken` and a
|
|
|
107
115
|
```
|
|
108
116
|
|
|
109
117
|
When `requiresMfa` is `true`, you must complete the MFA challenge before you receive
|
|
110
|
-
a session. See the [Authentication](
|
|
118
|
+
a session. See the [Authentication](/reference/management-api/authentication) guide.
|
|
111
119
|
|
|
112
120
|
For a server-to-server integration, use
|
|
113
|
-
[API key authentication](/api/authentication#api-key-authentication) and not a
|
|
121
|
+
[API key authentication](/reference/management-api/authentication#api-key-authentication) and not a
|
|
114
122
|
session token.
|
|
115
123
|
|
|
116
124
|
## Make an authenticated query
|
|
@@ -202,15 +210,19 @@ When something goes wrong, the API returns the errors in the standard GraphQL
|
|
|
202
210
|
```
|
|
203
211
|
|
|
204
212
|
Read the `extensions.code` field. It holds an error code that your code can act on.
|
|
205
|
-
See the [Errors](
|
|
213
|
+
See the [Errors](/reference/management-api/error-handling) guide for the full list of codes.
|
|
214
|
+
|
|
215
|
+
## What you built
|
|
206
216
|
|
|
207
|
-
|
|
217
|
+
You authenticated against the management API, read your own user, and created an
|
|
218
|
+
organization. Every other operation follows the same shape: a `POST` to one endpoint,
|
|
219
|
+
with your token in the `Authorization` header.
|
|
208
220
|
|
|
209
|
-
|
|
221
|
+
## Where to go next
|
|
210
222
|
|
|
211
|
-
- [Authentication](
|
|
223
|
+
- [Authentication](/reference/management-api/authentication) — an email address and a password, OAuth,
|
|
212
224
|
magic links, MFA, API keys, and how to control a session.
|
|
213
|
-
- [Authorization and Scopes](
|
|
225
|
+
- [Authorization and Scopes](/reference/management-api/authorization-and-scopes) — what each role can
|
|
214
226
|
reach, and how a scope controls a permission.
|
|
215
|
-
- [Pagination](
|
|
216
|
-
- [Errors](
|
|
227
|
+
- [Pagination](/reference/management-api/pagination) — how to move through a large result with a cursor.
|
|
228
|
+
- [Errors](/reference/management-api/error-handling) — every error code that the API can return.
|