Skip to content

Commit bf10ffb

Browse files
authored
Merge pull request #127 from episerver/bugfix/CMS-45749-sample-site
Add missing `key` (solves "every child should have a unique key prop" warning in React)
2 parents b0f3bdd + 97e713e commit bf10ffb

File tree

3 files changed

+65
-14
lines changed

3 files changed

+65
-14
lines changed

samples/fx-integration/README.md

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,80 @@
1-
This is a [Next.js](https://nextjs.org) project showcasing the integration between Optimizely CMS and Optimizely Feature Experimentation.
1+
This is a [Next.js](https://nextjs.org) project showcasing the integration between [Optimizely Content Management System (CMS)](https://docs.developers.optimizely.com/content-management-system/v1.0.0-CMS-SaaS/docs/overview-saas) and [Optimizely Feature Experimentation](https://docs.developers.optimizely.com/feature-experimentation/docs/introduction).
22

33
## Getting Started
44

55
You need a Optimizely CMS instance and Optimizely Feature Experimentation instance.
66

77
### Set up environment
88

9-
Create an `.env` file with the following environment variables:
9+
Create an `.env` file with the following content. You will learn how to get the values for the variables in the next steps.
1010

1111
```
1212
OPTIMIZELY_CMS_HOST=
1313
OPTIMIZELY_GRAPH_SINGLE_KEY=
1414
OPTIMIZELY_CMS_CLIENT_ID=
1515
OPTIMIZELY_CMS_CLIENT_SECRET=
16+
1617
OPTIMIZELY_FX_SDK_KEY=
18+
OPTIMIZELY_FX_ACCESS_TOKEN=
1719
```
1820

19-
Run `npm run cms:push-config` to create the content types (defined under the directory `/src/components/`)
21+
### CMS credentials
22+
23+
1. Put the URL of your CMS as the `OPTIMIZELY_CMS_HOST` variable. For example `https://app-1234.cms.optimizely.com/`
24+
2. Go to your CMS instance → Settings → API Keys.
25+
3. Under **Render Content**, the _Single Key_ variable, is the variable `OPTIMIZELY_GRAPH_SINGLE_KEY`
26+
4. In the same page, under **Manage Content**, click "Create API key".
27+
5. In the Create API dialog, give a name and click "Create API key"
28+
6. You will see Client ID and Client Secret. Those are the values for `OPTIMIZELY_CMS_CLIENT_ID` and `OPTIMIZELY_CMS_CLIENT_SECRET` variables respectively.
29+
30+
### Feature Experimentation credentials
31+
32+
In the Feature Experimentation app.
33+
34+
1. Go to Settings → Environmnents.
35+
2. The SDK Key for your environment is the variable `OPTIMIZELY_FX_SDK_KEY`.
36+
37+
> [!Note]
38+
> If the environment is _secured_, you will need an access token. Create it in the app and set it as the `OPTIMIZELY_FX_ACCESS_TOKEN` environment variable
39+
40+
## Push the content types model to the CMS
41+
42+
1. Run `npm run cms:login` to test your connection against the Optimizely CMS
43+
2. Run `npm run cms:push-config` to create the content types defined under `src/components` to the Optimizely CMS.
44+
45+
## Create variations in Feature Experimentation and CMS
46+
47+
This sample site assumes:
48+
49+
- There is a page under `/en/landing` that is running an experiment (i.e., different visitors will get different versions of the page)
50+
- The existance of a feature flag with the key `tv_genre` (the `tv_genre` contains the rules about which user will get which version)
51+
- Variations in Feature Experimentation have the same name as variations in CMS.
52+
53+
To reproduce it:
54+
55+
1. In Feature Experimentation, create a feature flag with key `tv_genre`. [Read the Feature Experimentation documentation](https://support.optimizely.com/hc/en-us/articles/38906082664077-Manage-flags) to be familiar with flags.
56+
2. In Feature Experimentation, create variations for the flag. [Read the Feature Experimentation docs to learn more about flag variations](https://support.optimizely.com/hc/en-us/articles/38676757193485-Create-flag-variations).
57+
58+
For example, create the variations `k_drama`, `action` and `sports`
59+
60+
3. In CMS, create a page with the content type `BlankExperience` with URL `landing`.
61+
4. In CMS, create variations for that page. You should use the names you used in FX to create variations in the CMS.
62+
63+
In this example, create the variations `k_drama`, `action` and `sports`
64+
65+
## Test your site
66+
67+
1. Run `npm run dev` to start the app
68+
2. Go to `https://localhost:3000/en/landing`. You should see a variation of the page.
69+
3. Open the inspector, locate the cookies and remove the cookie `user_id`.
70+
4. Refresh the page. You might see a different page variation (depending on the variation rules you have defined)
71+
72+
## Learn more about this sample site
2073

21-
Run `npm run dev` to start the development server
74+
- Inspect the file [`/src/lib.fx.ts`](./src/lib/fx.ts) to see the code that uses the Feature Experimentation SDK
75+
- Inspect the file [`/src/app/en/[...slug]/page.tsx`](./src/app/en/[...slug]/page.tsx) to learn how to fetch a specific variation from your CMS
2276

23-
### NPM scripts
77+
## Further reading
2478

25-
- `npm run cms:login` to test your connection agains the Optimizely CMS
26-
- `npm run cms:push-config` to create the content types defined here in the Optimizely CMS
79+
- [Optimizely Feature Experimentation JavaScript SDK](https://docs.developers.optimizely.com/feature-experimentation/docs/javascript-sdk)
80+
- [Create content variations in the Optimizely CMS](https://docs.developers.optimizely.com/content-management-system/v1.0.0-CMS-SaaS/docs/create-content-variation)

samples/fx-integration/src/components/FxHero.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export default function FxHero({ opti }: Props) {
2929
<p>{opti.subtitle}</p>
3030

3131
<div className={css.ctas}>
32-
{opti.ctas?.map((cta) => (
33-
<OptimizelyComponent opti={cta} />
32+
{opti.ctas?.map((cta, i) => (
33+
<OptimizelyComponent key={i} opti={cta} />
3434
))}
3535
</div>
3636
</div>

samples/fx-integration/src/lib/fx.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ import {
99
import { cookies } from 'next/headers';
1010

1111
const SDK_KEY = process.env.OPTIMIZELY_FX_SDK_KEY!;
12+
const ACCESS_TOKEN = process.env.OPTIMIZELY_FX_ACCESS_TOKEN;
1213

1314
const pollingConfigManager = createPollingProjectConfigManager({
1415
sdkKey: SDK_KEY,
16+
datafileAccessToken: ACCESS_TOKEN,
1517
autoUpdate: true,
1618
updateInterval: 60000, // 1 minute
1719
});
@@ -66,11 +68,6 @@ export async function getVariation(path: string) {
6668
if (!ruleset) {
6769
return null;
6870
}
69-
console.log(
70-
'Path: "%s". Running an experiment with ruleset "%s"',
71-
path,
72-
ruleset
73-
);
7471

7572
const user = await getUserContext();
7673
const decision = user.decide(ruleset);

0 commit comments

Comments
 (0)