See Agility CMS in action. Watch a product demo
Using the Next.js Starter
A complete guide to setting up and running your Agility CMS + Next.js website locally and deploying to production.
Prerequisites
Before you begin, ensure you have the following installed:
- Node.js 20.x or higher - Download Node.js
- npm or yarn - Package manager (comes with Node.js)
- Git - Download Git
- Agility CMS Account - Sign up for free
Quick Start
Option 1: Deploy to Vercel First (Recommended)
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
- Authorize the Agility Integration with Vercel
- Select or create a Git repository
- Vercel will automatically:
- Clone this starter template
- Set up environment variables
- Deploy your site
- Configure preview and production domains
-
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
- Go to your Vercel project settings
- Copy the
.env.localtab - Or manually create
.env.local(see below)
Option 2: Start Locally First
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
- Log in to Agility CMS
- Go to Settings > API Keys
- Copy the following values:
- GUID - Your instance identifier
- Live API Key - For production content
- Preview API Key - For draft content
- Security Key - For webhooks and previews
-
Create your environment file
Copy
.env.local.exampleto.env.local:cp .env.local.example .env.localThen edit
.env.localwith 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!
Local Development
Development Server
Start the Next.js development server:
npm run dev
Features in dev mode:
- Hot module replacement (changes appear instantly)
- Real-time error reporting
- Source maps for debugging
- Draft content visible (uses Preview API Key)
Building for Production
Test a production build locally:
# Build the site
npm run build
# Start the production server
npm start
The build process will:
- Generate static pages from your Agility sitemap
- Optimize images and assets
- Create optimized JavaScript bundles
- Output to
.next/directory
Project Structure
agilitycms-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)
Key Files Explained
| 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) |
Understanding the Project
How Pages Are Generated
-
Agility CMS manages your sitemap
- Editors create pages in the CMS
- Each page has a URL, template, and content zones
-
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.html
-
Runtime: 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} />; }
How Components Work
In Agility CMS:
- Create a "Component Model" (e.g., "Heading")
- Define fields (e.g., "title", "subtitle")
- Add to pages via content zones
In Next.js:
- Create React component:
components/agility-components/Heading.tsx - Register in
components/agility-components/index.ts - Component automatically renders when added to pages
Example:
// 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>
);
}
Data Fetching Pattern
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 });
}
Deployment Options
Vercel (Recommended)
Why Vercel?
- Built by Next.js creators
- Zero-config deployments
- Automatic HTTPS
- Global CDN
- Instant rollbacks
- Built-in analytics
Deploy via Agility Integration:
- Go to Agility CMS > Settings > Deployment
- Click "Setup Deployment" for Vercel
- Follow the wizard (autorizes, sets env vars, deploys)
- Done! Your site is live.
Manual Vercel Deployment:
- Push your code to GitHub
- Go to vercel.com/new
- Import your repository
- Add environment variables:
AGILITY_GUIDAGILITY_API_FETCH_KEYAGILITY_API_PREVIEW_KEYAGILITY_SECURITY_KEYAGILITY_LOCALESAGILITY_SITEMAP
- Click "Deploy"
Setup Webhooks:
- After deployment, copy your site URL
- In Agility: Settings > Webhooks > Add Webhook
- URL:
https://your-site.vercel.app/api/revalidate - Events: "Content Published", "Content Deleted", "Page Modified"
- Add header:
x-agility-webhook-secret: YOUR_AGILITY_SECURITY_KEY
Azure Static Web Apps
This starter includes a GitHub Actions workflow for Azure Static Web Apps.
Deployment Steps:
-
Create Azure Static Web App
- Go to Azure Portal
- Create new Static Web App
- Connect to your GitHub repository
- Framework: Next.js
- Output location:
.next
-
Configure Build
The included workflow at
.github/workflows/azure-static-web-apps-wonderful-meadow-008797210.ymlhandles:- Building with
npm run build-swa - Setting environment variables
- Deploying to Azure
- Building with
-
Set Repository Secrets
In GitHub: Settings > Secrets and variables > Actions
Add:
AZURE_STATIC_WEB_APPS_API_TOKEN_WONDERFUL_MEADOW_008797210(from Azure)AGILITY_API_FETCH_KEY
And Variables:
AGILITY_GUIDAGILITY_LOCALESAGILITY_SITEMAP
-
Setup Webhooks
In Agility CMS: Settings > Webhooks
- URL:
https://your-site.azurestaticapps.net/api/revalidate - Same configuration as Vercel
- URL:
Netlify
Deploy to Netlify:
- Push code to GitHub
- Go to app.netlify.com/start
- Import your repository
- Build settings:
- Build command:
npm run build - Publish directory:
.next
- Build command:
- Add environment variables (same as Vercel)
- Deploy
Setup Webhooks: Same process as Vercel, using your Netlify URL.
Self-Hosted
You can deploy to any Node.js hosting:
npm run build
npm start
Requires:
- Node.js 20+ runtime
- Environment variables configured
- Reverse proxy (nginx, Apache)
Setting Up Preview Mode
Preview mode allows editors to see draft content before publishing.
1. Configure in Agility CMS
Settings > Deployment:
- Set Preview Domain:
https://your-site.vercel.app - Set Production Domain:
https://your-site.com(or Vercel URL) - Save changes
2. How Preview Works
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
3. Testing Preview Locally
-
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:
- Draft content visible
- Preview bar at top
- "Exit Preview" button
4. Exit Preview
Click "Exit Preview" in the preview bar, or visit:
http://localhost:3000/api/preview/exit
Next Steps
For Content Editors
- Create pages: Add pages via Agility CMS sitemap
- Add content: Use page modules to build your pages
- Preview changes: Click "Preview" before publishing
- Publish: Click "Publish" to make changes live
For Developers
- Read the architecture docs: ARCHITECTURE.md
- Create your first component: COMPONENTS.md
- Understand content models: CONTENT-MODELS.md
- AI development guide: QUICK-START-AI.md
Customize Your Site
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:
- Edit
styles/globals.cssfor global styles - Use Tailwind classes in components
- Modify
tailwind.config.jsfor theme customization
Troubleshooting
Build Errors
Error: "Missing environment variables"
- Check
.env.localfile exists - Verify all required variables are set
- Restart dev server after changes
Error: "Invalid API Key"
- Double-check API keys in Agility CMS
- Ensure you're using the correct instance GUID
- Try copying keys again (no extra spaces)
Error: "Module not found"
- Run
npm installto ensure dependencies are installed - Clear Next.js cache:
rm -rf .next - Rebuild:
npm run build
Preview Mode Issues
Preview not working:
- Verify
AGILITY_SECURITY_KEYis set correctly - Check preview domain is configured in Agility CMS
- Test with full URL including
agilitypreviewkeyparam - Check browser console for errors
Can't exit preview mode:
- Visit
/api/preview/exitdirectly - Clear browser cookies
- Try incognito/private window
Content Not Updating
Changes not appearing:
- Check if webhooks are configured (production only)
- In development: Stop and restart
npm run dev - Verify content is Published (not just saved)
- Check cache duration settings in
.env.local
Old content still showing:
- Trigger manual revalidation:
/api/revalidate(POST) - Clear Vercel cache (in Vercel dashboard)
- Wait for
revalidateduration to expire - Check webhook logs in Agility CMS
Performance Issues
Slow build times:
- Reduce number of pages being generated
- Check for duplicate API calls
- Review component complexity
- Consider incremental builds (ISR)
Slow page loads:
- Optimize images (use
<AgilityPic>) - Check bundle size:
npm run build(see output) - Review client-side JavaScript
- Use React Server Components when possible
Getting Help
- Documentation: Check the
/docsfolder - Agility CMS Support: help.agilitycms.com
- GitHub Issues: github.com/agility/agilitycms-nextjs-starter/issues
- Community Slack: Join Agility Community
- Next.js Docs: nextjs.org/docs
Ready to build? Start by creating your first component! See COMPONENTS.md for a step-by-step guide.