@picked/client 0.0.101-next.1 → 0.0.101-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +34 -158
  2. package/dist/{api-DThEBKPu.cjs → api-9o_emCM5.cjs} +1 -1
  3. package/dist/{api-DcXndm41.js → api-BbQt8aW3.js} +1 -1
  4. package/dist/cjs/index.js +2 -2
  5. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  6. package/dist/cjs/server/index.js +1 -1
  7. package/dist/esm/index.js +2 -2
  8. package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
  9. package/dist/esm/server/index.js +2 -2
  10. package/dist/{plugin-DA34qpbe.cjs → plugin-I8_6ncy_.cjs} +1 -1
  11. package/dist/{plugin-BZPx7WhX.js → plugin-uZJ45vK6.js} +2 -2
  12. package/dist/{preview-unavailable-sDBBJFrE.cjs → preview-unavailable-BUNxTYLe.cjs} +1 -1
  13. package/dist/{preview-unavailable-Bg8UuQeR.js → preview-unavailable-BYFD2a58.js} +1 -1
  14. package/dist/{provider-BkN7A93w.cjs → provider-Bzi_Kb-n.cjs} +1 -1
  15. package/dist/{provider-DRNHPacW.js → provider-CQKp0iUJ.js} +1 -1
  16. package/package.json +5 -5
  17. package/dist/docs/_root.css +0 -101
  18. package/dist/docs/explanation/conditions-and-the-logic-engine.md +0 -94
  19. package/dist/docs/explanation/content-references.md +0 -99
  20. package/dist/docs/explanation/feature-flag-allocation.md +0 -218
  21. package/dist/docs/explanation/how-picked-works.md +0 -124
  22. package/dist/docs/explanation/how-pickedql-works.md +0 -76
  23. package/dist/docs/explanation/pages-and-flows.md +0 -64
  24. package/dist/docs/explanation/the-content-model.md +0 -87
  25. package/dist/docs/explanation/the-two-apis.md +0 -68
  26. package/dist/docs/explanation/why-server-side-rendering.md +0 -76
  27. package/dist/docs/explanation/workspaces-and-versions.md +0 -71
  28. package/dist/docs/how-to/add-a-step-field-or-action.md +0 -43
  29. package/dist/docs/how-to/analytics/index.md +0 -316
  30. package/dist/docs/how-to/archive-or-delete-a-workspace.md +0 -46
  31. package/dist/docs/how-to/authenticate-the-cli.md +0 -101
  32. package/dist/docs/how-to/authenticate-with-a-magic-link.md +0 -47
  33. package/dist/docs/how-to/authenticate-with-a-password.md +0 -59
  34. package/dist/docs/how-to/authenticate-with-an-api-key.md +0 -51
  35. package/dist/docs/how-to/authenticate-with-oauth.md +0 -40
  36. package/dist/docs/how-to/build-a-flow.md +0 -93
  37. package/dist/docs/how-to/call-an-external-api-from-a-workflow.md +0 -102
  38. package/dist/docs/how-to/connect-the-mcp-server.md +0 -46
  39. package/dist/docs/how-to/create-a-content-entry.md +0 -48
  40. package/dist/docs/how-to/create-a-project.md +0 -29
  41. package/dist/docs/how-to/create-an-experience.md +0 -42
  42. package/dist/docs/how-to/create-and-revoke-an-api-key.md +0 -42
  43. package/dist/docs/how-to/debug-with-the-chrome-extension.md +0 -57
  44. package/dist/docs/how-to/define-a-page-layout.md +0 -46
  45. package/dist/docs/how-to/fill-and-publish-a-page.md +0 -66
  46. package/dist/docs/how-to/install-the-gtm-template.md +0 -84
  47. package/dist/docs/how-to/install-the-sdk.md +0 -93
  48. package/dist/docs/how-to/install-the-vite-plugin.md +0 -69
  49. package/dist/docs/how-to/invite-and-remove-members.md +0 -35
  50. package/dist/docs/how-to/point-one-entry-at-another.md +0 -61
  51. package/dist/docs/how-to/preview-a-workspace.md +0 -28
  52. package/dist/docs/how-to/publish-a-workspace.md +0 -30
  53. package/dist/docs/how-to/read-a-feature-flag.md +0 -113
  54. package/dist/docs/how-to/read-a-referenced-entry.md +0 -109
  55. package/dist/docs/how-to/register-a-component.md +0 -55
  56. package/dist/docs/how-to/register-an-action-handler.md +0 -85
  57. package/dist/docs/how-to/register-an-api-that-uses-oauth2.md +0 -107
  58. package/dist/docs/how-to/render-a-step-form.md +0 -131
  59. package/dist/docs/how-to/render-an-unpublished-preview.md +0 -41
  60. package/dist/docs/how-to/retry-a-failed-call-with-a-loop.md +0 -81
  61. package/dist/docs/how-to/reuse-a-section.md +0 -53
  62. package/dist/docs/how-to/reuse-a-step-field-or-action.md +0 -28
  63. package/dist/docs/how-to/roll-back-a-published-version.md +0 -26
  64. package/dist/docs/how-to/run-an-ab-test.md +0 -49
  65. package/dist/docs/how-to/run-code-on-a-form-submission.md +0 -125
  66. package/dist/docs/how-to/server-render-a-page.md +0 -81
  67. package/dist/docs/how-to/set-a-content-security-policy.md +0 -32
  68. package/dist/docs/how-to/set-up-mfa.md +0 -113
  69. package/dist/docs/how-to/switch-workspaces.md +0 -122
  70. package/dist/docs/how-to/upload-and-use-an-asset.mdx +0 -73
  71. package/dist/docs/how-to/validate-a-field.md +0 -52
  72. package/dist/docs/how-to/wait-for-an-action-response.md +0 -182
  73. package/dist/docs/how-to/write-a-condition.md +0 -45
  74. package/dist/docs/how-to/write-a-predicate.md +0 -60
  75. package/dist/docs/index.md +0 -59
  76. package/dist/docs/reference/dashboard/actions.mdx +0 -56
  77. package/dist/docs/reference/dashboard/api-keys.mdx +0 -38
  78. package/dist/docs/reference/dashboard/conditions.mdx +0 -42
  79. package/dist/docs/reference/dashboard/content/asset-library.mdx +0 -63
  80. package/dist/docs/reference/dashboard/content/blocks.mdx +0 -57
  81. package/dist/docs/reference/dashboard/content/content-entries.mdx +0 -95
  82. package/dist/docs/reference/dashboard/content/models.mdx +0 -108
  83. package/dist/docs/reference/dashboard/content/pages.mdx +0 -61
  84. package/dist/docs/reference/dashboard/experiences.mdx +0 -51
  85. package/dist/docs/reference/dashboard/external-apis.md +0 -169
  86. package/dist/docs/reference/dashboard/features.mdx +0 -154
  87. package/dist/docs/reference/dashboard/fields.mdx +0 -106
  88. package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +0 -58
  89. package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +0 -57
  90. package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +0 -72
  91. package/dist/docs/reference/dashboard/flow-builder/nodes.md +0 -63
  92. package/dist/docs/reference/dashboard/labels.md +0 -321
  93. package/dist/docs/reference/dashboard/lead-search.md +0 -224
  94. package/dist/docs/reference/dashboard/projects.mdx +0 -44
  95. package/dist/docs/reference/dashboard/reports.mdx +0 -43
  96. package/dist/docs/reference/dashboard/steps.mdx +0 -37
  97. package/dist/docs/reference/dashboard/team-management.md +0 -29
  98. package/dist/docs/reference/dashboard/workflow-runs.md +0 -142
  99. package/dist/docs/reference/dashboard/workflow-templates.md +0 -182
  100. package/dist/docs/reference/dashboard/workflow-test-runs.md +0 -77
  101. package/dist/docs/reference/dashboard/workspace-versioning.mdx +0 -30
  102. package/dist/docs/reference/dashboard/workspaces.mdx +0 -76
  103. package/dist/docs/reference/delivery-api/experience-content.md +0 -152
  104. package/dist/docs/reference/delivery-api/index.md +0 -45
  105. package/dist/docs/reference/delivery-api/preview-caching-crawling.md +0 -79
  106. package/dist/docs/reference/delivery-api/project-config.md +0 -65
  107. package/dist/docs/reference/delivery-api/workspace-schema.md +0 -107
  108. package/dist/docs/reference/glossary.md +0 -201
  109. package/dist/docs/reference/management-api/authentication.md +0 -87
  110. package/dist/docs/reference/management-api/authorization-and-scopes.md +0 -291
  111. package/dist/docs/reference/management-api/error-handling.md +0 -232
  112. package/dist/docs/reference/management-api/pagination.md +0 -192
  113. package/dist/docs/reference/pickedql/data-sources.md +0 -174
  114. package/dist/docs/reference/pickedql/dimensions.md +0 -103
  115. package/dist/docs/reference/pickedql/filtering.md +0 -64
  116. package/dist/docs/reference/pickedql/index.md +0 -18
  117. package/dist/docs/reference/pickedql/schema.md +0 -172
  118. package/dist/docs/reference/pickedql/virtual-functions.md +0 -248
  119. package/dist/docs/reference/sdk/actions.md +0 -154
  120. package/dist/docs/reference/sdk/analytics-events.md +0 -453
  121. package/dist/docs/reference/sdk/conditions.md +0 -147
  122. package/dist/docs/reference/sdk/content-security-policy.md +0 -21
  123. package/dist/docs/reference/sdk/content.md +0 -253
  124. package/dist/docs/reference/sdk/experiences.md +0 -51
  125. package/dist/docs/reference/sdk/features.md +0 -256
  126. package/dist/docs/reference/sdk/fields.md +0 -255
  127. package/dist/docs/reference/sdk/index.md +0 -68
  128. package/dist/docs/reference/sdk/plugins/create-experience.md +0 -123
  129. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +0 -74
  130. package/dist/docs/reference/sdk/plugins/index.md +0 -29
  131. package/dist/docs/reference/sdk/plugins/window-object.md +0 -25
  132. package/dist/docs/reference/sdk/predicates.md +0 -43
  133. package/dist/docs/reference/sdk/ssr/index.md +0 -33
  134. package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +0 -103
  135. package/dist/docs/reference/sdk/ssr/serialize.md +0 -80
  136. package/dist/docs/reference/sdk/ssr/slots-and-placements.md +0 -113
  137. package/dist/docs/reference/sdk/steps.md +0 -86
  138. package/dist/docs/reference/sdk/type-generation.md +0 -265
  139. package/dist/docs/reference/tools/chrome-extension.md +0 -16
  140. package/dist/docs/reference/tools/cli.md +0 -292
  141. package/dist/docs/reference/tools/image-optimisation-service.md +0 -104
  142. package/dist/docs/reference/tools/mcp.md +0 -136
  143. package/dist/docs/reference/tools/vite-plugin.md +0 -163
  144. package/dist/docs/tutorials/first-api-call.md +0 -235
  145. package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +0 -143
  146. package/dist/docs/tutorials/first-experience.mdx +0 -254
  147. package/dist/docs/tutorials/first-server-rendered-page.mdx +0 -186
