Basic Starter
Get started quickly using a simple blog template built with best practices.
A complete guide to setting up and running your Agility CMS + Next.js website locally and deploying to production.
Before you begin, ensure you have the following installed:
The fastest way to get started is to deploy first, then clone and work locally:
Log in to your Agility CMS instance
Navigate to Settings > Deployment
Click "Setup Deployment" for Vercel
Follow the automated deployment wizard
Clone your repository locally
git clone https://github.com/YOUR-USERNAME/YOUR-REPO-NAME.git
cd YOUR-REPO-NAME
npm install
Copy environment variables from Vercel
.env.local tab.env.local (see below)If you prefer to start with local development:
Clone this repository
git clone https://github.com/agility/agilitycms-nextjs-starter.git
cd agilitycms-nextjs-starter
Install dependencies
npm install
Get your Agility CMS credentials
Create your environment file
Copy .env.local.example to .env.local:
cp .env.local.example .env.local
Then edit .env.local with your credentials:
# Your Agility CMS Instance GUID
AGILITY_GUID=your-guid-here
# API Keys (from Settings > API Keys)
AGILITY_API_FETCH_KEY=your-live-api-key
AGILITY_API_PREVIEW_KEY=your-preview-api-key
# Security Key (for webhooks and preview mode)
AGILITY_SECURITY_KEY=your-security-key
# Locales (comma-separated list, first is default)
AGILITY_LOCALES=en-us
# Sitemap reference name (usually 'website')
AGILITY_SITEMAP=website
# Cache durations (in seconds)
AGILITY_FETCH_CACHE_DURATION=120
AGILITY_PATH_REVALIDATE_DURATION=60
Run the development server
npm run dev
Open your browser
Navigate to http://localhost:3000
You should see your site with the sample content from your Agility instance!
Start the Next.js development server:
npm run dev
Features in dev mode:
Test a production build locally:
# Build the site
npm run build
# Start the production server
npm start
The build process will:
.next/ directoryagilitycms-nextjs-starter/
├── app/ # Next.js App Router
│ ├── layout.tsx # Root layout (header, footer)
│ ├── page.tsx # Homepage
│ ├── [...slug]/ # Dynamic catch-all route
│ │ ├── page.tsx # Page renderer
│ │ ├── error.tsx # Error boundary
│ │ └── not-found.tsx # 404 page
│ └── api/ # API routes
│ ├── preview/ # Preview mode activation
│ ├── revalidate/ # Webhook handler
│ └── dynamic-redirect/ # ContentID redirects
│
├── components/
│ ├── agility-components/ # CMS modules (registered)
│ │ ├── index.ts # Module registry
│ │ ├── Heading.tsx
│ │ ├── RichTextArea.tsx
│ │ ├── PostsListing/
│ │ └── ...
│ ├── agility-pages/ # Page templates
│ │ ├── index.ts # Template registry
│ │ └── MainTemplate.tsx
│ └── common/ # Shared UI components
│ ├── SiteHeader.tsx
│ ├── SiteFooter.tsx
│ ├── PreviewBar.tsx
│ └── ...
│
├── lib/
│ ├── cms/ # Generic CMS utilities
│ │ ├── getAgilitySDK.ts
│ │ ├── getContentItem.ts
│ │ ├── getContentList.ts
│ │ └── ...
│ ├── cms-content/ # Domain-specific queries
│ │ ├── getPostListing.ts
│ │ ├── getHeaderContent.ts
│ │ └── ...
│ └── types/ # TypeScript interfaces
│ ├── IPost.ts
│ ├── IAuthor.ts
│ └── ...
│
├── docs/ # Documentation
├── public/ # Static assets
├── styles/ # Global styles
└── middleware.ts # Middleware (preview mode)
| File | Purpose |
|---|---|
app/[...slug]/page.tsx | Renders all content pages dynamically |
components/agility-components/index.ts | Registers CMS modules → React components |
components/agility-pages/index.ts | Registers page templates |
lib/cms/getAgilityPage.ts | Fetches complete page with layout |
middleware.ts | Handles preview mode and redirects |
.env.local | Environment variables (not committed) |
Agility CMS manages your sitemap
Build time: Static Generation
// app/[...slug]/page.tsx
export async function generateStaticParams() {
// Fetches all pages from Agility CMS
const sitemap = await getSitemapFlat({ languageCode: "en-us" });
// Returns paths: ['/', '/about', '/blog', '/blog/post-1', ...]
return sitemap.map((node) => ({
slug: node.pagePath.split("/").filter(Boolean),
}));
}
Next.js generates HTML for each path
/ → index.html/about → about.html/blog/post-1 → blog/post-1.htmlRuntime: Page Rendering
export default async function Page({ params }) {
// Get page data from Agility
const page = await getAgilityPage({
slug: params.slug.join("/")
});
// Render appropriate template
const Template = getPageTemplate(page.templateName);
return <Template page={page} />;
}
In Agility CMS:
In Next.js:
components/agility-components/Heading.tsxcomponents/agility-components/index.tsExample:
// components/agility-components/Heading.tsx
import { UnloadedModuleProps } from "@agility/nextjs";
interface IHeadingModule {
title: string;
subtitle?: string;
}
export default async function Heading({
module
}: UnloadedModuleProps) {
const { fields } = module as { fields: IHeadingModule };
return (
<section className="py-12">
<h1 className="text-5xl font-bold dark:text-white">
{fields.title}
</h1>
{fields.subtitle && (
<p className="text-xl text-gray-600 dark:text-gray-400">
{fields.subtitle}
</p>
)}
</section>
);
}
This starter uses a three-tier architecture:
Component
↓
Domain Helper (lib/cms-content/)
↓
CMS Utility (lib/cms/)
↓
Agility SDK
Example:
// Component
const posts = await getPostListing({ take: 10 });
// Domain Helper (lib/cms-content/getPostListing.ts)
export async function getPostListing({ take, skip }) {
const posts = await getContentList({
referenceName: "posts",
take,
skip
});
// Add computed fields (URLs, etc.)
return { posts: postsWithUrls };
}
// CMS Utility (lib/cms/getContentList.ts)
export async function getContentList({ referenceName }) {
const api = getAgilitySDK({ isPreview });
return await api.getContentList({ referenceName });
}
Why Vercel?
Deploy via Agility Integration:
Manual Vercel Deployment:
AGILITY_GUIDAGILITY_API_FETCH_KEYAGILITY_API_PREVIEW_KEYAGILITY_SECURITY_KEYAGILITY_LOCALESAGILITY_SITEMAPSetup Webhooks:
https://your-site.vercel.app/api/revalidatex-agility-webhook-secret: YOUR_AGILITY_SECURITY_KEYThis starter includes a GitHub Actions workflow for Azure Static Web Apps.
Deployment Steps:
Create Azure Static Web App
.nextConfigure Build
The included workflow at .github/workflows/azure-static-web-apps-wonderful-meadow-008797210.yml handles:
npm run build-swaSet Repository Secrets
In GitHub: Settings > Secrets and variables > Actions
Add:
AZURE_STATIC_WEB_APPS_API_TOKEN_WONDERFUL_MEADOW_008797210 (from Azure)AGILITY_API_FETCH_KEYAnd Variables:
AGILITY_GUIDAGILITY_LOCALESAGILITY_SITEMAPSetup Webhooks
In Agility CMS: Settings > Webhooks
https://your-site.azurestaticapps.net/api/revalidateDeploy to Netlify:
npm run build.nextSetup Webhooks: Same process as Vercel, using your Netlify URL.
You can deploy to any Node.js hosting:
npm run build
npm start
Requires:
Preview mode allows editors to see draft content before publishing.
Settings > Deployment:
https://your-site.vercel.apphttps://your-site.com (or Vercel URL)Editor clicks "Preview" in CMS
↓
Request: /page?agilitypreviewkey=SECRET&ContentID=123
↓
Middleware intercepts → /api/preview
↓
API validates key, enables draft mode
↓
Redirects to actual page URL
↓
Page renders with draft content
↓
Preview bar appears at top
Start dev server: npm run dev
Get a preview URL from any page in Agility CMS
Replace the domain:
https://your-site.com/about?agilitypreviewkey=...&ContentID=123
becomes
http://localhost:3000/about?agilitypreviewkey=...&ContentID=123
You should see:
Click "Exit Preview" in the preview bar, or visit:
http://localhost:3000/api/preview/exit
Add a new component:
# 1. Create component
touch components/agility-components/MyComponent.tsx
# 2. Register component
# Edit components/agility-components/index.ts
# 3. Create component model in Agility CMS
# Match the reference name to "MyComponent"
Add a new content model:
// 1. Define interface
// lib/types/IMyModel.ts
export interface IMyModel {
contentID: number;
title: string;
// ... fields
}
// 2. Create helper
// lib/cms-content/getMyData.ts
export async function getMyData() {
return await getContentList<IMyModel>({
referenceName: "mymodel"
});
}
Customize styling:
styles/globals.css for global stylestailwind.config.js for theme customizationError: "Missing environment variables"
.env.local file existsError: "Invalid API Key"
Error: "Module not found"
npm install to ensure dependencies are installedrm -rf .nextnpm run buildPreview not working:
AGILITY_SECURITY_KEY is set correctlyagilitypreviewkey paramCan't exit preview mode:
/api/preview/exit directlyChanges not appearing:
npm run dev.env.localOld content still showing:
/api/revalidate (POST)revalidate duration to expireSlow build times:
Slow page loads:
<AgilityPic>)npm run build (see output)/docs folderReady to build? Start by creating your first component! See COMPONENTS.md for a step-by-step guide.
The Next.js Blog Starter was built for developers who want to quickly start using Agility CMS with Next.js. You can save time and effort by using this template that is already integrated with Agility CMS.
It's simple - it's a bare-bones template but has enough examples in it for you to follow
Fast rendering - your website is exported to static HTML, so there's no more waiting for your web server to piece together and render your HTML
Optimized images - using the next/image component, it will only load the appropriately sized images for the device the user is using so smaller devices will load smaller images
Fast preview & builds - deploy your site to Vercel to take advantage of lightning-fast build & previews
In order to get started with the Starter, Sign Up for a Free Agility CMS account.

