@croct/plug-react 0.4.2 → 0.5.0-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/CroctProvider.d.ts +7 -7
- package/CroctProvider.js +37 -0
- package/CroctProvider.js.map +1 -0
- package/README.md +245 -107
- package/api/evaluate.d.ts +7 -0
- package/api/evaluate.js +15 -0
- package/api/evaluate.js.map +1 -0
- package/api/fetchContent.d.ts +13 -0
- package/api/fetchContent.js +20 -0
- package/api/fetchContent.js.map +1 -0
- package/api/index.d.ts +2 -0
- package/api/index.js +19 -0
- package/api/index.js.map +1 -0
- package/components/Personalization/index.d.ts +10 -10
- package/components/Personalization/index.js +13 -0
- package/components/Personalization/index.js.map +1 -0
- package/components/Slot/index.d.ts +19 -19
- package/components/Slot/index.js +13 -0
- package/components/Slot/index.js.map +1 -0
- package/components/index.d.ts +2 -2
- package/components/index.js +19 -0
- package/components/index.js.map +1 -0
- package/hooks/Cache.d.ts +22 -22
- package/hooks/Cache.js +62 -0
- package/hooks/Cache.js.map +1 -0
- package/hooks/index.d.ts +3 -3
- package/hooks/index.js +20 -0
- package/hooks/index.js.map +1 -0
- package/hooks/useContent.d.ts +18 -17
- package/hooks/useContent.js +25 -0
- package/hooks/useContent.js.map +1 -0
- package/hooks/useCroct.d.ts +2 -2
- package/hooks/useCroct.js +14 -0
- package/hooks/useCroct.js.map +1 -0
- package/hooks/useEvaluation.d.ts +11 -11
- package/hooks/useEvaluation.js +35 -0
- package/hooks/useEvaluation.js.map +1 -0
- package/hooks/useLoader.d.ts +5 -5
- package/hooks/useLoader.js +41 -0
- package/hooks/useLoader.js.map +1 -0
- package/index.d.ts +5 -3
- package/index.js +20 -337
- package/index.js.map +1 -1
- package/package.json +33 -46
- package/src/api/evaluate.test.ts +59 -0
- package/src/api/evaluate.ts +19 -0
- package/src/api/fetchContent.test.ts +134 -0
- package/src/api/fetchContent.ts +47 -0
- package/src/api/index.ts +2 -0
- package/src/components/index.ts +2 -0
- package/src/global.d.ts +7 -0
- package/src/hooks/Cache.test.ts +280 -0
- package/src/hooks/Cache.ts +97 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useContent.ssr.test.ts +23 -0
- package/src/hooks/useContent.test.ts +66 -0
- package/src/hooks/useContent.ts +69 -0
- package/src/hooks/useCroct.ts +13 -0
- package/src/hooks/useEvaluation.ssr.test.ts +23 -0
- package/src/hooks/useEvaluation.test.ts +92 -0
- package/src/hooks/useEvaluation.ts +58 -0
- package/src/hooks/useLoader.test.ts +320 -0
- package/src/hooks/useLoader.ts +50 -0
- package/src/index.ts +5 -0
- package/src/react-app-env.d.ts +1 -0
- package/src/ssr-polyfills.ssr.test.ts +46 -0
- package/src/ssr-polyfills.test.ts +65 -0
- package/src/ssr-polyfills.ts +68 -0
- package/ssr-polyfills.d.ts +3 -3
- package/ssr-polyfills.js +64 -0
- package/ssr-polyfills.js.map +1 -0
- package/CroctProvider.test.d.ts +0 -1
- package/components/Personalization/index.d.test.d.ts +0 -1
- package/components/Personalization/index.stories.d.ts +0 -7
- package/components/Personalization/index.test.d.ts +0 -1
- package/components/Slot/index.d.test.d.ts +0 -1
- package/components/Slot/index.stories.d.ts +0 -17
- package/components/Slot/index.test.d.ts +0 -1
- package/hooks/Cache.test.d.ts +0 -1
- package/hooks/useContent.d.test.d.ts +0 -1
- package/hooks/useContent.ssr.test.d.ts +0 -1
- package/hooks/useContent.stories.d.ts +0 -19
- package/hooks/useContent.test.d.ts +0 -1
- package/hooks/useCroct.ssr.test.d.ts +0 -1
- package/hooks/useCroct.test.d.ts +0 -1
- package/hooks/useEvaluation.d.test.d.ts +0 -1
- package/hooks/useEvaluation.ssr.test.d.ts +0 -1
- package/hooks/useEvaluation.stories.d.ts +0 -8
- package/hooks/useEvaluation.test.d.ts +0 -1
- package/hooks/useLoader.test.d.ts +0 -1
- package/ssr-polyfills.ssr.test.d.ts +0 -1
- package/ssr-polyfills.test.d.ts +0 -1
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
## Introduction
|
|
25
25
|
|
|
26
|
-
The React Plug library provides components and hooks for personalizing applications in real-time that are easy for your
|
|
26
|
+
The React Plug library provides components and hooks for personalizing applications in real-time that are easy for your
|
|
27
|
+
marketing team to scale and maintain.
|
|
27
28
|
|
|
28
29
|
- **Easy integration**: personalize existing components without touching their code.
|
|
29
30
|
- **Suspense-ready**: take advantage of the latest React features to improve user experience.
|
|
@@ -68,32 +69,33 @@ import {render} from 'react-dom';
|
|
|
68
69
|
import {CroctProvider} from '@croct/plug-react';
|
|
69
70
|
|
|
70
71
|
function App() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
return (
|
|
73
|
+
<CroctProvider appId="<APP_ID>">
|
|
74
|
+
<div>
|
|
75
|
+
<h1>My first personalized app 🚀</h1>
|
|
76
|
+
</div>
|
|
77
|
+
</CroctProvider>
|
|
78
|
+
);
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
render(<App
|
|
81
|
+
render(<App/>, document.getElementById('root'));
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
> Replace `<APP_ID>` with your public app ID that you can find at Workspaces > Applications > Setup.
|
|
84
85
|
> In case you don't have an account yet, you can use the sandbox application ID `00000000-0000-0000-0000-000000000000`
|
|
85
86
|
|
|
86
|
-
### Evaluating
|
|
87
|
+
### Evaluating queries
|
|
87
88
|
|
|
88
89
|
Once your application is plugged in, you're ready to start personalizing your components using the `<Personalization />`
|
|
89
90
|
component or the `useEvaluation` hook.
|
|
90
91
|
|
|
91
|
-
We'll go through a simple example that shows how
|
|
92
|
+
We'll go through a simple example that shows how you can implement feature flags (also known as feature toggles)
|
|
92
93
|
to conditionally renders a different button depending on the user's persona.
|
|
93
94
|
|
|
94
95
|

|
|
95
96
|
|
|
96
|
-
Let's first implement the use-case using the `<Personalization />` component. It takes an
|
|
97
|
+
Let's first implement the use-case using the `<Personalization />` component. It takes an query (
|
|
98
|
+
e.g. `user's persona`)
|
|
97
99
|
and a render function, which tells the component how to render the UI, depending on the evaluation result.
|
|
98
100
|
|
|
99
101
|
This is what our component would look like:
|
|
@@ -105,7 +107,7 @@ import {Personalization} from '@croct/plug-react';
|
|
|
105
107
|
function OnboardingPage(): ReactElement {
|
|
106
108
|
return (
|
|
107
109
|
<Suspense fallback="✨ Personalizing...">
|
|
108
|
-
<Personalization
|
|
110
|
+
<Personalization query="user's persona is not 'developer'">
|
|
109
111
|
{(isDeveloper: boolean) => isDeveloper
|
|
110
112
|
? <a href="/docs">View docs</a>
|
|
111
113
|
: <a href="/share">Share with your developer</a>
|
|
@@ -124,7 +126,7 @@ import {Personalization} from '@croct/plug-react';
|
|
|
124
126
|
|
|
125
127
|
function OnboardingPage(): ReactElement {
|
|
126
128
|
return (
|
|
127
|
-
<Personalization
|
|
129
|
+
<Personalization query="user's persona is not 'developer'" initial={false}>
|
|
128
130
|
{(isDeveloper: boolean) => isDeveloper
|
|
129
131
|
? <a href="/docs">View docs</a>
|
|
130
132
|
: <a href="/share">Share with your developer</a>
|
|
@@ -153,7 +155,7 @@ function ViewDocsLink(): ReactElement {
|
|
|
153
155
|
export default function OnboardingPage(): ReactElement {
|
|
154
156
|
return (
|
|
155
157
|
<Suspense fallback="✨ Personalizing...">
|
|
156
|
-
<ViewDocsLink
|
|
158
|
+
<ViewDocsLink/>
|
|
157
159
|
</Suspense>
|
|
158
160
|
)
|
|
159
161
|
}
|
|
@@ -166,8 +168,8 @@ user's profile.
|
|
|
166
168
|
|
|
167
169
|
#### Fault tolerance
|
|
168
170
|
|
|
169
|
-
We strongly recommend specifying the `fallback` property in client-side rendered applications to ensure your app behaves
|
|
170
|
-
the same way regardless of the personalization. In this way, the UI will still be fully functional even in maintenance
|
|
171
|
+
We strongly recommend specifying the `fallback` property in client-side rendered applications to ensure your app behaves
|
|
172
|
+
the same way regardless of the personalization. In this way, the UI will still be fully functional even in maintenance
|
|
171
173
|
windows. **Specifying a `fallback` is required for server-side rendering (SSR).**
|
|
172
174
|
|
|
173
175
|
The following example shows how you can specify a fallback behaviour for the docs link:
|
|
@@ -186,7 +188,7 @@ export default function OnboardingPage(): ReactElement {
|
|
|
186
188
|
return (
|
|
187
189
|
<Suspense fallback="✨ Personalizing...">
|
|
188
190
|
{/* Using the <Personalization /> component */}
|
|
189
|
-
<Personalization
|
|
191
|
+
<Personalization query="user's persona is 'developer'" fallback={false}>
|
|
190
192
|
{(isDeveloper: boolean) => (
|
|
191
193
|
<Fragment>
|
|
192
194
|
{isDeveloper && <a href="/docs">View docs</a>}
|
|
@@ -195,7 +197,7 @@ export default function OnboardingPage(): ReactElement {
|
|
|
195
197
|
</Personalization>
|
|
196
198
|
|
|
197
199
|
{/* Using useEvaluation hook */}
|
|
198
|
-
<ViewDocsLink
|
|
200
|
+
<ViewDocsLink/>
|
|
199
201
|
</Suspense>
|
|
200
202
|
)
|
|
201
203
|
}
|
|
@@ -205,7 +207,7 @@ For a full list of the available options, please refer to the [API documentation
|
|
|
205
207
|
|
|
206
208
|
### Using slots
|
|
207
209
|
|
|
208
|
-
Evaluating
|
|
210
|
+
Evaluating query is a flexible and powerful way to customize your UI. However, for components whose content
|
|
209
211
|
changes too often, this approach can be overkill. For those cases, we encourage you to use the Slots feature instead.
|
|
210
212
|
Using slots gives your team the flexibility to change the content or personalization rules whenever needed without
|
|
211
213
|
touching the component code.
|
|
@@ -240,19 +242,23 @@ import {ReactElement, Suspense} from 'react';
|
|
|
240
242
|
import {Slot} from '@croct/plug-react';
|
|
241
243
|
|
|
242
244
|
type HomeBannerContent = {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
title: string,
|
|
246
|
+
subtitle: string,
|
|
247
|
+
cta: {
|
|
248
|
+
label: string,
|
|
249
|
+
link: string,
|
|
250
|
+
},
|
|
249
251
|
};
|
|
250
252
|
|
|
251
253
|
export default function OnboardingPage(): ReactElement {
|
|
252
254
|
return (
|
|
253
255
|
<Suspense fallback="✨ Personalizing content...">
|
|
254
256
|
<Slot id="home-banner">
|
|
255
|
-
{({
|
|
257
|
+
{({
|
|
258
|
+
title,
|
|
259
|
+
subtitle,
|
|
260
|
+
cta
|
|
261
|
+
}: HomeBannerContent) => (
|
|
256
262
|
<div>
|
|
257
263
|
<strong>{title}</strong>
|
|
258
264
|
<p>{subtitle}</p>
|
|
@@ -272,26 +278,26 @@ import {ReactElement} from 'react';
|
|
|
272
278
|
import {Slot} from '@croct/plug-react';
|
|
273
279
|
|
|
274
280
|
type HomeBannerContent = {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
+
title: string,
|
|
282
|
+
subtitle: string,
|
|
283
|
+
cta: {
|
|
284
|
+
label: string,
|
|
285
|
+
link: string,
|
|
286
|
+
},
|
|
281
287
|
};
|
|
282
288
|
|
|
283
289
|
export default function OnboardingPage(): ReactElement {
|
|
284
290
|
return (
|
|
285
291
|
<Slot id="home-banner" initial={null}>
|
|
286
|
-
{(props: HomeBannerContent|null) => (
|
|
287
|
-
props === null
|
|
292
|
+
{(props: HomeBannerContent | null) => (
|
|
293
|
+
props === null
|
|
288
294
|
? '✨ Personalizing...'
|
|
289
295
|
: (
|
|
290
296
|
<div>
|
|
291
297
|
<strong>{props.title}</strong>
|
|
292
298
|
<p>{props.subtitle}</p>
|
|
293
299
|
<a href={props.cta.link}>{props.cta.label}</a>
|
|
294
|
-
</div>
|
|
300
|
+
</div>
|
|
295
301
|
)
|
|
296
302
|
)}
|
|
297
303
|
</Slot>
|
|
@@ -306,16 +312,20 @@ import {ReactElement, Suspense} from 'react';
|
|
|
306
312
|
import {useContent} from '@croct/plug-react';
|
|
307
313
|
|
|
308
314
|
type HomeBannerContent = {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
+
title: string,
|
|
316
|
+
subtitle: string,
|
|
317
|
+
cta: {
|
|
318
|
+
label: string,
|
|
319
|
+
link: string,
|
|
320
|
+
},
|
|
315
321
|
};
|
|
316
322
|
|
|
317
323
|
function HomeBanner(): ReactElement {
|
|
318
|
-
const {
|
|
324
|
+
const {
|
|
325
|
+
title,
|
|
326
|
+
subtitle,
|
|
327
|
+
cta
|
|
328
|
+
} = useContent<HomeBannerContent>('home-banner');
|
|
319
329
|
|
|
320
330
|
return (
|
|
321
331
|
<div>
|
|
@@ -335,6 +345,15 @@ export default function HomePage(): ReactElement {
|
|
|
335
345
|
}
|
|
336
346
|
```
|
|
337
347
|
|
|
348
|
+
You can specify the version of the slot by passing a versioned ID in the form `id@version`. For example,
|
|
349
|
+
passing `home-banner@1` will fetch the content for the `home-banner` slot in version 1. Not specifying a
|
|
350
|
+
version number is the same as passing `home-banner@latest`, which will load the latest version of the slot.
|
|
351
|
+
|
|
352
|
+
> ✅ Best practice
|
|
353
|
+
> It's strongly recommended to specify a slot version for production deployments.
|
|
354
|
+
> That way, you ensure the front end will always receive content with the expected
|
|
355
|
+
> schema while your team can freely evolve the content's schema in parallel.
|
|
356
|
+
|
|
338
357
|
#### Fault tolerance
|
|
339
358
|
|
|
340
359
|
The following example shows how you can specify a fallback state for the `home-banner` slot:
|
|
@@ -344,12 +363,12 @@ import {ReactElement, Suspense} from 'react';
|
|
|
344
363
|
import {Slot, useContent} from '@croct/plug-react';
|
|
345
364
|
|
|
346
365
|
type HomeBannerContent = {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
366
|
+
title: string,
|
|
367
|
+
subtitle: string,
|
|
368
|
+
cta: {
|
|
369
|
+
label: string,
|
|
370
|
+
link: string,
|
|
371
|
+
},
|
|
353
372
|
};
|
|
354
373
|
|
|
355
374
|
const fallbackBanner: HomeBannerContent = {
|
|
@@ -362,7 +381,11 @@ const fallbackBanner: HomeBannerContent = {
|
|
|
362
381
|
};
|
|
363
382
|
|
|
364
383
|
function HomeBanner(): ReactElement {
|
|
365
|
-
const {
|
|
384
|
+
const {
|
|
385
|
+
title,
|
|
386
|
+
subtitle,
|
|
387
|
+
cta
|
|
388
|
+
} = useContent<HomeBannerContent>('home-banner', {fallback: fallbackBanner});
|
|
366
389
|
|
|
367
390
|
return (
|
|
368
391
|
<div>
|
|
@@ -378,7 +401,11 @@ export default function HomePage(): ReactElement {
|
|
|
378
401
|
<Suspense fallback="Personalizing content...">
|
|
379
402
|
{/* Using the <Slot /> component */}
|
|
380
403
|
<Slot id="home-banner" fallback={fallbackBanner}>
|
|
381
|
-
{({
|
|
404
|
+
{({
|
|
405
|
+
title,
|
|
406
|
+
subtitle,
|
|
407
|
+
cta
|
|
408
|
+
}: HomeBannerContent) => (
|
|
382
409
|
<div>
|
|
383
410
|
<strong>{title}</strong>
|
|
384
411
|
<p>{subtitle}</p>
|
|
@@ -388,13 +415,14 @@ export default function HomePage(): ReactElement {
|
|
|
388
415
|
</Slot>
|
|
389
416
|
|
|
390
417
|
{/* Using the useContent hook */}
|
|
391
|
-
<HomeBanner
|
|
418
|
+
<HomeBanner/>
|
|
392
419
|
</Suspense>
|
|
393
420
|
)
|
|
394
421
|
}
|
|
395
422
|
```
|
|
396
423
|
|
|
397
|
-
Again, we strongly recommend always providing a value for the `fallback` property. For a full list of the available
|
|
424
|
+
Again, we strongly recommend always providing a value for the `fallback` property. For a full list of the available
|
|
425
|
+
options,
|
|
398
426
|
please refer to the [API documentation](#component-api-reference).
|
|
399
427
|
|
|
400
428
|
#### 💡 ProTip
|
|
@@ -407,11 +435,10 @@ using module augmentation as follows:
|
|
|
407
435
|
|
|
408
436
|
```ts
|
|
409
437
|
// slots.d.ts
|
|
410
|
-
import {NullableJsonObject} from '@croct/plug/sdk/json';
|
|
411
438
|
import {HomeBanner} from './HomePage';
|
|
412
439
|
|
|
413
|
-
declare module '@croct/plug/
|
|
414
|
-
interface SlotMap
|
|
440
|
+
declare module '@croct/plug/slot' {
|
|
441
|
+
interface SlotMap {
|
|
415
442
|
'home-banner': HomeBanner;
|
|
416
443
|
}
|
|
417
444
|
}
|
|
@@ -428,12 +455,15 @@ You can use the same components and hooks on the server-side by simply providing
|
|
|
428
455
|
pre-render on the server - the personalization happens transparently on the client during the initial render.
|
|
429
456
|
That means it's SEO friendly and can be cached with no performance overhead.
|
|
430
457
|
|
|
431
|
-
Notice that the methods exposed by the Plug work only on the client-side. Therefore, if you are
|
|
432
|
-
|
|
458
|
+
Notice that the methods exposed by the Plug work only on the client-side. Therefore, if you are
|
|
459
|
+
using [`useCroct`](#usecroct),
|
|
460
|
+
the operations have to be executed inside the `useEffect` hook or client-side callbacks, such as `onClick` or `onChange`
|
|
461
|
+
, for example.
|
|
433
462
|
|
|
434
463
|
### Accessing the Plug instance
|
|
435
464
|
|
|
436
|
-
This library is built on top of the PlugJS. You can access the Plug instance through the `useCroct` hook to track
|
|
465
|
+
This library is built on top of the PlugJS. You can access the Plug instance through the `useCroct` hook to track
|
|
466
|
+
events,
|
|
437
467
|
login and logout users, and more.
|
|
438
468
|
|
|
439
469
|
In the following example we use the `useCroct` to get the Plug instance and set an attribute to the user profile:
|
|
@@ -461,7 +491,7 @@ This reference documents all components available in the library.
|
|
|
461
491
|
|
|
462
492
|
### <CroctProvider />
|
|
463
493
|
|
|
464
|
-
The `<CroctProvider />` component
|
|
494
|
+
The `<CroctProvider />` component leverages [React's Context API](https://reactjs.org/docs/context.html) to
|
|
465
495
|
make a configured [Plug instance](https://github.com/croct-tech/plug-js/blob/master/docs/plug.md) available throughout
|
|
466
496
|
a React component tree.
|
|
467
497
|
|
|
@@ -471,18 +501,19 @@ The component takes the followings properties:
|
|
|
471
501
|
|
|
472
502
|
| Option | Type | Required | Default Value | Description |
|
|
473
503
|
|-------------------------|--------------|----------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
474
|
-
| `appId` | string | Yes | None | The ID of the application you set up on Croct.
|
|
504
|
+
| `appId` | string | Yes | None | The ID of the application you set up on Croct. |
|
|
475
505
|
| `debug` | boolean | No | `false` | If `true`, turns on debug mode, which logs helpful messages to the console. |
|
|
476
|
-
| `track` | boolean | No | `true` | If `true`, enables the automatic event tracking on initialization.
|
|
477
|
-
| `
|
|
478
|
-
| `
|
|
479
|
-
| `
|
|
480
|
-
| `
|
|
481
|
-
| `
|
|
482
|
-
| `
|
|
483
|
-
| `
|
|
484
|
-
| `
|
|
485
|
-
| `
|
|
506
|
+
| `track` | boolean | No | `true` | If `true`, enables the automatic event tracking on initialization. |
|
|
507
|
+
| `clientId` | string | No | None | The ID of the client using the application. |
|
|
508
|
+
| `token` | string\|null | No | None | The JWT token issued by Croct. If `null`, clears any token specified on previous calls. |
|
|
509
|
+
| `userId` | string | No | None | The ID of the user logged into the application. Internally, the SDK will issue a token using the specified ID as the subject claim of the token. The `token` and `userId` options are mutually exclusive. |
|
|
510
|
+
| `tokenScope` | string | No | `global` | Defines how the SDK should synchronize the token across multiple tabs, see [token scopes](#token-scopes) for more details. |
|
|
511
|
+
| `eventMetadata` | JSON | No | None | Any additional information that may be useful to include as part of the event metadata. A common use case is to record the version of the application for future reference. |
|
|
512
|
+
| `logger` | object | No | None | A custom logger to handle log messages. By default, all logs are suppressed. |
|
|
513
|
+
| `urlSanitizer` | function | No | None | A function to sanitize URLs that allows removing sensitive information from URLs, such as tokens, that should not be sent to the platform. |
|
|
514
|
+
| `trackerEndpointUrl` | string | No | None | The URL of the tracker service, used by Croct's development team for testing purposes. |
|
|
515
|
+
| `evaluationEndpointUrl` | string | No | None | The URL of the evaluation service, used by Croct's development team for testing purposes. |
|
|
516
|
+
| `bootstrapEndpointUrl` | string | No | None | The URL of the bootstrap service, used by Croct's development team for testing purposes. |
|
|
486
517
|
|
|
487
518
|
#### Code Sample
|
|
488
519
|
|
|
@@ -512,16 +543,16 @@ The `<Personalization />` component evaluates and renders a CQL query.
|
|
|
512
543
|
|
|
513
544
|
The component takes the followings properties:
|
|
514
545
|
|
|
515
|
-
| Option | Type | Required | Description
|
|
516
|
-
|
|
517
|
-
| `
|
|
518
|
-
| `children` | Function | Yes | A callback to render the result.
|
|
519
|
-
| `fallback` | Result | No | A value to render when the evaluation fails. If not specified, the hook will throw an exception in case of failures.
|
|
520
|
-
| `initial` | Result | SSR only | A value to render while loading, required for server-side rendering. If not specified, the rendering will suspend.
|
|
521
|
-
| `timeout` | number | No | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail.
|
|
522
|
-
| `attributes` | JSON | No | A map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in
|
|
523
|
-
| `cacheKey` | string | No | An identifier that allows keeping the cached result separate from other cached items. By default, the cache key is formed from the
|
|
524
|
-
| `expiration` | number | No | The cache expiration time in milliseconds, extended on every render. If negative, the cache never expires. By default, the cache lifespan is set to 60000 (1 minute).
|
|
546
|
+
| Option | Type | Required | Description |
|
|
547
|
+
|--------------|----------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
548
|
+
| `query` | string | Yes | The CQL query to evaluate. |
|
|
549
|
+
| `children` | Function | Yes | A callback to render the result. |
|
|
550
|
+
| `fallback` | Result | No | A value to render when the evaluation fails. If not specified, the hook will throw an exception in case of failures. |
|
|
551
|
+
| `initial` | Result | SSR only | A value to render while loading, required for server-side rendering. If not specified, the rendering will suspend. |
|
|
552
|
+
| `timeout` | number | No | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail. |
|
|
553
|
+
| `attributes` | JSON | No | A map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in queries like `context's cities include location's city`. |
|
|
554
|
+
| `cacheKey` | string | No | An identifier that allows keeping the cached result separate from other cached items. By default, the cache key is formed from the query and attributes. |
|
|
555
|
+
| `expiration` | number | No | The cache expiration time in milliseconds, extended on every render. If negative, the cache never expires. By default, the cache lifespan is set to 60000 (1 minute). |
|
|
525
556
|
|
|
526
557
|
#### Code Sample
|
|
527
558
|
|
|
@@ -533,7 +564,7 @@ import {Personalization} from '@croct/plug-react';
|
|
|
533
564
|
|
|
534
565
|
function PersonaBadge(): ReactElement {
|
|
535
566
|
return (
|
|
536
|
-
<Personalization
|
|
567
|
+
<Personalization query="user's persona or else 'unknown'">
|
|
537
568
|
{persona => (<span>{persona}</span>)}
|
|
538
569
|
</Personalization>
|
|
539
570
|
);
|
|
@@ -548,14 +579,15 @@ The `<Slot />` component fetches and renders a slot.
|
|
|
548
579
|
|
|
549
580
|
The component takes the followings properties:
|
|
550
581
|
|
|
551
|
-
| Option
|
|
552
|
-
|
|
553
|
-
| `id`
|
|
554
|
-
| `children`
|
|
555
|
-
| `fallback`
|
|
556
|
-
| `
|
|
557
|
-
| `
|
|
558
|
-
| `
|
|
582
|
+
| Option | Type | Required | Description |
|
|
583
|
+
|-------------------|----------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
584
|
+
| `id` | string | Yes | The ID of the slot to fetch. |
|
|
585
|
+
| `children` | Function | Yes | A callback to render the result. |
|
|
586
|
+
| `fallback` | Result | No | A value to render when the fetch fails. If not specified, the hook will throw an exception in case of failures. |
|
|
587
|
+
| `preferredLocale` | string | No | The preferred locale to fetch. If not specified or not available, the hook will fetch the default locale. |
|
|
588
|
+
| `initial` | Result | SSR only | A value to render while loading, required for server-side rendering. If not specified, the rendering will suspend. |
|
|
589
|
+
| `cacheKey` | string | No | An identifier that allows keeping the cached result separate from other cached items. By default, the cache key is formed from the query and attributes. |
|
|
590
|
+
| `expiration` | number | No | The cache expiration time in milliseconds, extended on every render. If negative, the cache never expires. By default, the cache lifespan is set to 60000 (1 minute). |
|
|
559
591
|
|
|
560
592
|
#### Code Sample
|
|
561
593
|
|
|
@@ -568,7 +600,10 @@ import {Slot} from '@croct/plug-react';
|
|
|
568
600
|
function HeroBanner(): ReactElement {
|
|
569
601
|
return (
|
|
570
602
|
<Slot id="hero">
|
|
571
|
-
{({
|
|
603
|
+
{({
|
|
604
|
+
title,
|
|
605
|
+
subtitle
|
|
606
|
+
}) => (
|
|
572
607
|
<div>
|
|
573
608
|
<h1>{title}</h1>
|
|
574
609
|
<p>{subtitle}</p>
|
|
@@ -620,18 +655,18 @@ The `useEvaluation` hook evaluates a CQL query.
|
|
|
620
655
|
The hook has the following signature:
|
|
621
656
|
|
|
622
657
|
```ts
|
|
623
|
-
function useEvaluation<Result extends JsonValue>(
|
|
658
|
+
function useEvaluation<Result extends JsonValue>(query: string, options: Options = {}): Result
|
|
624
659
|
```
|
|
625
660
|
|
|
626
661
|
These are the currently supported options:
|
|
627
662
|
|
|
628
|
-
| Option | Type
|
|
629
|
-
|
|
630
|
-
| `fallback` | Result
|
|
631
|
-
| `timeout` | number
|
|
632
|
-
| `attributes` | JSON
|
|
633
|
-
| `cacheKey` | string
|
|
634
|
-
| `expiration` | number
|
|
663
|
+
| Option | Type | Description |
|
|
664
|
+
|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
665
|
+
| `fallback` | Result | The value returned when the evaluation fails. If not specified, the hook will throw an exception in case of failures. |
|
|
666
|
+
| `timeout` | number | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail. |
|
|
667
|
+
| `attributes` | JSON | The map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in querys like `context's cities include location's city`. |
|
|
668
|
+
| `cacheKey` | string | An identifier that allows keeping the cached result separate from other cached items. By default, the cache key is formed from the query and attributes. |
|
|
669
|
+
| `expiration` | number | The cache expiration time in milliseconds, extended on every render. If negative, the cache never expires. By default, the cache lifespan is set to 60000 (1 minute). |
|
|
635
670
|
|
|
636
671
|
#### Code Sample
|
|
637
672
|
|
|
@@ -657,16 +692,18 @@ The `useContent` hook fetches the content of a slot.
|
|
|
657
692
|
The hook has the following signature:
|
|
658
693
|
|
|
659
694
|
```ts
|
|
660
|
-
function useContent
|
|
695
|
+
function useContent(slotId: string, options: Options = {}): JsonObject
|
|
661
696
|
```
|
|
662
697
|
|
|
663
698
|
These are the currently supported options:
|
|
664
699
|
|
|
665
|
-
| Option
|
|
666
|
-
|
|
667
|
-
| `fallback`
|
|
668
|
-
| `
|
|
669
|
-
| `
|
|
700
|
+
| Option | Type | Description |
|
|
701
|
+
|-------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
702
|
+
| `fallback` | Content | The content returned when the fetch fails. If not specified, the hook will throw an exception in case of failures. |
|
|
703
|
+
| `preferredLocale` | string | The preferred locale to fetch. If not specified or not available, the hook will fetch the default locale. |
|
|
704
|
+
| `cacheKey` | string | An identifier that allows keeping the cached content separate from other cached items. By default, the cache key is formed from the slot ID. |
|
|
705
|
+
| `expiration` | number | The cache expiration time in milliseconds, extended on every render. If negative, the cache never expires. By default, the cache lifespan is set to 60000 (1 minute). |
|
|
706
|
+
|
|
670
707
|
|
|
671
708
|
#### Code Sample
|
|
672
709
|
|
|
@@ -686,7 +723,10 @@ type HomeBannerContent = {
|
|
|
686
723
|
};
|
|
687
724
|
|
|
688
725
|
export default function HeroBanner(): ReactElement {
|
|
689
|
-
const {
|
|
726
|
+
const {
|
|
727
|
+
title,
|
|
728
|
+
subtitle
|
|
729
|
+
} = useContent<HomeBannerContent>('hero');
|
|
690
730
|
|
|
691
731
|
return (
|
|
692
732
|
<div>
|
|
@@ -697,6 +737,103 @@ export default function HeroBanner(): ReactElement {
|
|
|
697
737
|
}
|
|
698
738
|
```
|
|
699
739
|
|
|
740
|
+
## Standalone function reference
|
|
741
|
+
|
|
742
|
+
This reference documents all standalone functions available in the library.
|
|
743
|
+
|
|
744
|
+
### evaluate
|
|
745
|
+
|
|
746
|
+
The `evaluate` function evaluates a CQL query on the server-side and returns the result.
|
|
747
|
+
|
|
748
|
+
#### Signature
|
|
749
|
+
|
|
750
|
+
The function has the following signature:
|
|
751
|
+
|
|
752
|
+
```ts
|
|
753
|
+
function evaluate(query: string, options: EvaluationOptions): Promise<JsonValue>
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
These are the currently supported options:
|
|
757
|
+
|
|
758
|
+
| Option | Type | Required | Description |
|
|
759
|
+
|----------------------------|--------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
760
|
+
| `apiKey` | string | Yes | The private API key of the application. This is a private key that should never be exposed to the client-side. |
|
|
761
|
+
| `fallback` | JSON | No | The value returned when the evaluation fails. If not specified, the function will throw an exception in case of failures. |
|
|
762
|
+
| `timeout` | number | No | The maximum evaluation time in milliseconds. Once reached, the evaluation will fail. |
|
|
763
|
+
| `clientId` | string | No | A UUID v4 that uniquely identifies the client across multiple evaluations. You should generate this identifier on your server-side using a random, cryptographically secure generator and ensure it doesn't change throughout the user journey (e.g. store in cookies). If not specified, the evaluation will run in an anonymous context. |
|
|
764
|
+
| `clientIp` | string | No | The IP address of the client to determine the location. The IP is only used to determine the location and then discarded. |
|
|
765
|
+
| `userAgent` | string | No | The user agent of the client to determine the device. |
|
|
766
|
+
| `userToken` | string | No | The token that uniquely identifies the user. You can use this to provide consistent experiences across multiple channels. |
|
|
767
|
+
| `context` | JSON | No | The evaluation context. |
|
|
768
|
+
| `context.timeZone` | string | No | The time zone of the client. |
|
|
769
|
+
| `context.campaign` | JSON | No | The marketing campaign that brought the user to the application. |
|
|
770
|
+
| `context.campaign.name` | string | No | The name of the campaign. |
|
|
771
|
+
| `context.campaign.source` | string | No | The source of the campaign. For example, "google", "newsletter", "facebook". |
|
|
772
|
+
| `context.campaign.medium` | string | No | The marketing medium. For example, "cpc", "banner", "ads". |
|
|
773
|
+
| `context.campaign.term` | string | No | The campaign keywords. For example, "smartphone online sale". |
|
|
774
|
+
| `context.campaign.content` | string | No | The campaign content. For example, "top-banner", "cta", "sidebar". |
|
|
775
|
+
| `context.page` | JSON | No | The page the user is currently viewing. |
|
|
776
|
+
| `context.page.url` | string | Yes | The URL of the page. |
|
|
777
|
+
| `context.page.title` | string | No | The title of the page. |
|
|
778
|
+
| `context.page.referrer` | string | No | The URL of the page that referred the user to the current page. |
|
|
779
|
+
| `context.attributes` | JSON | No | The map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in querys like `context's cities include location's city`. |
|
|
780
|
+
| `extra` | JSON | No | Additional [options](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters) to pass to the fetch function. |
|
|
781
|
+
|
|
782
|
+
#### Code Sample
|
|
783
|
+
|
|
784
|
+
Here's a simple example showing how to evaluate a CQL query:
|
|
785
|
+
|
|
786
|
+
```ts
|
|
787
|
+
import {evaluate} from '@croct/plug/api';
|
|
788
|
+
|
|
789
|
+
const result = await evaluate("user's persona", {
|
|
790
|
+
apiKey: process.env.CROCT_API_KEY,
|
|
791
|
+
});
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### fetchContent
|
|
795
|
+
|
|
796
|
+
The `fetchContent` function fetches the content for a slot on the server-side and returns the result.
|
|
797
|
+
|
|
798
|
+
#### Signature
|
|
799
|
+
|
|
800
|
+
The function has the following signature:
|
|
801
|
+
|
|
802
|
+
```ts
|
|
803
|
+
function fetchContent(slotId: string, options: FetchOptions): Promise<{content: JsonValue}>
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
These are the currently supported options:
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
| Option | Type | Required | Description |
|
|
810
|
+
|----------------------------|---------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
811
|
+
| `apiKey` | string | Yes | The private API key of the application. This is a private key that should never be exposed to the client-side. |
|
|
812
|
+
| `fallback` | JSON | No | The value returned when the fetch fails. If not specified, the function will throw an exception in case of failures. |
|
|
813
|
+
| `static` | boolean | No | Whether to fetch the static content. If not specified, the function will fetch the dynamic content. |
|
|
814
|
+
| `timeout` | number | No | The maximum fetch time in milliseconds. Once reached, the fetch will fail. |
|
|
815
|
+
| `previewToken` | string | No | The token that enables preview mode. |
|
|
816
|
+
| `preferredLocale` | string | No | The preferred locale to fetch. If not specified or not available, the hook will fetch the default locale. |
|
|
817
|
+
| `clientId` | string | No | A UUID v4 that uniquely identifies the client across multiple evaluations. You should generate this identifier on your server-side using a random, cryptographically secure generator and ensure it doesn't change throughout the user journey (e.g. store in cookies). If not specified, the evaluation will run in an anonymous context. |
|
|
818
|
+
| `clientIp` | string | No | The IP address of the client to determine the location. The IP is only used to determine the location and then discarded. |
|
|
819
|
+
| `userAgent` | string | No | The user agent of the client to determine the device. |
|
|
820
|
+
| `userToken` | string | No | The token that uniquely identifies the user. You can use this to provide consistent experiences across multiple channels. |
|
|
821
|
+
| `context` | JSON | No | The evaluation context. |
|
|
822
|
+
| `context.timeZone` | string | No | The time zone of the client. |
|
|
823
|
+
| `context.campaign` | JSON | No | The marketing campaign that brought the user to the application. |
|
|
824
|
+
| `context.campaign.name` | string | No | The name of the campaign. |
|
|
825
|
+
| `context.campaign.source` | string | No | The source of the campaign. For example, "google", "newsletter", "facebook". |
|
|
826
|
+
| `context.campaign.medium` | string | No | The marketing medium. For example, "cpc", "banner", "ads". |
|
|
827
|
+
| `context.campaign.term` | string | No | The campaign keywords. For example, "smartphone online sale". |
|
|
828
|
+
| `context.campaign.content` | string | No | The campaign content. For example, "top-banner", "cta", "sidebar". |
|
|
829
|
+
| `context.page` | JSON | No | The page the user is currently viewing. |
|
|
830
|
+
| `context.page.url` | string | Yes | The URL of the page. |
|
|
831
|
+
| `context.page.title` | string | No | The title of the page. |
|
|
832
|
+
| `context.page.referrer` | string | No | The URL of the page that referred the user to the current page. |
|
|
833
|
+
| `context.attributes` | JSON | No | The map of attributes to inject in the evaluation context. For example, passing the attributes `{cities: ['New York', 'San Francisco']}` you can reference them in querys like `context's cities include location's city`. |
|
|
834
|
+
| `extra` | JSON | No | Additional [options](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters) to pass to the fetch function. |
|
|
835
|
+
|
|
836
|
+
|
|
700
837
|
## Support
|
|
701
838
|
|
|
702
839
|
If this documentation has not answered all your questions, don't worry.
|
|
@@ -714,7 +851,8 @@ please [ask a new one](https://stackoverflow.com/questions/ask?tags=croct%20plug
|
|
|
714
851
|
If you have what looks like a bug, or you would like to make a feature request, please
|
|
715
852
|
[open a new issue on GitHub](https://github.com/croct-tech/plug-react/issues/new/choose).
|
|
716
853
|
|
|
717
|
-
Before you file an issue, a good practice is to search for issues to see whether others have the same or similar
|
|
854
|
+
Before you file an issue, a good practice is to search for issues to see whether others have the same or similar
|
|
855
|
+
problems.
|
|
718
856
|
If you are unable to find an open issue addressing the problem, then feel free to open a new one.
|
|
719
857
|
|
|
720
858
|
### Slack Channel
|