@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
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Asset Library
|
|
8
|
-
|
|
9
|
-
The Asset Library holds the files that your content points at. These are images,
|
|
10
|
-
video, documents, and HTML.
|
|
11
|
-
|
|
12
|
-
<Screenshot
|
|
13
|
-
route="/{orgSlug}/{projectId}/assets"
|
|
14
|
-
alt="The asset library on the Picked dashboard"
|
|
15
|
-
/>
|
|
16
|
-
|
|
17
|
-
## Upload and control your assets
|
|
18
|
-
|
|
19
|
-
The Asset Library is a project-level store. Upload a file, then point at it from any
|
|
20
|
-
Content Entry in the project.
|
|
21
|
-
|
|
22
|
-
- **Size limit:** 50 MB for each file.
|
|
23
|
-
- **Allowed types:** an image in PNG, JPEG, WebP, AVIF, GIF, or SVG. A video in MP4
|
|
24
|
-
or WebM. A common document format. HTML, as `text/html`.
|
|
25
|
-
|
|
26
|
-
Picked rejects a file of another type. It also rejects a file above the size limit.
|
|
27
|
-
|
|
28
|
-
## Reference an asset from a field
|
|
29
|
-
|
|
30
|
-
Two field types point at an item in the library:
|
|
31
|
-
|
|
32
|
-
- An **Asset** field points at an image, a video, or a document.
|
|
33
|
-
- An **HTML asset** field takes a `.html` file from your library.
|
|
34
|
-
|
|
35
|
-
Add the field to a [layout](/content/layouts). Then choose an item from the library
|
|
36
|
-
when you fill in the [Content Entry](/content/content-entries).
|
|
37
|
-
|
|
38
|
-
## Pick an asset
|
|
39
|
-
|
|
40
|
-
Every Asset field opens the same picker. Click **Choose file** to open it. On a field
|
|
41
|
-
with a value already, click **Replace**. The modal has two tabs: **Library**, where
|
|
42
|
-
you browse the assets that are there, and **Upload**, where you add a new file.
|
|
43
|
-
|
|
44
|
-
<Screenshot
|
|
45
|
-
route="/{orgSlug}/{projectId}/design-systems/new"
|
|
46
|
-
wait='button:has-text("Upload file")'
|
|
47
|
-
click='button:has-text("Upload file")'
|
|
48
|
-
selector="[role=dialog]"
|
|
49
|
-
alt="The asset picker modal on the Picked dashboard, with the Library tab, its search box, its type filter, and its Sort by menu"
|
|
50
|
-
renderWidth={1072}
|
|
51
|
-
renderHeight={790}
|
|
52
|
-
/>
|
|
53
|
-
|
|
54
|
-
### Search, filter, and sort
|
|
55
|
-
|
|
56
|
-
The Library tab has three controls that make a large asset list smaller. The server
|
|
57
|
-
applies each one across the whole library, and not only across the assets that it
|
|
58
|
-
loaded already:
|
|
59
|
-
|
|
60
|
-
- **Search:** narrows the list by file name while you type.
|
|
61
|
-
- **Type filter:** narrows the list to one media type. The choices are All types,
|
|
62
|
-
Images, Video, Audio, Documents, and Archive files.
|
|
63
|
-
- **Sort by:** orders the list by the Name or by the Date uploaded, each one
|
|
64
|
-
ascending or descending.
|
|
65
|
-
|
|
66
|
-
:::note
|
|
67
|
-
The results come one page at a time. Click **Load more** at the bottom of the list to
|
|
68
|
-
read the next page.
|
|
69
|
-
:::
|
|
70
|
-
|
|
71
|
-
### Choose one asset or several
|
|
72
|
-
|
|
73
|
-
The picker changes with the number of assets that the field takes:
|
|
74
|
-
|
|
75
|
-
- A field that holds one asset shows a **radio** indicator next to each row. The
|
|
76
|
-
Asset field of a layout and the guidance file of a design system both do this. A
|
|
77
|
-
new choice replaces the current asset.
|
|
78
|
-
- A place that takes several assets at once shows a **checkbox** indicator. The
|
|
79
|
-
detail panel then also shows a count of what you chose. The Files tab of a
|
|
80
|
-
workbench does this.
|
|
81
|
-
|
|
82
|
-
The detail panel on the right shows the kind, the dimensions, the size, and the
|
|
83
|
-
upload date of the asset that you chose.
|
|
84
|
-
|
|
85
|
-
### Open an asset in a new tab
|
|
86
|
-
|
|
87
|
-
Each row has an **Open in new tab** control, and so does the detail panel of the
|
|
88
|
-
asset that you chose. It links to the full detail page of the asset, and your choice
|
|
89
|
-
in the picker stays as it is.
|
|
90
|
-
|
|
91
|
-
:::tip
|
|
92
|
-
Use this to check an asset again before you choose it. You can see the full-size
|
|
93
|
-
preview and every version that somebody uploaded.
|
|
94
|
-
:::
|
|
95
|
-
|
|
96
|
-
## HTML assets
|
|
97
|
-
|
|
98
|
-
Upload a `.html` file and point at it from an **HTML asset** field. Picked then scans
|
|
99
|
-
the file. The scan is advisory: it helps you, and it never stops you. It
|
|
100
|
-
reports findings about speed, about search rank, and about accessibility, so that you
|
|
101
|
-
can improve the file before you publish it:
|
|
102
|
-
|
|
103
|
-
- **File size:** a warning at 100 KB, and a stronger one at 250 KB.
|
|
104
|
-
- **Inline images:** a note when inline `base64` image data adds about 50 KB or more.
|
|
105
|
-
- **Image dimensions:** an image with no width and no height. Such an image can move
|
|
106
|
-
the content around it while the page loads.
|
|
107
|
-
- **Lazy load:** an image with no `loading="lazy"` attribute.
|
|
108
|
-
- **Link safety:** an external link with `target="_blank"` and no `rel="noopener"`.
|
|
109
|
-
- **Link search rank:** an external link with no `rel="nofollow"`.
|
|
110
|
-
- **Accessibility:** a pass by `axe-core`. It covers alt text, heading order,
|
|
111
|
-
contrast, and more.
|
|
112
|
-
|
|
113
|
-
Every finding is advisory. You can always upload the file as it is.
|
|
114
|
-
|
|
115
|
-
## How assets are served
|
|
116
|
-
|
|
117
|
-
Picked serves each asset from a sandboxed storage origin. That origin is separate
|
|
118
|
-
from the trusted origin of your application. HTML therefore comes from its own
|
|
119
|
-
origin, so a document that you upload runs in isolation and cannot reach the page
|
|
120
|
-
that holds it.
|
|
121
|
-
|
|
122
|
-
An [Experience Content](/delivery-api/experience-content) response can hold an HTML
|
|
123
|
-
asset. The response then carries the content of that asset, and the SDK renders it
|
|
124
|
-
with no second request to storage.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Pages
|
|
8
|
-
|
|
9
|
-
A Page is a standalone, server-rendered experience backed by CMS content, built for SEO-critical landing pages.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/experiences"
|
|
13
|
-
alt="The experiences list, where Pages and Flows are created on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## Pages and flows
|
|
17
|
-
|
|
18
|
-
Picked has two experience kinds:
|
|
19
|
-
|
|
20
|
-
| Experience | What it is | Use it for |
|
|
21
|
-
| --- | --- | --- |
|
|
22
|
-
| **Page** | A standalone experience that your server renders from a Content Entry. | A landing page or a campaign page where the search rank matters, and any content that a crawler must see. |
|
|
23
|
-
| **Flow** | An interactive experience of more than one step, which the browser renders. | A quiz, a survey, a product finder, and onboarding of more than one step. |
|
|
24
|
-
|
|
25
|
-
Choose a **Page** when the content must be in the HTML from your server, for a search
|
|
26
|
-
engine and for a social preview. Choose a **Flow** when the value is in the
|
|
27
|
-
interaction, and a browser render is acceptable. See
|
|
28
|
-
[Experiences](/experiences) for the wider picture.
|
|
29
|
-
|
|
30
|
-
## How a page fits together
|
|
31
|
-
|
|
32
|
-
Four pieces back every Page:
|
|
33
|
-
|
|
34
|
-
1. A **Page Layout** defines the shape: the fields a page can hold. See [Page & Step Layouts](/content/layouts).
|
|
35
|
-
2. A **Content Entry** fills that shape with real data. See [Content Entries](/content/content-entries).
|
|
36
|
-
3. A **Page** binds one entry so the SDK can render it.
|
|
37
|
-
4. The **SDK** fetches the entry and renders it on your server. See [Server-Side Rendering](/sdk/ssr).
|
|
38
|
-
|
|
39
|
-
A layout defines the shape, a content entry fills it with data, a Page binds an entry so the SDK can render it. Step Layouts do the same for individual Steps inside a Flow.
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
Author (dashboard) -> Publish -> Delivery API (config + content)
|
|
43
|
-
-> serialize() on server -> Provider seeds client -> ExperienceSlot renders -> hydrate
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Create a page
|
|
47
|
-
|
|
48
|
-
1. Open your project.
|
|
49
|
-
2. Choose a workspace.
|
|
50
|
-
3. Click **Experiences** in the sidebar.
|
|
51
|
-
4. Click **New Experience**.
|
|
52
|
-
5. Choose the **Page** type.
|
|
53
|
-
6. Choose a **Page Layout**. The layout sets which fields the page holds.
|
|
54
|
-
7. Click **Create**.
|
|
55
|
-
|
|
56
|
-
A Content Entry is created and linked to the page on its first save, so the page always has somewhere to store its data.
|
|
57
|
-
|
|
58
|
-
## Edit page content
|
|
59
|
-
|
|
60
|
-
The Page editor has two tabs. The **Properties** tab holds the content of the page.
|
|
61
|
-
The **Settings** tab holds its name, its condition, and its layout. Fill in the
|
|
62
|
-
fields on the **Properties** tab. The inspector on the right edits the field that you
|
|
63
|
-
choose, and the preview panel shows the page while it fills in.
|
|
64
|
-
|
|
65
|
-
## Change or remove the layout
|
|
66
|
-
|
|
67
|
-
Use the change-layout control on the **Settings** tab to move the page to another
|
|
68
|
-
Page Layout. When you unlink a layout, Picked separates the Content Entry from the
|
|
69
|
-
page. It deletes no entry, but the page then has no content to render until you
|
|
70
|
-
attach a layout again.
|
|
71
|
-
|
|
72
|
-
## Validate and publish
|
|
73
|
-
|
|
74
|
-
An invalid field shows an error next to it while you edit, so that you can correct it
|
|
75
|
-
before you publish. When the page is valid, publish the workspace to make it live.
|
|
76
|
-
That makes the version that the Delivery API serves to an anonymous reader.
|
|
77
|
-
|
|
78
|
-
## Render a page
|
|
79
|
-
|
|
80
|
-
The SDK renders a published Page on your server. See the
|
|
81
|
-
[Build a Personalized Page](/guides/build-a-personalized-page) guide for the full
|
|
82
|
-
steps, and [Server-Side Rendering](/sdk/ssr) for the SDK reference.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Sections
|
|
8
|
-
|
|
9
|
-
Sections are reusable schema fragments you embed inside layouts, so common structures such as a hero or a feature list are defined once.
|
|
10
|
-
|
|
11
|
-
<Screenshot
|
|
12
|
-
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/blocks"
|
|
13
|
-
alt="The sections list in the schema builder on the Picked dashboard"
|
|
14
|
-
/>
|
|
15
|
-
|
|
16
|
-
## What a section is
|
|
17
|
-
|
|
18
|
-
A Section is a reusable schema fragment with its own **Key**. A
|
|
19
|
-
[layout](/content/layouts) gives its shape to a whole Page or Step. A Section is a
|
|
20
|
-
part that you put into one or more layouts. Define the shape one time, then reuse it
|
|
21
|
-
everywhere.
|
|
22
|
-
|
|
23
|
-
## Create a section
|
|
24
|
-
|
|
25
|
-
1. Open your workspace.
|
|
26
|
-
2. Click **Sections** in the sidebar.
|
|
27
|
-
3. Click **New Section**.
|
|
28
|
-
4. Enter a name and a **Key**. The Key is a unique, stable identifier. Your SDK code
|
|
29
|
-
and your API calls both use it.
|
|
30
|
-
5. Add your fields.
|
|
31
|
-
6. Save.
|
|
32
|
-
|
|
33
|
-
## Use a section in a layout
|
|
34
|
-
|
|
35
|
-
Add a **Section** field to a Page Layout or a Step Layout. Point that field at the
|
|
36
|
-
Section that you want. The layout then carries the fields of the Section at every
|
|
37
|
-
place where that field appears. A Content Entry from the layout fills in the fields
|
|
38
|
-
of the Section in the same way as every other field.
|
|
39
|
-
|
|
40
|
-
## Change a section
|
|
41
|
-
|
|
42
|
-
An edit to a Section does not migrate the entries that use it. After you change a
|
|
43
|
-
Section, check each affected [Content Entry](/content/content-entries) again. Correct
|
|
44
|
-
every field error before you publish.
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Delivery API
|
|
6
|
-
|
|
7
|
-
The Delivery API is a public REST API. It is read-only, and it serves the published
|
|
8
|
-
options of your project together with your page content. It is separate from the
|
|
9
|
-
GraphQL management API.
|
|
10
|
-
|
|
11
|
-
## The Delivery API and the management API
|
|
12
|
-
|
|
13
|
-
Picked has two HTTP APIs. Use the one that fits your work:
|
|
14
|
-
|
|
15
|
-
| | Delivery API | Management API |
|
|
16
|
-
| --- | --- | --- |
|
|
17
|
-
| Style | REST | GraphQL |
|
|
18
|
-
| Access | Public, anonymous | Authenticated |
|
|
19
|
-
| Operations | Read-only | Read and write |
|
|
20
|
-
| Use it to | Serve published options and content to your application | Control your projects, experiences, and content |
|
|
21
|
-
|
|
22
|
-
The [API Reference](/api) covers the management API. This section covers the Delivery
|
|
23
|
-
API.
|
|
24
|
-
|
|
25
|
-
## Base URL and versioning
|
|
26
|
-
|
|
27
|
-
All Delivery API routes are versioned under `/api/v1`:
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
https://api.picked.app/api/v1
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Published content and preview content
|
|
34
|
-
|
|
35
|
-
Each endpoint serves two surfaces:
|
|
36
|
-
|
|
37
|
-
- **Published** content is anonymous. Anybody can read your published options and
|
|
38
|
-
your published content.
|
|
39
|
-
- **Preview** content needs a `preview_token` query parameter. With it you can render
|
|
40
|
-
an unpublished draft before you make it live.
|
|
41
|
-
|
|
42
|
-
The management API holds the preview token of a workspace in the `previewToken`
|
|
43
|
-
field. The preview action in the dashboard also makes one for you.
|
|
44
|
-
|
|
45
|
-
## Endpoints
|
|
46
|
-
|
|
47
|
-
| Endpoint | Description |
|
|
48
|
-
| --- | --- |
|
|
49
|
-
| [Project Config](/delivery-api/project-config) | `GET /api/v1/projects/:projectId` returns the published options of the project, with the content link of each step. |
|
|
50
|
-
| [Experience Content](/delivery-api/experience-content) | `GET /api/v1/projects/:projectId/experiences/:id/content` returns the Content Entries of an experience. |
|
|
51
|
-
|
|
52
|
-
Both endpoints share some behaviour. See
|
|
53
|
-
[Preview, cache, and crawlers](/delivery-api/preview-caching-crawling).
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Build a Personalized Page
|
|
8
|
-
|
|
9
|
-
Build a personalized landing page with Picked: model it in the dashboard, publish it, and render it server-side in your app.
|
|
10
|
-
|
|
11
|
-
## What you will build
|
|
12
|
-
|
|
13
|
-
A standalone landing page where the search rank matters. Its content lives in the
|
|
14
|
-
Picked CMS, and your server renders it. You describe the shape of the page one time,
|
|
15
|
-
fill it with content, and publish it. Your server then reads it and renders it in
|
|
16
|
-
React or in Svelte. These are the stages, from the first draft to a hydrated page:
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
Author (dashboard) -> Publish -> Delivery API (config + content)
|
|
20
|
-
-> serialize() on server -> Provider seeds client -> ExperienceSlot renders -> hydrate
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Model a page layout
|
|
24
|
-
|
|
25
|
-
A [Page Layout](/content/layouts) defines the fields your page can hold.
|
|
26
|
-
|
|
27
|
-
1. Open your workspace.
|
|
28
|
-
2. Click **Models** in the sidebar.
|
|
29
|
-
3. Click **New Model**.
|
|
30
|
-
4. Choose **Page Layout**.
|
|
31
|
-
5. Enter a name and a **Key**, for example `page-hero`. The Key is a unique, stable
|
|
32
|
-
identifier. Your SDK code and your API calls both use it.
|
|
33
|
-
6. Add three fields: a **Single-line text** field `title`, a **Markdown** field
|
|
34
|
-
`body`, and an **Asset** field `image`.
|
|
35
|
-
7. Save the layout.
|
|
36
|
-
|
|
37
|
-
<Screenshot
|
|
38
|
-
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/models"
|
|
39
|
-
alt="A page layout in the schema builder on the Picked dashboard"
|
|
40
|
-
/>
|
|
41
|
-
|
|
42
|
-
See [Page & Step Layouts](/content/layouts) for every field type.
|
|
43
|
-
|
|
44
|
-
## Create and fill the page
|
|
45
|
-
|
|
46
|
-
1. Click **Experiences** in the sidebar.
|
|
47
|
-
2. Click **New Experience**.
|
|
48
|
-
3. Choose the **Page** type.
|
|
49
|
-
4. Choose your `page-hero` layout.
|
|
50
|
-
5. On the **Properties** tab, fill in `title`, `body`, and `image`. On the first save,
|
|
51
|
-
Picked creates a [Content Entry](/content/content-entries) and links it to the
|
|
52
|
-
page.
|
|
53
|
-
6. Correct every field error.
|
|
54
|
-
7. Publish the workspace to make the page live.
|
|
55
|
-
|
|
56
|
-
See [Pages](/content/pages) for the full editor reference.
|
|
57
|
-
|
|
58
|
-
## Fetch the config and content
|
|
59
|
-
|
|
60
|
-
Your server reads two things from the [Delivery API](/delivery-api). The first is the
|
|
61
|
-
options of the project, which give the experiences and the steps. The second is the
|
|
62
|
-
content of the experience that matches.
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
# 1. The project options: find the steps and their content links.
|
|
66
|
-
curl https://api.picked.app/api/v1/projects/proj_123
|
|
67
|
-
|
|
68
|
-
# 2. The experience content: the entry data of the page.
|
|
69
|
-
curl https://api.picked.app/api/v1/projects/proj_123/experiences/exp_123/content
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
In practice you fetch the config, then let `serialize()` fetch the content for you. See [Project Config](/delivery-api/project-config) and [Experience Content](/delivery-api/experience-content).
|
|
73
|
-
|
|
74
|
-
## Render server-side and hydrate
|
|
75
|
-
|
|
76
|
-
On the server, create a per-request client, call `serialize()` to produce a snapshot, render your app, and embed the snapshot. On the client, seed from the snapshot and hydrate.
|
|
77
|
-
|
|
78
|
-
```ts
|
|
79
|
-
// `server.ts`
|
|
80
|
-
import { createClient } from '@picked/client'
|
|
81
|
-
import { serialize } from '@picked/client/server'
|
|
82
|
-
|
|
83
|
-
const client = createClient(options)
|
|
84
|
-
const snapshot = await serialize(client, {
|
|
85
|
-
projectConfig,
|
|
86
|
-
attributes: { location: { pathname: url.pathname } },
|
|
87
|
-
})
|
|
88
|
-
// Render your app, then embed `snapshot` in the HTML response.
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Render `<ExperienceSlot name="page" />` inside the provider, and register the component the Page maps to (here, `CMSPage`):
|
|
92
|
-
|
|
93
|
-
:::code-group
|
|
94
|
-
|
|
95
|
-
```tsx [React]
|
|
96
|
-
import type { CreateClientOptions } from '@picked/client'
|
|
97
|
-
import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
|
|
98
|
-
import { adaptReactComponent, ExperienceSlot, PickedProvider } from '@picked/react'
|
|
99
|
-
import { reactFrameworkPlugin } from '@picked/react/plugins/framework'
|
|
100
|
-
import { useStepContent } from '@picked/react/hooks'
|
|
101
|
-
|
|
102
|
-
function CMSPage() {
|
|
103
|
-
const content = useStepContent()
|
|
104
|
-
const title = typeof content?.title === 'string' ? content.title : ''
|
|
105
|
-
return <h1>{title}</h1>
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const options = {
|
|
109
|
-
projectId: 'proj_123',
|
|
110
|
-
components: { CMSPage: adaptReactComponent(CMSPage) },
|
|
111
|
-
plugins: [reactFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
|
|
112
|
-
} satisfies CreateClientOptions
|
|
113
|
-
|
|
114
|
-
export function Page({ snapshot }) {
|
|
115
|
-
return (
|
|
116
|
-
<PickedProvider options={options} snapshot={snapshot}>
|
|
117
|
-
<ExperienceSlot name="page" />
|
|
118
|
-
</PickedProvider>
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
```svelte [Svelte]
|
|
124
|
-
<script lang="ts">
|
|
125
|
-
import type { CreateClientOptions } from '@picked/client'
|
|
126
|
-
import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
|
|
127
|
-
import { adaptSvelteComponent, ExperienceSlot, setPickedContext } from '@picked/svelte'
|
|
128
|
-
import { svelteFrameworkPlugin } from '@picked/svelte/plugins/framework'
|
|
129
|
-
import CMSPage from './CMSPage.svelte'
|
|
130
|
-
|
|
131
|
-
const { snapshot } = $props()
|
|
132
|
-
|
|
133
|
-
const options = {
|
|
134
|
-
projectId: 'proj_123',
|
|
135
|
-
components: { CMSPage: adaptSvelteComponent(CMSPage) },
|
|
136
|
-
plugins: [svelteFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
|
|
137
|
-
} satisfies CreateClientOptions
|
|
138
|
-
|
|
139
|
-
setPickedContext({ options, snapshot })
|
|
140
|
-
</script>
|
|
141
|
-
|
|
142
|
-
<ExperienceSlot name="page" />
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
:::
|
|
146
|
-
|
|
147
|
-
The provider seeds synchronously, so the server HTML and the client's first paint match, then the SDK hydrates. See [Server-Side Rendering](/sdk/ssr) for the full reference.
|
|
148
|
-
|
|
149
|
-
## Verify SEO
|
|
150
|
-
|
|
151
|
-
Confirm the page is crawlable end to end:
|
|
152
|
-
|
|
153
|
-
1. Read the response from your server. Use `curl`, or the view-source command of
|
|
154
|
-
your browser.
|
|
155
|
-
2. Check that the HTML holds your `title` and your `body`, and that it is not an
|
|
156
|
-
empty shell.
|
|
157
|
-
3. Check that the content endpoint answers an anonymous request.
|
|
158
|
-
4. Check that it returns your entry data.
|
|
159
|
-
|
|
160
|
-
A crawler can read a published Delivery API response. A preview URL is disallowed.
|
|
161
|
-
See [Preview, cache, and crawlers](/delivery-api/preview-caching-crawling).
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# PickedQL
|
|
6
|
-
|
|
7
|
-
PickedQL is a SQL query language for your Picked analytics data. Write short SQL with
|
|
8
|
-
a virtual table and a virtual function. PickedQL expands them into a full query, and
|
|
9
|
-
it adds the joins and the A/B test aggregations for you.
|
|
10
|
-
|
|
11
|
-
## Quick start
|
|
12
|
-
|
|
13
|
-
```sql
|
|
14
|
-
-- How many users are in the control group, and how many in the variant group?
|
|
15
|
-
SELECT control_users(), variant_users()
|
|
16
|
-
FROM metrics
|
|
17
|
-
WHERE project_id = 'your-project-id'
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
PickedQL maps each table and adds each dimension join for you. You write short SQL
|
|
21
|
-
that a person can read, and PickedQL does the rest.
|
|
22
|
-
|
|
23
|
-
## How PickedQL works
|
|
24
|
-
|
|
25
|
-
1. **Virtual table expansion**: a table name such as `metrics` maps to the data
|
|
26
|
-
tables below it.
|
|
27
|
-
2. **Virtual function expansion**: a short function such as `control_users()` expands
|
|
28
|
-
to a full aggregate expression.
|
|
29
|
-
3. **Automatic dimension joins**: PickedQL adds a `LEFT JOIN` when you point at a
|
|
30
|
-
dimension column, such as `device_category` or `country_code`. You write no join.
|
|
31
|
-
4. **Tenant isolation**: every query must hold a tenant filter in the `WHERE` clause.
|
|
32
|
-
That filter is `project_id` for most tables. The `projects` table uses `id`
|
|
33
|
-
instead, because the `id` of the row is the project ID. PickedQL reads the filter
|
|
34
|
-
and checks that you have permission for that project.
|
|
35
|
-
5. **SQL passthrough**: standard SQL works next to a virtual function. This includes
|
|
36
|
-
`CASE WHEN`, a window function, and a subquery.
|
|
37
|
-
|
|
38
|
-
## Best practices
|
|
39
|
-
|
|
40
|
-
- **Use `metrics` for a dashboard**: data that PickedQL aggregates first is much
|
|
41
|
-
faster than raw events for a standard report.
|
|
42
|
-
- **Use `events` to go deeper**: raw event data lets you build any breakdown or
|
|
43
|
-
funnel that you want.
|
|
44
|
-
- **Use `experience_journey` for a sankey chart or a funnel chart**: one line of SQL
|
|
45
|
-
returns `source, target, users`. PickedQL builds the eight common table expressions
|
|
46
|
-
for you. Those remove the duplicates, rank the top paths, and call `lagInFrame`.
|
|
47
|
-
Pass your parameters in the `WHERE` clause.
|
|
48
|
-
- **Write no JOIN**: PickedQL adds each one when you point at a dimension column.
|
|
49
|
-
- **Group by any dimension**: add a dimension column to `SELECT` and to `GROUP BY`.
|
|
50
|
-
PickedQL adds the join that it needs.
|
|
51
|
-
- **Read the reference tables for no cost**: use `step_title`, `experience_title`, and
|
|
52
|
-
`project_name` directly in an `events` query. PickedQL joins the `steps`,
|
|
53
|
-
`experiences`, and `projects` reference tables for you.
|
|
54
|
-
|
package/dist/docs/projects.mdx
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Projects
|
|
8
|
-
|
|
9
|
-
A project is one site or one application that you want to measure with Picked. Each
|
|
10
|
-
project has its own experiences, entities, and options.
|
|
11
|
-
|
|
12
|
-
<Screenshot
|
|
13
|
-
route="/{orgSlug}"
|
|
14
|
-
alt="The organization home page on the Picked dashboard, with the projects in an organization"
|
|
15
|
-
/>
|
|
16
|
-
|
|
17
|
-
## Create a project
|
|
18
|
-
|
|
19
|
-
You need an organization first. If you do not have one, create it when you sign up.
|
|
20
|
-
|
|
21
|
-
1. Open your organization.
|
|
22
|
-
2. Click **New Project**.
|
|
23
|
-
3. Enter a name.
|
|
24
|
-
4. Click **Create**.
|
|
25
|
-
|
|
26
|
-
## Workspaces
|
|
27
|
-
|
|
28
|
-
Each project holds one or more [Workspaces](/workspaces). In a workspace you set the
|
|
29
|
-
options for an experience and you see a preview of it before you make it live.
|
|
30
|
-
|
|
31
|
-
## Project home
|
|
32
|
-
|
|
33
|
-
When you open a project, you land on the project home page. It shows your SDK
|
|
34
|
-
snippet and a list of the setup tasks that are still open.
|
|
35
|
-
|
|
36
|
-
Copy the snippet and add it to your site. The snippet connects your site to the
|
|
37
|
-
project and lets Picked serve experiences to it. See
|
|
38
|
-
[SDK Installation](/sdk) for the setup detail.
|
|
39
|
-
|
|
40
|
-
## Project navigation
|
|
41
|
-
|
|
42
|
-
The sidebar shows every section of your project: **Experiences**, **Fields**,
|
|
43
|
-
**Steps**, **Actions**, **Conditions**, and more. Some sections appear only when your
|
|
44
|
-
account has them.
|
package/dist/docs/reports.mdx
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
import { Screenshot } from '../../components/Screenshot'
|
|
6
|
-
|
|
7
|
-
# Reports
|
|
8
|
-
|
|
9
|
-
A report shows analytics data for your project. Use a report to track how your
|
|
10
|
-
visitors use your experiences and feature flags.
|
|
11
|
-
|
|
12
|
-
<Screenshot
|
|
13
|
-
route="/{orgSlug}/{projectId}/reports"
|
|
14
|
-
alt="The reports list for a project on the Picked dashboard"
|
|
15
|
-
/>
|
|
16
|
-
|
|
17
|
-
## See report data
|
|
18
|
-
|
|
19
|
-
Open a report to see its analytics. The data updates when Picked records a new
|
|
20
|
-
visitor interaction.
|
package/dist/docs/sdk/actions.md
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
layout: docs
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Actions
|
|
6
|
-
|
|
7
|
-
Register an action handler on the Picked client. The SDK then invokes the handler
|
|
8
|
-
when an experience flow reaches an action node.
|
|
9
|
-
|
|
10
|
-
## Register an action
|
|
11
|
-
|
|
12
|
-
Register your actions when you create the Picked client. Each key in the `actions`
|
|
13
|
-
object must match an action key from the dashboard:
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { createClient } from '@picked/client'
|
|
17
|
-
|
|
18
|
-
const picked = createClient({
|
|
19
|
-
projectId: 'your-project-id',
|
|
20
|
-
actions: {
|
|
21
|
-
'track-signup': () => {
|
|
22
|
-
analytics.track('signup_completed')
|
|
23
|
-
},
|
|
24
|
-
'notify': (params) => {
|
|
25
|
-
sendNotification(params)
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Each action is a function. It takes optional parameters and it usually runs a side
|
|
32
|
-
effect. When the flow reaches an action node, the SDK calls the function that
|
|
33
|
-
matches. The SDK then takes a branch, which depends on whether the function succeeds
|
|
34
|
-
or throws. See [Success and failure branches](#success-and-failure-branches).
|
|
35
|
-
|
|
36
|
-
## How actions work
|
|
37
|
-
|
|
38
|
-
1. **Registration**: you register each action on the Picked client at startup.
|
|
39
|
-
2. **Flow traversal**: the SDK walks the experience flow. When it reaches an action
|
|
40
|
-
node, it finds the action by its key.
|
|
41
|
-
3. **Execution**: the SDK calls the function that matches and awaits it. The outcome
|
|
42
|
-
then decides which node comes next.
|
|
43
|
-
4. **No block**: an action does not interrupt your visitor. The current step
|
|
44
|
-
stays on the screen while an async action runs.
|
|
45
|
-
|
|
46
|
-
## Success and failure branches
|
|
47
|
-
|
|
48
|
-
An action node can have a **success** branch and a **failure** branch. The SDK
|
|
49
|
-
chooses the branch from the outcome of the action:
|
|
50
|
-
|
|
51
|
-
- **Failure** — the action throws, or its promise rejects. The flow takes the failure
|
|
52
|
-
branch, `onFail`.
|
|
53
|
-
- **Success** — the action resolves to any value: `void`, `true`, `false`, or a
|
|
54
|
-
string. A resolved `false` is a valid response and not a failure. The flow takes
|
|
55
|
-
the success branch, `onSuccess`.
|
|
56
|
-
|
|
57
|
-
Keep the failure branch for a true error. Throw on the failure case, because a
|
|
58
|
-
returned value never takes the `onFail` branch:
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
'check-eligibility': async () => {
|
|
62
|
-
const response = await fetch('/api/eligibility')
|
|
63
|
-
// Throw only when the request itself fails. That takes the failure branch.
|
|
64
|
-
if (!response.ok) throw new Error('Eligibility request failed')
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
A valid negative result is not a failure. An API can return `200` with a "no", for
|
|
69
|
-
example `{ serviced: false }`. Record that value as a response and branch on it with
|
|
70
|
-
a condition. Do not throw:
|
|
71
|
-
|
|
72
|
-
```ts
|
|
73
|
-
'check-serviced-area': async ({ client, responses }) => {
|
|
74
|
-
const postcode = responses.find((r) => r.fieldKey === 'postcode')?.value
|
|
75
|
-
const { serviced } = await fetch(`/api/serviced?postcode=${postcode}`).then((r) => r.json())
|
|
76
|
-
// Store the outcome as a response. A later condition then takes the branch.
|
|
77
|
-
client.responses.register('is-serviced', serviced)
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
An action node can also have one plain connection, with no success or failure branch.
|
|
82
|
-
The flow then continues through it on either outcome.
|