Select an Image
Once you've created an account, you will be able to create a new Instance based off of the Blog Starter with Next.js.

Select an Image
The easiest way to deploy a Next.js website to production is to use Vercel from the creators of Next.js. Vercel is an all-in-one platform with Global CDN supporting static & Jamstack deployment and Serverless Functions.
You can get your Next.js and Agility CMS website deployed with a Preview Environment setup within minutes from your Agility CMS Manager!
NoteYou will need to have a GitHub and a Vercel account to get your project deployed.
To start, head by going into Settings > Sitemaps, then click Setup Deployment.

Select an Image
Select the Vercel Automated Deployment to connect to Vercel and deploy your Next.js website.

Select an Image
First, create a Git Repository for your project to ensure you can easily update your project after deploying it.

Select an Image
Next, Install the Agility CMS integration that will authorize access between Vercel and your Agility CMS content so that we can automatically configure your Production and Preview domains, as well as set up your Environment Variables.

Select an Image
Lastly, Vercel will fetch the source code for the agilitycms-nextjs-starter and it will be cloned into your Git repository. Vercel will also build your project and upload/deploy your build output.

Select an Image
Once deployed you will be taken back to your Agility CMS Manager, and you will see that your Production and Preview domains have been set. You can click on the link to view your live site.

Select an Image
🎉 Congratulations! You've successfully deployed your Next.js and Agility CMS website to Vercel!

Select an Image
Once logged into Agility CMS, you'll want to grab your API credentials so your Next.js site can authenticate and retrieve data from your instance.
From your Agility CMS dashboard, click into Settings > API Keys.

Select an Image
Take note of your GUID, Live API Key, Preview API Key and Security Key credentials and copy these somewhere temporarily as you'll need to use them later.
Upon deploying your Next.js Site, a new GitHub repository will be created in your GitHub account containing the code for the Blog Starter.
If you are setting up the site without Deploy to Vercel, clone this repository.
# Your Instance ID AGILITY_GUID= # Your Live API Key AGILITY_API_FETCH_KEY= # Your Preview API Key AGILITY_API_PREVIEW_KEY= # Your Security Key AGILITY_API_SECURITY_KEY=
To run the site locally, run npm run dev or yarn dev to start up your development server. If successful, Next.js will compile your pages in real-time and you will be able to access the site in your browser on https://localhost:3000

Select an Image
Did you get a Build Error?If you get an error during the build, check your log and ensure that you've entered the correct GUID and API Keys, as well as renamed the env.local.example file to .env.local.