Quick start guide: Next.js/React
Learn how to connect your GraphQL endpoint, query content, and display Content Management System Software as a Service (CMS SaaS) data using Apollo Client.
Integrate a Next.js project with Optimizely Content Management System Software as a Service (CMS SaaS) using Apollo Client. Configure a GraphQL client with cached templates, create reusable components to fetch content and landing pages, and render them efficiently in your application. This set up ensures type safety, optimized queries, and a streamlined developer experience for managing content in CMS.
Prerequisites
Before you begin, ensure that you have:
- Node.js (v18 or higher)
- An Optimizely CMS SaaS instance
- API key and Optimizely Graph endpoint
1. Create a Next.js project
npx create-next-app@latest my-saas-cms-site
cd my-saas-cms-site2. Install GraphQL dependencies
npm install @apollo/client graphql3. Set up Apollo Client with cached templates
Create a file named lib/apollo-client.ts and add:
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
const httpLink = new HttpLink({
uri: 'https://beta.cg.optimizely.com/content/v2?auth=<<INSERT_YOUR_KEY_HERE>>&stored=true',
headers: {
// Enable cached templates for better performance
'cg-stored-query': 'template',
}
});
const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
errorPolicy: 'all',
},
query: {
errorPolicy: 'all',
},
},
});
export default client;4. Configure environment variables
Create a .env.local file and add:
NEXT_PUBLIC_OPTIMIZELY_GRAPH_ENDPOINT=https://beta.cg.optimizely.com/content/v2?auth=<<INSERT_YOUR_KEY_HERE>>&stored=true5. Create your first component
Create a file named components/ContentList.tsx and add:
import { gql } from '@apollo/client';
import { useQuery } from '@apollo/client/react';
const GET_CONTENT = gql`
query GetContent($locale: [Locales], $skip: Int = 0, $limit: Int = 10) {
_Content(
locale: $locale
orderBy: { _metadata: { lastModified: DESC } }
skip: $skip
limit: $limit
) {
items {
_metadata {
displayName
url {
default
}
types
published
}
}
total
}
}
`;
export function ContentList() {
const { loading, error, data } = useQuery(GET_CONTENT, {
variables: { locale: ['en', 'NEUTRAL'] },
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>Latest content from SaaS CMS</h1>
<p>Total content items: {data._Content.total}</p>
{data._Content.items.map((item, index) => (
<div
key={index}
style={{
marginBottom: '1rem',
padding: '1rem',
border: '1px solid #ccc',
}}
>
<h3>{item._metadata.displayName}</h3>
<p>
<strong>Type:</strong> {item._metadata.types?.join(', ')}
</p>
<p>
<strong>URL:</strong> {item._metadata.url?.default}
</p>
<p>
<strong>Published:</strong>{' '}
{new Date(item._metadata.published).toLocaleDateString()}
</p>
{item._metadata.url?.default && (
<a
href={item._metadata.url.default}
target="_blank"
rel="noopener noreferrer"
>
View content →
</a>
)}
</div>
))}
</div>
);
}6. Create a landing page component
Create a file named components/LandingPageList.tsx and add:
import { gql } from '@apollo/client';
import { useQuery } from '@apollo/client/react';
const GET_LANDING_PAGES = gql`
query GetLandingPages($locale: Locales) {
LandingPage(locale: [$locale]) {
items {
_metadata {
displayName
url {
default
}
published
}
}
total
}
}
`;
export function LandingPageList() {
const { loading, error, data } = useQuery(GET_LANDING_PAGES, {
variables: { locale: 'en' },
});
if (loading) return <p>Loading landing pages...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h2>Landing pages</h2>
<p>Total landing pages: {data.LandingPage.total}</p>
{data.LandingPage.items.map((page, index) => (
<div
key={index}
style={{
marginBottom: '1rem',
padding: '1rem',
border: '1px solid #ccc',
}}
>
<h3>{page._metadata.displayName}</h3>
<p>
<strong>URL:</strong> {page._metadata.url?.default}
</p>
<p>
<strong>Published:</strong>{' '}
{new Date(page._metadata.published).toLocaleDateString()}
</p>
{page._metadata.url?.default && (
<a
href={page._metadata.url.default}
target="_blank"
rel="noopener noreferrer"
>
View page →
</a>
)}
</div>
))}
</div>
);
}7. Use the components in your page
In app/page.tsx, import and render the components:
'use client';
import { ApolloProvider } from '@apollo/client/react';
import client from '../lib/apollo-client';
import { ContentList } from '../components/ContentList';
import { LandingPageList } from '../components/LandingPageList';
export default function Home() {
return (
<ApolloProvider client={client}>
<div style={{ padding: '2rem' }}>
<h1>Mosey Bank CMS content</h1>
<ContentList />
<hr style={{ margin: '2rem 0' }} />
<LandingPageList />
</div>
</ApolloProvider>
);
}Result
Run the project locally:
npm run devOpen your Localhost to see your content and landing pages loaded from Optimizely Graph.
Updated 16 days ago
