@picked/client 0.0.1-dev.1785305085063 → 0.0.1-dev.1785908062293

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 (291) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/api-03c5jvVk.js +38 -0
  3. package/dist/api-CQxCVIrm.cjs +1 -0
  4. package/dist/cjs/form/index.js +1 -1
  5. package/dist/cjs/index.js +2 -2
  6. package/dist/cjs/plugins/dom-observer/index.js +1 -1
  7. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  8. package/dist/cjs/server/index.js +1 -1
  9. package/dist/docs/explanation/conditions-and-the-logic-engine.md +94 -0
  10. package/dist/docs/explanation/feature-flag-allocation.md +176 -0
  11. package/dist/docs/explanation/how-picked-works.md +124 -0
  12. package/dist/docs/explanation/how-pickedql-works.md +76 -0
  13. package/dist/docs/explanation/pages-and-flows.md +64 -0
  14. package/dist/docs/explanation/the-content-model.md +77 -0
  15. package/dist/docs/explanation/the-two-apis.md +68 -0
  16. package/dist/docs/explanation/why-server-side-rendering.md +76 -0
  17. package/dist/docs/explanation/workspaces-and-versions.md +71 -0
  18. package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
  19. package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +53 -28
  20. package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
  21. package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
  22. package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
  23. package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
  24. package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
  25. package/dist/docs/how-to/build-a-flow.md +83 -0
  26. package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
  27. package/dist/docs/how-to/create-a-project.md +29 -0
  28. package/dist/docs/how-to/create-an-experience.md +42 -0
  29. package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
  30. package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
  31. package/dist/docs/how-to/define-a-page-layout.md +39 -0
  32. package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
  33. package/dist/docs/how-to/install-the-gtm-template.md +84 -0
  34. package/dist/docs/how-to/install-the-sdk.md +68 -0
  35. package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
  36. package/dist/docs/how-to/invite-and-remove-members.md +34 -0
  37. package/dist/docs/how-to/preview-a-workspace.md +28 -0
  38. package/dist/docs/how-to/publish-a-workspace.md +30 -0
  39. package/dist/docs/how-to/read-a-feature-flag.md +101 -0
  40. package/dist/docs/how-to/register-a-component.md +55 -0
  41. package/dist/docs/how-to/register-an-action-handler.md +67 -0
  42. package/dist/docs/how-to/render-a-step-form.md +132 -0
  43. package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
  44. package/dist/docs/how-to/reuse-a-section.md +37 -0
  45. package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
  46. package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
  47. package/dist/docs/how-to/run-an-ab-test.md +49 -0
  48. package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
  49. package/dist/docs/how-to/server-render-a-page.md +81 -0
  50. package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
  51. package/dist/docs/how-to/set-up-mfa.md +69 -0
  52. package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
  53. package/dist/docs/how-to/validate-a-field.md +52 -0
  54. package/dist/docs/how-to/write-a-condition.md +45 -0
  55. package/dist/docs/how-to/write-a-predicate.md +60 -0
  56. package/dist/docs/index.md +41 -59
  57. package/dist/docs/reference/dashboard/actions.mdx +53 -0
  58. package/dist/docs/reference/dashboard/api-keys.mdx +37 -0
  59. package/dist/docs/reference/dashboard/conditions.mdx +42 -0
  60. package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
  61. package/dist/docs/reference/dashboard/content/content-entries.mdx +44 -0
  62. package/dist/docs/reference/dashboard/content/layouts.mdx +62 -0
  63. package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
  64. package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
  65. package/dist/docs/reference/dashboard/experiences.mdx +51 -0
  66. package/dist/docs/reference/dashboard/features.mdx +114 -0
  67. package/dist/docs/reference/dashboard/fields.mdx +100 -0
  68. package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +58 -0
  69. package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +57 -0
  70. package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +72 -0
  71. package/dist/docs/reference/dashboard/flow-builder/nodes.md +63 -0
  72. package/dist/docs/reference/dashboard/projects.mdx +44 -0
  73. package/dist/docs/reference/dashboard/reports.mdx +43 -0
  74. package/dist/docs/reference/dashboard/steps.mdx +37 -0
  75. package/dist/docs/reference/dashboard/team-management.md +29 -0
  76. package/dist/docs/reference/dashboard/workspace-versioning.mdx +30 -0
  77. package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
  78. package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +17 -5
  79. package/dist/docs/reference/delivery-api/index.md +45 -0
  80. package/dist/docs/reference/delivery-api/preview-caching-crawling.md +79 -0
  81. package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +15 -6
  82. package/dist/docs/reference/glossary.md +173 -0
  83. package/dist/docs/reference/management-api/authentication.md +74 -0
  84. package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +70 -47
  85. package/dist/docs/reference/management-api/error-handling.md +233 -0
  86. package/dist/docs/{api → reference/management-api}/pagination.md +36 -20
  87. package/dist/docs/reference/pickedql/data-sources.md +174 -0
  88. package/dist/docs/reference/pickedql/dimensions.md +87 -0
  89. package/dist/docs/{pickedql → reference/pickedql}/filtering.md +17 -6
  90. package/dist/docs/reference/pickedql/index.md +18 -0
  91. package/dist/docs/reference/pickedql/schema.md +172 -0
  92. package/dist/docs/reference/pickedql/virtual-functions.md +237 -0
  93. package/dist/docs/reference/sdk/actions.md +30 -0
  94. package/dist/docs/{sdk → reference/sdk}/conditions.md +15 -5
  95. package/dist/docs/reference/sdk/content-security-policy.md +21 -0
  96. package/dist/docs/reference/sdk/experiences.md +51 -0
  97. package/dist/docs/reference/sdk/features.md +233 -0
  98. package/dist/docs/reference/sdk/fields.md +209 -0
  99. package/dist/docs/reference/sdk/index.md +68 -0
  100. package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +25 -34
  101. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +74 -0
  102. package/dist/docs/reference/sdk/plugins/index.md +29 -0
  103. package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
  104. package/dist/docs/reference/sdk/predicates.md +43 -0
  105. package/dist/docs/reference/sdk/ssr/index.md +33 -0
  106. package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +103 -0
  107. package/dist/docs/reference/sdk/ssr/serialize.md +77 -0
  108. package/dist/docs/reference/sdk/ssr/slots-and-placements.md +59 -0
  109. package/dist/docs/reference/sdk/steps.md +87 -0
  110. package/dist/docs/reference/tools/chrome-extension.md +16 -0
  111. package/dist/docs/reference/tools/image-optimisation-service.md +104 -0
  112. package/dist/docs/reference/tools/mcp.md +88 -0
  113. package/dist/docs/reference/tools/vite-plugin.md +88 -0
  114. package/dist/docs/tutorials/first-api-call.md +228 -0
  115. package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
  116. package/dist/docs/tutorials/first-experience.mdx +255 -0
  117. package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
  118. package/dist/{dom-BwmTHeT7.js → dom-BqcToNL0.js} +1 -3
  119. package/dist/{dom-CDrHc_j9.cjs → dom-DlLH3FxV.cjs} +1 -1
  120. package/dist/esm/form/index.js +2 -4
  121. package/dist/esm/index.js +225 -186
  122. package/dist/esm/plugins/dom-observer/index.js +1 -1
  123. package/dist/esm/plugins/dynamic-experiences/index.js +3 -3
  124. package/dist/esm/preview/index.js +1 -1
  125. package/dist/esm/server/index.js +33 -31
  126. package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
  127. package/dist/experience-instance-Dej3P1sE.cjs +1 -0
  128. package/dist/plugin-CHOVsx7Z.js +287 -0
  129. package/dist/plugin-DsaGXQHx.cjs +1 -0
  130. package/dist/{preview-channel-DW9J8t4B.js → preview-channel-CSr96XAo.js} +1 -1
  131. package/dist/{protocol-DSqOlW2r.js → protocol-C5KkkiZc.js} +1 -1
  132. package/dist/types/client.d.ts +7 -6
  133. package/dist/types/data-source/api.d.ts +60 -0
  134. package/dist/types/data-source/api.d.ts.map +1 -0
  135. package/dist/types/data-source/provider.d.ts +97 -0
  136. package/dist/types/data-source/provider.d.ts.map +1 -0
  137. package/dist/types/entities/action/action.d.ts +5 -4
  138. package/dist/types/entities/action/action.d.ts.map +1 -1
  139. package/dist/types/entities/component/component.d.ts +6 -5
  140. package/dist/types/entities/component/component.d.ts.map +1 -1
  141. package/dist/types/entities/condition/condition.d.ts +5 -5
  142. package/dist/types/entities/content/content.d.ts +4 -3
  143. package/dist/types/entities/experience/experience.d.ts +11 -10
  144. package/dist/types/entities/experience/experience.d.ts.map +1 -1
  145. package/dist/types/entities/experience-instance/experience-instance.d.ts +10 -9
  146. package/dist/types/entities/feature/feature.d.ts +19 -2
  147. package/dist/types/entities/feature/feature.d.ts.map +1 -1
  148. package/dist/types/entities/field/field.d.ts +7 -6
  149. package/dist/types/entities/framework/framework.d.ts +7 -6
  150. package/dist/types/entities/framework/framework.d.ts.map +1 -1
  151. package/dist/types/entities/history/history.d.ts +6 -6
  152. package/dist/types/entities/plugin/plugin.d.ts +3 -2
  153. package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
  154. package/dist/types/entities/predicate/predicate.d.ts +4 -3
  155. package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
  156. package/dist/types/entities/response/response-validation.d.ts +3 -2
  157. package/dist/types/entities/response/response.d.ts +12 -11
  158. package/dist/types/entities/session/session.d.ts +2 -1
  159. package/dist/types/entities/step/step.d.ts +6 -5
  160. package/dist/types/exports.d.ts +2 -1
  161. package/dist/types/exports.d.ts.map +1 -1
  162. package/dist/types/form/build-responses.d.ts +2 -1
  163. package/dist/types/form/create-field-evaluator.d.ts +4 -3
  164. package/dist/types/form/create-field-validation.d.ts +5 -4
  165. package/dist/types/form/create-form.d.ts +7 -6
  166. package/dist/types/form/create-submit-pipeline.d.ts +7 -6
  167. package/dist/types/form/get-step-fields.d.ts +3 -2
  168. package/dist/types/lifecycle/condition-selection.d.ts +14 -4
  169. package/dist/types/lifecycle/lifecycle.d.ts +4 -3
  170. package/dist/types/lifecycle/rules-logic.d.ts +4 -3
  171. package/dist/types/lifecycle/state-snapshot.d.ts +4 -3
  172. package/dist/types/picked.d.ts +79 -62
  173. package/dist/types/picked.d.ts.map +1 -1
  174. package/dist/types/ping.d.ts +1 -1
  175. package/dist/types/ping.d.ts.map +1 -1
  176. package/dist/types/plugins/create-experience/create-experience.d.ts +9 -8
  177. package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
  178. package/dist/types/plugins/create-experience/plugin.d.ts +3 -2
  179. package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
  180. package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
  181. package/dist/types/plugins/dom-observer/plugin.d.ts +1 -1
  182. package/dist/types/plugins/dynamic-experiences/hash.d.ts +40 -5
  183. package/dist/types/plugins/dynamic-experiences/hash.d.ts.map +1 -1
  184. package/dist/types/plugins/dynamic-experiences/index.d.ts +2 -0
  185. package/dist/types/plugins/dynamic-experiences/index.d.ts.map +1 -1
  186. package/dist/types/plugins/dynamic-experiences/plugin.d.ts +4 -36
  187. package/dist/types/plugins/dynamic-experiences/plugin.d.ts.map +1 -1
  188. package/dist/types/plugins/dynamic-experiences/types.d.ts +42 -11
  189. package/dist/types/plugins/dynamic-experiences/types.d.ts.map +1 -1
  190. package/dist/types/plugins/experience-browser-storage/plugin.d.ts +1 -1
  191. package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +1 -1
  192. package/dist/types/plugins/history-browser-storage/plugin.d.ts +1 -1
  193. package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +1 -1
  194. package/dist/types/plugins/responses-browser-storage/plugin.d.ts +1 -1
  195. package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +1 -1
  196. package/dist/types/plugins/responses-indexeddb/plugin.d.ts +1 -1
  197. package/dist/types/plugins/single-page-app/plugin.d.ts +1 -1
  198. package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
  199. package/dist/types/plugins/web-components/plugin.d.ts +2 -1
  200. package/dist/types/plugins/window-object/plugin.d.ts +2 -2
  201. package/dist/types/preview-channel.d.ts +5 -1
  202. package/dist/types/preview-receiver/index.d.ts +18 -1
  203. package/dist/types/preview-receiver/protocol.d.ts +10 -1
  204. package/dist/types/server/index.d.ts +3 -3
  205. package/dist/types/server/serialize.d.ts +8 -2
  206. package/dist/types/server/serialize.d.ts.map +1 -1
  207. package/dist/types/utils/dom.d.ts +2 -1
  208. package/dist/types/utils/events.d.ts +6 -6
  209. package/dist/types/utils/events.d.ts.map +1 -1
  210. package/dist/types/utils/global-obj.d.ts +1 -1
  211. package/dist/types/utils/global-obj.d.ts.map +1 -1
  212. package/dist/types/utils/id.d.ts.map +1 -1
  213. package/dist/types/utils/logger.d.ts +2 -1
  214. package/dist/types/utils/logger.d.ts.map +1 -1
  215. package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +2 -1
  216. package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +2 -1
  217. package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
  218. package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
  219. package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
  220. package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
  221. package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
  222. package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
  223. package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
  224. package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
  225. package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
  226. package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
  227. package/dist/types/utils/nodes.d.ts +1 -1
  228. package/dist/types/utils/picked-config.d.ts +2 -1
  229. package/dist/types/utils/rehydrate-scripts.d.ts +6 -0
  230. package/dist/types/utils/rehydrate-scripts.d.ts.map +1 -1
  231. package/dist/types/utils/rules-logic.d.ts +6 -2
  232. package/dist/types/utils/storage.d.ts +1 -1
  233. package/dist/types/utils/storage.d.ts.map +1 -1
  234. package/package.json +22 -23
  235. package/dist/api-CPL40b7A.js +0 -40
  236. package/dist/api-Dz5rgRgQ.cjs +0 -1
  237. package/dist/docs/actions.mdx +0 -78
  238. package/dist/docs/api/authentication.md +0 -376
  239. package/dist/docs/api/error-handling.md +0 -211
  240. package/dist/docs/api/index.md +0 -197
  241. package/dist/docs/api-keys.mdx +0 -40
  242. package/dist/docs/chrome-extension.md +0 -51
  243. package/dist/docs/conditions.mdx +0 -59
  244. package/dist/docs/content/asset-library.mdx +0 -93
  245. package/dist/docs/content/content-entries.mdx +0 -30
  246. package/dist/docs/content/layouts.mdx +0 -70
  247. package/dist/docs/content/pages.mdx +0 -67
  248. package/dist/docs/content/sections.mdx +0 -33
  249. package/dist/docs/delivery-api/index.md +0 -46
  250. package/dist/docs/delivery-api/preview-caching-crawling.md +0 -59
  251. package/dist/docs/experiences.mdx +0 -42
  252. package/dist/docs/features.mdx +0 -58
  253. package/dist/docs/fields.mdx +0 -79
  254. package/dist/docs/flow-builder/building-flows.md +0 -61
  255. package/dist/docs/flow-builder/condition-builder.md +0 -54
  256. package/dist/docs/flow-builder/keyboard-shortcuts.md +0 -66
  257. package/dist/docs/flow-builder/nodes.md +0 -43
  258. package/dist/docs/flow-builder/overview.mdx +0 -50
  259. package/dist/docs/gtm-template.md +0 -69
  260. package/dist/docs/guides/build-a-personalized-page.mdx +0 -143
  261. package/dist/docs/image-optimisation-service.md +0 -80
  262. package/dist/docs/mcp.md +0 -120
  263. package/dist/docs/pickedql/data-sources.md +0 -145
  264. package/dist/docs/pickedql/dimensions.md +0 -65
  265. package/dist/docs/pickedql/index.md +0 -36
  266. package/dist/docs/pickedql/schema.md +0 -156
  267. package/dist/docs/pickedql/virtual-functions.md +0 -204
  268. package/dist/docs/projects.mdx +0 -37
  269. package/dist/docs/reports.mdx +0 -18
  270. package/dist/docs/sdk/actions.md +0 -66
  271. package/dist/docs/sdk/content-security-policy.md +0 -32
  272. package/dist/docs/sdk/experiences.md +0 -46
  273. package/dist/docs/sdk/features.md +0 -212
  274. package/dist/docs/sdk/fields.md +0 -263
  275. package/dist/docs/sdk/index.md +0 -83
  276. package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -58
  277. package/dist/docs/sdk/plugins/index.md +0 -9
  278. package/dist/docs/sdk/predicates.md +0 -112
  279. package/dist/docs/sdk/ssr/index.md +0 -62
  280. package/dist/docs/sdk/ssr/rendering-and-hydration.md +0 -141
  281. package/dist/docs/sdk/ssr/serialize.md +0 -86
  282. package/dist/docs/sdk/ssr/slots-and-placements.md +0 -35
  283. package/dist/docs/sdk/steps.md +0 -434
  284. package/dist/docs/steps.mdx +0 -44
  285. package/dist/docs/team-management.md +0 -40
  286. package/dist/docs/vite-plugin.md +0 -82
  287. package/dist/docs/workspace-versioning.mdx +0 -28
  288. package/dist/docs/workspaces.mdx +0 -102
  289. package/dist/experience-instance-DurC3pE-.cjs +0 -1
  290. package/dist/plugin-CFXwbXeM.js +0 -247
  291. package/dist/plugin-m4qekgtA.cjs +0 -1