@@ -1,93 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to install the SDK
7
-
8
- This guide shows you how to add the Picked client to a web application. You need a project
9
- ID from the dashboard.
10
-
11
- ## 1. Install the packages
12
-
13
- :::code-group
14
-
15
- ```bash [React]
16
- npm install picked @picked/react
17
- ```
18
-
19
- ```bash [Svelte]
20
- npm install picked @picked/svelte
21
- ```
22
-
23
- :::
24
-
25
- `picked` gives you the client, the `picked.config` helpers, and the `picked` command. Your
26
- package manager adds `@picked/client` with it, which carries the runtime and holds the
27
- generated types.
28
-
29
- ## 2. Add `picked.config.ts`
30
-
31
- Create this file in the root of your project. The `picked` command and the
32
- [Vite plugin](/reference/tools/vite-plugin) read your project identity from it:
33
-
34
- ```typescript
35
- import { defineConfig } from 'picked/config'
36
-
37
- export default defineConfig({
38
- projectId: 'your-project-id',
39
- })
40
- ```
41
-
42
- [Type generation](/reference/sdk/type-generation) reads this file, and gives your fields,
43
- features and steps the types the workspace declares.
44
-
45
- ## 3. Create and start the client
46
-
47
- :::code-group
48
-
49
- ```tsx [React]
50
- import { createClient } from 'picked'
51
- import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
52
- import { reactFrameworkPlugin } from '@picked/react/plugins/framework'
53
-
54
- export const picked = createClient({
55
- projectId: 'your-project-id',
56
- plugins: [reactFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
57
- })
58
-
59
- picked.start()
60
- ```
61
-
62
- ```ts [Svelte]
63
- import { createClient } from 'picked'
64
- import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
65
- import { svelteFrameworkPlugin } from '@picked/svelte/plugins/framework'
66
-
67
- export const picked = createClient({
68
- projectId: 'your-project-id',
69
- plugins: [svelteFrameworkPlugin({ components: {} }), dynamicExperiencesPlugin()],
70
- })
71
-
72
- picked.start()
73
- ```
74
-
75
- :::
76
-
77
- `picked` carries the client's root entry. Each deeper import path, such as
78
- `@picked/client/plugins/dynamic-experiences` and `@picked/client/server`, keeps its own
79
- name.
80
-
81
- `start()` is idempotent. A second call changes nothing on a client that started already.
82
-
83
- ## 4. Add the optional plugins
84
-
85
- - `windowObjectPlugin()` puts the client on `window.Picked`, which helps when you debug.
86
- - `singlePageAppPlugin()` starts the client again on a history event.
87
-
88
- ## Related
89
-
90
- - [Add Picked to your application](/tutorials/first-experience) — the whole path.
91
- - [SDK installation](/reference/sdk) — every client option.
92
- - [Type generation](/reference/sdk/type-generation) — types from your workspace.
93
- - [How to register a component](/how-to/register-a-component).
@@ -1,69 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to install the Vite plugin
7
-
8
- This guide shows you how to embed your project configuration at build time, so the SDK makes no
9
- API request at runtime.
10
-
11
- ## 1. Install
12
-
13
- :::code-group
14
-
15
- ```bash [npm]
16
- npm install @picked/vite-plugin-picked picked
17
- ```
18
-
19
- ```bash [pnpm]
20
- pnpm add @picked/vite-plugin-picked picked
21
- ```
22
-
23
- ```bash [yarn]
24
- yarn add @picked/vite-plugin-picked picked
25
- ```
26
-
27
- :::
28
-
29
- ## 2. Name your project
30
-
31
- Create `picked.config.ts` in the root of your project. The plugin reads your project
32
- identity from this file:
33
-
34
- ```typescript
35
- import { defineConfig } from 'picked/config'
36
-
37
- export default defineConfig({
38
- projectId: 'your-project-id',
39
- })
40
- ```
41
-
42
- ## 3. Add the plugin to your Vite config
43
-
44
- ```typescript
45
- import { defineConfig } from 'vite'
46
- import { picked } from '@picked/vite-plugin-picked'
47
-
48
- export default defineConfig({
49
- plugins: [picked()],
50
- })
51
- ```
52
-
53
- When Vite starts, the plugin reads your project configuration and embeds them in your bundle.
54
- The SDK then reads the embedded configuration and makes no network request.
55
-
56
- The plugin also writes `picked-env.d.ts`, which types your fields, features and steps
57
- against the workspace. See [Type generation](/reference/sdk/type-generation).
58
-
59
- :::note
60
- When a preview token is there at runtime, the SDK ignores the embedded configuration and reads
61
- fresh data from the API.
62
- :::
63
-
64
- ## Related
65
-
66
- - [Vite plugin](/reference/tools/vite-plugin) — every option.
67
- - [Type generation](/reference/sdk/type-generation) — the `picked.config.ts` options.
68
- - [About how Picked works](/explanation/how-picked-works) — where build-time configuration sit
69
- in the startup order.
@@ -1,35 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to invite and remove members
7
-
8
- This guide shows you how to control who reaches your organization.
9
-
10
- ## Invite a member
11
-
12
- 1. Open your organization.
13
- 2. Click **Members**.
14
- 3. Click **Invite member**.
15
- 4. Enter an email address.
16
- 5. Choose a role. Give the smallest role that the work needs.
17
- 6. Click **Send invitation**.
18
-
19
- The person receives an email with a link to join. To join, they click the link in the
20
- email and set a password. They can also go to the register page and enter the same email
21
- address. Then they confirm the address and set a password.
22
-
23
- ## Remove a member
24
-
25
- 1. Open your organization.
26
- 2. Click **Members**.
27
- 3. Find the member.
28
- 4. Click **Remove** next to the name.
29
- 5. Confirm.
30
-
31
- The member loses access to every project in the organization immediately.
32
-
33
- ## Related
34
-
35
- - [Team management](/reference/dashboard/team-management) — the roles.
@@ -1,61 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to point one entry at another
7
-
8
- This guide shows you how to point one content entry at another, such as a product at its
9
- category. You need two Models: the one that holds the pointer, and the one that the
10
- pointer reaches.
11
-
12
- ## 1. Create the target Model
13
-
14
- 1. Click **CMS** in the sidebar, then **Models**.
15
- 2. Click **New model**.
16
- 3. Enter a **Name** and a **Key**, such as `category`.
17
- 4. Leave **Category** as **None (general content)**.
18
- 5. Add your fields.
19
- 6. Click **Create model**.
20
-
21
- ## 2. Add a Reference field
22
-
23
- 1. Open the Model that holds the pointer.
24
- 2. Drag a **Reference** property onto the schema.
25
- 3. Enter a **Name** and a **Key**, such as `category`.
26
- 4. Set **Target Model** to the Model from step 1.
27
- 5. Click **Save**.
28
-
29
- Turn on **repeatable** for a field that points at more than one entry. Leave **Target
30
- Model** as **Any Model** to accept an entry of any Model in the workspace.
31
-
32
- ## 3. Choose a target on an entry
33
-
34
- 1. Open a content entry that uses the Model.
35
- 2. Find your Reference field.
36
- 3. Click **Choose entry**.
37
- 4. Search for the entry.
38
- 5. Choose the entry.
39
- 6. Click **Save**.
40
-
41
- Use **Change entry** to point the field somewhere else. Use **Clear** to remove the
42
- pointer. **Clear** deletes no content.
43
-
44
- ## Delete a target
45
-
46
- Picked does not delete an entry while another entry points at it. Clear the reference on
47
- each entry that points at the target, then delete the target.
48
-
49
- The same rule holds for a Model. Remove the Reference field that holds it as its **Target
50
- Model** first.
51
-
52
- ## Read it in your code
53
-
54
- The pointer and the entry travel separately. See
55
- [How to read a referenced entry](/how-to/read-a-referenced-entry).
56
-
57
- ## Related
58
-
59
- - [About content references](/explanation/content-references) — why a reference is a pointer.
60
- - [Models](/reference/dashboard/content/models) — the field and its options.
61
- - [Content entries](/reference/dashboard/content/content-entries) — the editor reference.
@@ -1,28 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to see a preview of a workspace
7
-
8
- This guide shows you how to see an unpublished change on your own site before your
9
- visitors get it. You need a draft workspace with at least one change in it.
10
-
11
- ## Steps
12
-
13
- 1. Click **Preview** in the workspace toolbar.
14
- 2. Enter the URL of your site.
15
- 3. Set each feature flag to the **Default** value, to **On**, or to **Off**. This step
16
- is optional.
17
- 4. Click **Open preview**.
18
-
19
- Your site opens in a new tab with the unpublished workspace applied.
20
-
21
- The preview sends the workspace state to the SDK in the query parameters. The visitors on
22
- your live site therefore see no change.
23
-
24
- ## Related
25
-
26
- - [About workspaces and versions](/explanation/workspaces-and-versions) — why a preview
27
- cannot reach production.
28
- - [Workspaces](/reference/dashboard/workspaces) — the workspace states.
@@ -1,30 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to publish a workspace
7
-
8
- This guide shows you how to make the changes in a workspace live. You need a draft
9
- workspace with at least one unpublished change.
10
-
11
- The **Publish** button is active only when the workspace holds an unpublished change. A
12
- badge in the toolbar shows the current state.
13
-
14
- ## Steps
15
-
16
- 1. Click **Publish** in the workspace toolbar.
17
- 2. Read the change preview in the publish modal.
18
- 3. Expand any modified row to see which properties changed.
19
- 4. Read the banner above the diff, if one is there. It reports a change that breaks
20
- another record.
21
- 5. Click **Publish** to confirm.
22
-
23
- Picked makes an immutable snapshot of your workspace, and the SDK serves it to your
24
- visitors.
25
-
26
- ## Related
27
-
28
- - [About workspaces and versions](/explanation/workspaces-and-versions) — why the modal
29
- shows a diff.
30
- - [How to roll back a published version](/how-to/roll-back-a-published-version).
@@ -1,113 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to read a feature flag
7
-
8
- This guide shows you how to read the resolved bucket of a feature flag in your
9
- application. You need a feature flag in your project first, either from the dashboard or
10
- [defined in SDK code](/reference/sdk/features#define-a-feature-flag-in-sdk-code).
11
-
12
- Which accessor you pick decides *when* the visitor enters the test, so read
13
- [About feature flag allocation](/explanation/feature-flag-allocation) before you choose.
14
-
15
- ## 1. Choose an accessor
16
-
17
- Each accessor returns a different value, and they differ in whether a read resolves the
18
- feature flag. A read that resolves the feature flag commits the visitor to a bucket and reports the
19
- decision.
20
-
21
- | API | Returns | Does a read resolve the feature flag? |
22
- | --- | --- | --- |
23
- | `useFeature` / `getFeature` | `() => Promise<bucket>` | Only when you call the function that it returns |
24
- | `useFeatureResult` / `getFeatureResult` | `{ id, bucket }`, and `undefined` until it resolves | Yes, as soon as the component renders |
25
- | `useFeatureEnabled` / `getFeatureEnabled` | `boolean \| undefined`, the dashboard **Enabled** setting | No |
26
- | `client.features.listStore` | Every registered feature flag, each with an `isResolved` property | No |
27
- | `client.features.getById(id)` | A store that holds one feature flag | No |
28
-
29
- Some decisions must wait for data that you do not have yet, such as a cart, a quote, or
30
- the profile of a signed-in user. For those, use `useFeature` or `getFeature`. Call the
31
- function they return after the data arrives.
32
-
33
- ## 2. Read the bucket
34
-
35
- The bucket is what your site receives. A Boolean feature flag gives `true` or `false`. A
36
- Text feature flag gives the value of one variant, or `false` for the control group.
37
-
38
- :::code-group
39
-
40
- ```tsx [React]
41
- import { useFeatureResult } from '@picked/react/hooks'
42
-
43
- function MyComponent() {
44
- // { id, bucket }, or undefined until the feature flag resolves.
45
- const result = useFeatureResult('hero')
46
-
47
- return (
48
- <div>
49
- {result?.bucket === false && <p>Control</p>}
50
- {result?.bucket === 'hero-a' && <p>Hero A</p>}
51
- {result?.bucket === 'hero-b' && <p>Hero B</p>}
52
- </div>
53
- )
54
- }
55
- ```
56
-
57
- ```svelte [Svelte]
58
- <script lang="ts">
59
- import { getFeatureResult } from '@picked/svelte/hooks'
60
-
61
- // A store that holds { id, bucket }, or undefined until the feature flag resolves.
62
- const result = getFeatureResult('hero')
63
- </script>
64
-
65
- {#if $result?.bucket === false}
66
- <p>Control</p>
67
- {:else if $result?.bucket === 'hero-a'}
68
- <p>Hero A</p>
69
- {:else if $result?.bucket === 'hero-b'}
70
- <p>Hero B</p>
71
- {/if}
72
- ```
73
-
74
- :::
75
-
76
- :::warning
77
- `useFeatureResult` and `getFeatureResult` resolve the feature flag as soon as the component
78
- renders, and they commit the visitor to a bucket at that moment.
79
- :::
80
-
81
- :::tip
82
- Run [type generation](/reference/sdk/type-generation) and `bucket` narrows to the values
83
- that this Text feature flag declares. Your editor then shows each value, and it reports a
84
- comparison against a value that the feature flag cannot serve.
85
- :::
86
-
87
- ## 3. Read it without a framework
88
-
89
- The event bus works with any framework, and with none:
90
-
91
- ```ts
92
- import { createClient } from 'picked'
93
-
94
- const client = createClient({
95
- /* Put your client options here. */
96
- })
97
-
98
- client.eventBus.watch((event) => {
99
- if (event.type === 'feature_decide' && event.feature.id === 'my-feature') {
100
- console.log(event.feature) // { id: 'my-feature', key: 'v1', bucket: 'hero-a' }
101
- }
102
- })
103
- ```
104
-
105
- `feature_decide` fires only when the SDK makes a new decision. A visitor who returns
106
- restores the decision from storage and fires nothing, so watch
107
- `client.features.listStore` when you need the current state instead.
108
-
109
- ## Related
110
-
111
- - [About feature flag allocation](/explanation/feature-flag-allocation) — when the
112
- visitor enters the test.
113
- - [SDK feature flags](/reference/sdk/features) — the definition shape and the overrides.
@@ -1,109 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to read a referenced entry
7
-
8
- This guide shows you how to read the content that a
9
- [Reference field](/reference/dashboard/content/models#reference-fields) points at. You
10
- need a component that renders a step first. See
11
- [How to render a step form](/how-to/render-a-step-form).
12
-
13
- A Reference field holds a pointer, and not the content. The entry travels beside the
14
- content of the step, so you resolve the pointer against the content of the client.
15
-
16
- ## 1. Resolve a single reference
17
-
18
- Pass the raw field value to `useReference()` in React, or to `getReference()` in Svelte.
19
-
20
- :::code-group
21
-
22
- ```tsx [React]
23
- import { useReference, useStepContent, useStoreGlobal } from '@picked/react/hooks'
24
-
25
- export function ProductCategory() {
26
- const content = useStepContent()
27
- const category = useStoreGlobal(useReference(content?.category))
28
-
29
- if (!category) return null
30
-
31
- return <span>{String(category.data.name ?? '')}</span>
32
- }
33
- ```
34
-
35
- ```svelte [Svelte]
36
- <script lang="ts">
37
- import { getStepContent, getReference } from '@picked/svelte/hooks'
38
-
39
- const content = getStepContent()
40
- const category = getReference(content.map((c) => c?.category ?? null, { skipVoid: false }))
41
- </script>
42
-
43
- {#if $category}
44
- <span>{$category.data.name ?? ''}</span>
45
- {/if}
46
- ```
47
-
48
- :::
49
-
50
- In Svelte, pass a store and not a plain value. Content arrives after the component
51
- starts. A plain value therefore holds the result at "not set".
52
-
53
- ## 2. Resolve a repeatable reference
54
-
55
- Use `useReferences()` or `getReferences()`. They give a list in field order.
56
-
57
- :::code-group
58
-
59
- ```tsx [React]
60
- import { useReferences, useStepContent, useStoreGlobal } from '@picked/react/hooks'
61
-
62
- export function ProductCategories() {
63
- const content = useStepContent()
64
- const categories = useStoreGlobal(useReferences(content?.categories))
65
-
66
- return (
67
- <ul>
68
- {categories.map((category) => (
69
- <li key={category.id}>{String(category.data.name ?? '')}</li>
70
- ))}
71
- </ul>
72
- )
73
- }
74
- ```
75
-
76
- ```svelte [Svelte]
77
- <script lang="ts">
78
- import { getStepContent, getReferences } from '@picked/svelte/hooks'
79
-
80
- const content = getStepContent()
81
- const categories = getReferences(content.map((c) => c?.categories ?? null, { skipVoid: false }))
82
- </script>
83
-
84
- <ul>
85
- {#each $categories as category (category.id)}
86
- <li>{category.data.name ?? ''}</li>
87
- {/each}
88
- </ul>
89
- ```
90
-
91
- :::
92
-
93
- The list holds no empty places, so you need no check for each item.
94
-
95
- ## Handle a target that does not resolve
96
-
97
- A single reference gives an empty result when Picked cannot resolve the target. A
98
- repeatable reference leaves the item out of the list.
99
-
100
- This happens when somebody deleted the target, when the target belongs to another
101
- workspace, or when the chain of references is deeper than the limit.
102
-
103
- Render something else for the empty case, as the React example above does.
104
-
105
- ## Related
106
-
107
- - [Content](/reference/sdk/content) — every hook and its return type.
108
- - [About content references](/explanation/content-references) — why the entry travels separately.
109
- - [How to point one entry at another](/how-to/point-one-entry-at-another) — the dashboard side.
@@ -1,55 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to register a component
7
-
8
- This guide shows you how to connect a component in your application to an experience in
9
- the dashboard.
10
-
11
- ## Steps
12
-
13
- 1. Wrap your component with the adapter for your framework.
14
- 2. Pass it in the `components` object of `createClient()`.
15
- 3. Use the same key as the component name of the experience.
16
-
17
- :::code-group
18
-
19
- ```tsx [React]
20
- import { createClient } from 'picked'
21
- import { adaptReactComponent } from '@picked/react'
22
- import { MyWidget } from './MyWidget'
23
-
24
- const picked = createClient({
25
- projectId: 'your-project-id',
26
- components: {
27
- MyWidget: adaptReactComponent(MyWidget),
28
- },
29
- })
30
- ```
31
-
32
- ```ts [Svelte]
33
- import { createClient } from 'picked'
34
- import { adaptSvelteComponent } from '@picked/svelte'
35
- import MyWidget from './MyWidget.svelte'
36
-
37
- const picked = createClient({
38
- projectId: 'your-project-id',
39
- components: {
40
- MyWidget: adaptSvelteComponent(MyWidget),
41
- },
42
- })
43
- ```
44
-
45
- :::
46
-
47
- :::warning
48
- `components` takes an adapted component. A plain React or Svelte component does not work
49
- without `adaptReactComponent` or `adaptSvelteComponent`.
50
- :::
51
-
52
- ## Related
53
-
54
- - [SDK experiences](/reference/sdk/experiences) — the experience shape.
55
- - [How to install the SDK](/how-to/install-the-sdk).
@@ -1,85 +0,0 @@
1
- ---
2
- type: how-to
3
- layout: docs
4
- ---
5
-
6
- # How to register an action handler
7
-
8
- This guide shows you how to connect an action node in a flow to a function in your
9
- application. You need an action in your project first, with a key. See
10
- [Actions](/reference/dashboard/actions).
11
-
12
- A published action that starts a workflow runs without a handler. A handler under its key
13
- replaces the workflow.
14
-
15
- ## 1. Register the handler
16
-
17
- Pass an `actions` object to `createClient()`. Each key must match an action key from the
18
- dashboard:
19
-
20
- ```ts
21
- import { createClient } from 'picked'
22
-
23
- const picked = createClient({
24
- projectId: 'your-project-id',
25
- actions: {
26
- 'track-signup': () => {
27
- analytics.track('signup_completed')
28
- },
29
- notify: (params) => {
30
- sendNotification(params)
31
- },
32
- },
33
- })
34
- ```
35
-
36
- The SDK calls the function that matches when the flow reaches the action node.
37
-
38
- ## 2. Throw only for a true error
39
-
40
- The flow takes the failure branch when your handler throws or its promise rejects. Throw
41
- when the request itself did not complete:
42
-
43
- ```ts
44
- 'check-eligibility': async () => {
45
- const response = await fetch('/api/eligibility')
46
- // Throw only when the request itself fails. That takes the failure branch.
47
- if (!response.ok) throw new Error('Eligibility request failed')
48
- }
49
- ```
50
-
51
- ## 3. Return a response
52
-
53
- The value that your handler returns is the response of the action. Code that runs the
54
- action reads this value:
55
-
56
- ```ts
57
- 'quote-premium': async ({ responses }) => {
58
- const age = responses.find((r) => r.fieldKey === 'age')?.value
59
- const { premium } = await fetch(`/api/premium?age=${age}`).then((r) => r.json())
60
- return { premium }
61
- }
62
- ```
63
-
64
- ## 4. Record a negative answer as a response
65
-
66
- A valid negative result is not a failure. An endpoint can answer `200` with a "no". Store
67
- that value as a response and branch on it with a condition instead:
68
-
69
- ```ts
70
- 'check-serviced-area': async ({ client, responses }) => {
71
- const postcode = responses.find((r) => r.fieldKey === 'postcode')?.value
72
- const { serviced } = await fetch(`/api/serviced?postcode=${postcode}`).then((r) => r.json())
73
- // Store the outcome as a response. A later condition then takes the branch.
74
- client.responses.register('is-serviced', serviced)
75
- }
76
- ```
77
-
78
- ## Related
79
-
80
- - [About how Picked works](/explanation/how-picked-works#how-an-action-decides-which-way-to-go)
81
- — why a returned `false` is a success.
82
- - [SDK actions](/reference/sdk/actions) — what the handler receives and returns.
83
- - [How to wait for the response of an action](/how-to/wait-for-an-action-response) — show the
84
- response in a component.
85
- - [Actions](/reference/dashboard/actions) — the dashboard options.