Step 2 of 10 (20% complete)
Tech Stack & Project Setup
Step Code
The code for this specific step can be found on the following branch:
Before diving into the code, let's go through what this starter uses and how to get it running locally.
Tech Stack
| Technology | Version | Role |
|---|---|---|
| Next.js | 16 | Framework (App Router) |
| React | 19 | UI runtime |
@optimizely/cms-sdk | ^1.0.0 | CMS integration — content types, GraphQL client, React registry |
@optimizely/cms-cli | ^1.0.0 | CLI for pushing content types to CMS |
| Tailwind CSS | ^4 | Styling |
| TypeScript | ^5 (strict) | Type safety |
| shadcn/ui + Radix UI | — | UI primitives |
The two most important packages are @optimizely/cms-sdk and @optimizely/cms-cli. Together they form the full integration loop between your code and the CMS:
@optimizely/cms-sdk— you use this in your application to define content types, fetch content from Optimizely Graph, and render it with React@optimizely/cms-cli— you use this as a developer tool to push the content type definitions from your code to your CMS instance, so that editors can work with them
Prerequisites
Before starting, you will need:
- Node.js 20 or later
- An Optimizely SaaS CMS instance
- An Optimizely Content Graph API key
- A Client ID and Client Secret from your CMS instance (for the CLI)
Getting the Project Running
1. Clone the repository
git clone https://github.com/szymonuryga/Optimizely-CMS-Content-SDK-Next.js-16.git cd Optimizely-CMS-Content-SDK-Next.js-15
2. Install dependencies
npm install
3. Configure environment variables
Copy .env.example to .env and fill in your values:
cp .env.example .env
Here is a breakdown of every variable and where to get it:
# Used to communicate with Optimizely Content Graph (fetching content in the app). # Find it in your CMS instance: Settings > API Keys OPTIMIZELY_GRAPH_SINGLE_KEY="" # The Content Graph base URL. This value is always the same for production: OPTIMIZELY_GRAPH_URL="https://cg.optimizely.com/content/v2" # Used by @optimizely/cms-cli to authenticate when pushing content types to CMS. # Go to your CMS instance: Settings > API Keys > Create API key # Save the Client Secret immediately — you cannot retrieve it again after closing the dialog. OPTIMIZELY_CMS_CLIENT_ID="" OPTIMIZELY_CMS_CLIENT_SECRET="" # Root URL of your CMS instance. # Used to load the preview communication script for in-context editing. OPTIMIZELY_CMS_HOST="https://<your-instance>.cms.optimizely.com" # A secret string you choose yourself. # Added to the webhook URL so the revalidation endpoint can verify the request is legitimate. OPTIMIZELY_REVALIDATE_SECRET="" # Optional. The CMS route URL of your Start Page (e.g. "/start-page"). # The revalidation webhook maps this URL to "/" so the home page revalidates correctly. # In correctly configured SaaS CMS instances this should not be needed, # but older instances sometimes produce this URL pattern from the CMS. OPTIMIZELY_START_PAGE_URL=""
For more details on where to find these values, see the official documentation:
4. Push content types to CMS
This is the step that makes this starter special. Instead of defining content types manually in the Optimizely UI, you define them in code and push them with the CLI:
npm run opti-push
This reads your component files and pushes all contentType() definitions to your CMS instance. After this step, your blocks, pages, and experiences are ready to use in the editor.
npm run opti-push-data-loss
5. Start the development server
npm run dev
Open http://localhost:3000 in your browser.
Available Scripts
| Script | Description |
|---|---|
npm run dev | Start development server |
npm run build | Build for production |
npm run start | Start production server |
npm run format | Format code with Prettier |
npm run opti-push | Push content types to Optimizely CMS |
npm run opti-push-data-loss | Push content types with force (allows data loss) |
Have questions? I'm here to help!