@@ -0,0 +1,77 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Server Snapshot
7
+
8
+ `serialize()` finds which experiences match a URL and reads their content on the
9
+ server. It returns a snapshot as plain JSON, and you pass that snapshot to the
10
+ client.
11
+
12
+ ## The `serialize(client, params)` function
13
+
14
+ ```ts
15
+ import { createClient } from '@picked/client'
16
+ import { serialize } from '@picked/client/server'
17
+
18
+ const client = createClient(options)
19
+
20
+ const snapshot = await serialize(client, {
21
+ projectConfig,
22
+ attributes: { location: { pathname: '/promo' } },
23
+ })
24
+ ```
25
+
26
+ `serialize()` does this. It registers the project configuration on the client at once. It
27
+ evaluates the condition of each experience against `attributes.location`. It reads
28
+ the content for each experience whose steps point at layout content. It removes the
29
+ duplicate content blobs, which it finds by their IDs. It then returns a
30
+ `PickedSnapshot`.
31
+
32
+ Give `serialize()` one client for each request. It does not support two calls at the
33
+ same time on one client.
34
+
35
+ ```ts
36
+ serialize(client: Picked, params: SerializeParams): Promise<PickedSnapshot>
37
+ ```
38
+
39
+ ## Parameters
40
+
41
+ | Parameter | Type | Default | Description |
42
+ | --- | --- | --- | --- |
43
+ | `projectConfig` | `ProjectConfig` | required | The published configuration, or the preview configuration, to register and choose against. |
44
+ | `attributes.location` | `Partial<SerializeLocation>` | none | The URL fields that go into the selection context, such as `pathname`. |
45
+ | `getContent` | `SerializeGetContent` | runtime API | Your own function to read content, in place of the runtime API. |
46
+ | `previewToken` | `string` | none | The SDK sends this with the content request, so that preview content resolves during a preview render. |
47
+ | `timeoutMs` | `number` | `10000` | The limit for each content request. After the limit, the SDK skips that blob and continues. |
48
+
49
+ `SerializeLocation` carries the URL fields `href`, `pathname`, `search`, `hostname`,
50
+ `origin`, `protocol`, `port`, `host`, and `hash`. Pass only the fields that your
51
+ conditions read.
52
+
53
+ ## The snapshot
54
+
55
+ ```ts
56
+ interface PickedSnapshot {
57
+ versionId: string | null
58
+ projectConfig: ProjectConfig
59
+ content: ContentBlob[]
60
+ conditionResults: Record<string, boolean>
61
+ }
62
+ ```
63
+
64
+ | Field | Description |
65
+ | --- | --- |
66
+ | `versionId` | The project version that the snapshot was chosen against. It is `null` when the version is not known, for example in a preview. |
67
+ | `projectConfig` | The options that the server chose with. They travel to the client, so that the client renders against exactly the same options. |
68
+ | `content` | The content blobs for the chosen experiences, with the duplicates removed. |
69
+ | `conditionResults` | The condition results that the server kept, under a key made from the rule hash. The client then reuses the choice of the server. |
70
+
71
+ The snapshot is plain JSON. Write it into your HTML response with `JSON.stringify`
72
+ and read it back on the client.
73
+
74
+ ## Related
75
+
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)
@@ -0,0 +1,59 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Slots and Placements
7
+
8
+ A slot is a named mount point. `<ExperienceSlot name="page" />` renders every
9
+ experience that points at that slot and whose condition matches.
10
+
11
+ ## What a slot is
12
+
13
+ The `name` of a slot points at the `.picked-slot-<name>` selector. So
14
+ `<ExperienceSlot name="page" />` renders every experience with the target selector
15
+ `.picked-slot-page`, when the condition of that experience is active.
16
+
17
+ The slot reads the active state of each experience from the seeded snapshot. It
18
+ therefore renders at once, both in server-side rendering and at the first paint of
19
+ the hydration.
20
+
21
+ ```tsx
22
+ <ExperienceSlot name="page" />
23
+ ```
24
+
25
+ ## Point an experience at a slot
26
+
27
+ Set the target selector of the experience to `.picked-slot-<name>`. An experience
28
+ that points at `.picked-slot-page` renders into `<ExperienceSlot name="page" />`. The
29
+ name of the slot and the end of the selector must match.
30
+
31
+ ## Placement order
32
+
33
+ When more than one experience points at the same slot, they render in this placement
34
+ order:
35
+
36
+ ```
37
+ replace -> before -> prepend -> append -> after
38
+ ```
39
+
40
+ `replace` wins. An active experience with the `replace` placement renders alone, and
41
+ it replaces every other match in the slot. In every other case each active experience
42
+ renders, in placement order.
43
+
44
+ ## More than one experience in one slot
45
+
46
+ The slot collects each experience that points at its selector. It drops each one
47
+ whose condition is not active. It then sorts the rest into placement order. When a `replace`
48
+ experience is among the active ones, only that experience renders. With no active
49
+ `replace`, the slot renders every active experience in the order `before`, `prepend`,
50
+ `append`, `after`.
51
+
52
+ One Page can therefore take a whole slot with `replace`, while another slot holds
53
+ several experiences that use the other placements. A condition decides which
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
+ ![Picked Developer Tools](/chrome-extension-screenshot.jpg)
13
+
14
+ ## Related
15
+
16
+ - [How to debug with the Chrome extension](/how-to/debug-with-the-chrome-extension)
@@ -0,0 +1,104 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Image optimisation service
7
+
8
+ The Picked service for image optimisation is a hosted endpoint at
9
+ `https://img.picked-content.com`. It reads an image from an allowed source domain and
10
+ resizes it. It then encodes the image again to a modern format, WebP or AVIF, and
11
+ caches the result.
12
+
13
+ ## Endpoint
14
+
15
+ ```
16
+ GET https://img.picked-content.com/_next/image?url={source}&w={width}&q={quality}
17
+ ```
18
+
19
+ | Parameter | Description |
20
+ |-----------|-------------|
21
+ | `url` | The URL of the source image, URL-encoded. It must point at an allowed source domain. See below. |
22
+ | `w` | The width in pixels. It must be one of the supported widths. |
23
+ | `q` | The quality: `25`, `50`, `75`, or `100`. |
24
+
25
+ The service chooses the response format. When the browser advertises `image/avif` or
26
+ `image/webp` in its `Accept` header, the response uses that format. If it does not,
27
+ the response uses the source format.
28
+
29
+ ## Allowed source domains
30
+
31
+ The service reads only from these hostnames:
32
+
33
+ - `**.picked.app`
34
+
35
+ A request with a `url` parameter for any other hostname returns `400 Bad Request`.
36
+
37
+ ## Supported widths
38
+
39
+ Device sizes, for a responsive image that spans the width of the viewport:
40
+
41
+ ```
42
+ 640, 750, 828, 1080, 1200, 1920, 2048, 3840
43
+ ```
44
+
45
+ Image sizes, for a UI element of fixed size such as an icon, an avatar, or a
46
+ thumbnail:
47
+
48
+ ```
49
+ 16, 32, 48, 64, 96, 128, 256, 384
50
+ ```
51
+
52
+ A request with any other width returns `400 Bad Request`. Choose the smallest width
53
+ that covers the size you render at the device pixel ratio of the visitor.
54
+
55
+ ## Supported qualities
56
+
57
+ ```
58
+ 25, 50, 75, 100
59
+ ```
60
+
61
+ A lower value reduces the bandwidth by a large amount. `75` is a good default for
62
+ most images. Use `25` or `50` for a thumbnail on a slow network.
63
+
64
+ ## Responsive images
65
+
66
+ Use the endpoint together with the standard `srcset` attribute. The browser then
67
+ picks the correct width for each viewport:
68
+
69
+ ```html
70
+ <img
71
+ src="https://img.picked-content.com/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1080&q=75"
72
+ srcset="
73
+ https://img.picked-content.com/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=640&q=75 640w,
74
+ https://img.picked-content.com/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1080&q=75 1080w,
75
+ https://img.picked-content.com/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1920&q=75 1920w
76
+ "
77
+ sizes="(max-width: 768px) 100vw, 720px"
78
+ alt="..."
79
+ />
80
+ ```
81
+
82
+ ## Cache
83
+
84
+ The upstream CDN caches each optimised response. The smallest cache TTL is 60
85
+ seconds. The real lifetime depends on the eviction policy of the CDN. When you change
86
+ the source image at the same URL, the optimised copy stays in the cache for at least
87
+ that time.
88
+
89
+ ## Security
90
+
91
+ - The service does not optimise an SVG source. A request for an SVG returns the
92
+ original bytes when the source is allowed. The service never runs an embedded
93
+ script.
94
+ - Each optimised response carries a strict `Content-Security-Policy`
95
+ (`default-src *; script-src 'none'; sandbox;`). A compromised source therefore
96
+ cannot run a script in the browser that shows the image.
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.
@@ -0,0 +1,88 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # MCP server
7
+
8
+ Control your Picked workspace from an AI tool that writes code, with the Model
9
+ Context Protocol (MCP).
10
+
11
+ ## Tools
12
+
13
+ ### Discovery
14
+
15
+ | Tool | Description |
16
+ | ------------------------ | ------------------------------------------------------------ |
17
+ | `list_projects` | Lists your organizations and projects |
18
+ | `get_workspace_overview` | Reads the full workspace state |
19
+ | `get_schema_info` | Reads the documentation for Picked concepts and the data model |
20
+ | `get_picked_docs` | Reads the complete Picked documentation, as text for an agent |
21
+
22
+ ### Experiences
23
+
24
+ | Tool | Description |
25
+ | ------------------------ | ----------------------------------------------------------------------------------------- |
26
+ | `create_experience` | Creates an experience |
27
+ | `get_experience` | Reads an experience, with its flow graph |
28
+ | `list_experiences` | Lists your experiences |
29
+ | `update_experience_flow` | Creates, updates, or deletes steps, conditions, actions, fields, nodes, and edges as one operation |
30
+
31
+ ### Steps, fields, conditions, and actions
32
+
33
+ | Tool | Description |
34
+ | ----------------------------------- | --------------- |
35
+ | `get_step` / `list_steps` | Read steps |
36
+ | `get_field` / `list_fields` | Read fields |
37
+ | `get_condition` / `list_conditions` | Read conditions |
38
+ | `get_action` / `list_actions` | Read actions |
39
+
40
+ ### Feature flags
41
+
42
+ | Tool | Description |
43
+ | ---------------- | ---------------------------------------------------- |
44
+ | `create_feature` | Creates a feature flag |
45
+ | `get_feature` | Reads a feature flag |
46
+ | `list_features` | Lists your feature flags |
47
+ | `update_feature` | Updates the name, description, state, or weight |
48
+
49
+ ### Analytics
50
+
51
+ | Tool | Description |
52
+ | ---------------- | ---------------------------------------------------------------- |
53
+ | `query_pickedql` | Runs a PickedQL analytics query and returns the rows as a table |
54
+
55
+ Call `get_schema_info` with the topic `pickedql` to see the tables, the virtual
56
+ functions, and the dimension columns before you write a query.
57
+
58
+ ### Publish
59
+
60
+ | Tool | Description |
61
+ | ------------------- | ---------------------------------------------- |
62
+ | `get_preview_url` | Makes a preview URL for your unpublished work |
63
+ | `publish_workspace` | Publishes the workspace |
64
+
65
+ ## Example prompts
66
+
67
+ - "List my Picked projects and show me the options on each one"
68
+ - "Create a feature flag called 'new-checkout' at 50% traffic"
69
+ - "Create an experience with a step that collects an email address"
70
+ - "Show me control and variant users by the device type for the last 30 days"
71
+ - "Make a preview URL for my workspace on `https://example.com`"
72
+
73
+ ## Tips
74
+
75
+ - Ask your agent for a list of your projects first. Then ask it to read your
76
+ workspace and report the options on each record.
77
+ - For a large experience, ask your agent about flow graphs and JSON Logic. The agent
78
+ can read the documentation for you.
79
+ - An update to an experience flow is atomic. Your agent can create steps, fields,
80
+ nodes, and edges in one operation.
81
+ - See a preview of your work on your site before you publish, to check that each page
82
+ is correct.
83
+ - Ask your agent to run a PickedQL query on your analytics data. The agent can read
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)
@@ -0,0 +1,88 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ # Vite Plugin
7
+
8
+ `@picked/vite-plugin-picked` adds Picked to your Vite project. It reads the options
9
+ of your project at build time. It then injects them through the Vite `define`
10
+ option, so the SDK makes no API request at runtime. In development it also serves a
11
+ launcher page. On that page you can see a preview of an experience with your own
12
+ feature flag values.
13
+
14
+ ## How it works
15
+
16
+ ### Build-time config injection
17
+
18
+ When Vite starts, in both `dev` and `build`, the plugin does this:
19
+
20
+ 1. It reads the configuration of your project from the Picked API.
21
+ 2. It embeds those options in your bundle.
22
+ 3. The SDK reads the embedded configuration at runtime and makes no network request.
23
+
24
+ When a preview token is there at runtime, the SDK ignores the embedded configuration and
25
+ reads fresh data from the API.
26
+
27
+ ### Preload of the data file
28
+
29
+ Vite puts the options of your project in their own JavaScript file. For each HTML page
30
+ in your build, the plugin adds a `<link rel="modulepreload">` for that file. The
31
+ browser then gets it while it reads the page, and not later when the SDK starts.
32
+
33
+ The CMS content of an experience stays in its own file and gets no preload. The
34
+ browser gets it only when an experience needs it.
35
+
36
+ Some applications make their HTML from the code, and not from an HTML file in your
37
+ project. React Router in server mode is one of these. Such a build has no page for the
38
+ plugin to add the link to. Add this line to the code that runs in the browser instead:
39
+
40
+ :::code-group
41
+
42
+ ```ts [entry.client.ts]
43
+ import 'virtual:picked/data'
44
+ ```
45
+
46
+ :::
47
+
48
+ Your framework then sees the file in its own list and adds the preload for you.
49
+
50
+ ### Dev launcher
51
+
52
+ In development, the plugin serves an HTML page at `/`. On that page you can:
53
+
54
+ - see every feature flag in your project with its current state;
55
+ - turn a feature flag on or off for a local test;
56
+ - see a preview of an experience with your own feature flag values.
57
+
58
+ After the dev server starts, the launcher URL appears next to the Vite output:
59
+
60
+ ```
61
+ ➜ Picked: http://localhost:5173/
62
+ ➜ Local: http://localhost:5173/
63
+ ➜ Network: use --host to expose
64
+ ```
65
+
66
+ ## Options
67
+
68
+ | Option | Type | Default | Description |
69
+ | ---------------- | --------- | ---------------------------- | -------------------------------------------------------- |
70
+ | `projectId` | `string` | — | **Required.** The ID of your Picked project. |
71
+ | `apiUrl` | `string` | `https://api.picked.app` | Your own API URL, for a self-hosted or local API. |
72
+ | `disableLauncher`| `boolean` | `false` | Turns the launcher page off in both dev and build output.|
73
+
74
+ ## Build output
75
+
76
+ For a production build, `vite build`, the plugin writes an `index.html` file that
77
+ holds the launcher page. Set `disableLauncher` to stop this. The file lets you deploy
78
+ the launcher next to your application, so that a stakeholder can see a preview.
79
+
80
+ The plugin writes that file only when your build made no `index.html` of its own. An
81
+ application that has an HTML entry keeps its own page at the root of the output.
82
+
83
+ The plugin also writes a `.picked` directory next to your Vite `root`. It holds the
84
+ options of your project and the CMS content of each experience.
85
+
86
+ ## Related
87
+
88
+ - [How to install the Vite plugin](/how-to/install-the-vite-plugin)