See Agility CMS in action. Watch a product demo
Best Practices
This guide covers best practices for developing with Agility CMS, including code organization, performance, security, and maintainability.
Code Organization
Project Structure
Organize code logically:
src/
├── app/ # Next.js App Router
├── components/
│ └── agility-components/ # Agility components
├── lib/
│ ├── cms/ # CMS utilities
│ └── types/ # TypeScript types
└── middleware.ts # Middleware
Component Organization
- Group related components
- Use consistent naming
- Keep components focused
- Extract reusable logic
Type Definitions
- Define interfaces for all content types
- Use TypeScript for type safety
- Keep types in dedicated files
- Document complex types
Type Safety
Always Use TypeScript
// ✅ Good
const { fields } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
})
// ❌ Bad
const { fields } = await getContentItem({
contentID: 204,
languageCode: "en-us"
})
Define Interfaces
interface IPost {
contentID: number
fields: {
heading: string
slug: string
content: string
image: ImageField
}
}
Performance
Image Optimization
- Always use
<AgilityPic>for Agility images - Set
priorityfor above-the-fold images - Use appropriate
fallbackWidth - Leverage CDN delivery
Caching
- Use appropriate cache durations
- Leverage cache tags for invalidation
- Implement webhook revalidation
- Monitor cache performance
Code Splitting
- Use dynamic imports for large components
- Split client and server components
- Lazy load non-critical content
Error Handling
Graceful Degradation
try {
const { fields } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
})
} catch (error) {
// Handle gracefully
return <div>Content not available</div>
}
Fallback Content
const { fields } = await getContentItem<IPost>({
contentID: 204,
languageCode: "en-us"
}).catch(() => ({
fields: {
heading: "Default Heading",
content: "Default content"
}
}))
Security
API Keys
- Never commit API keys to version control
- Use environment variables
- Rotate keys periodically
- Use different keys for different environments
Preview Mode
- Validate preview keys
- Secure preview endpoints
- Limit preview access
- Log preview usage
Input Validation
- Validate all user input
- Sanitize HTML content
- Use TypeScript for type safety
- Handle edge cases
Accessibility
Semantic HTML
- Use proper HTML elements
- Include alt text for images
- Provide ARIA labels when needed
- Ensure keyboard navigation
Image Alt Text
<AgilityPic
image={imageField}
alt={imageField.label || "Descriptive alt text"}
data-agility-field="image"
/>
SEO
Meta Tags
- Set page titles and descriptions
- Use proper heading hierarchy
- Include Open Graph tags
- Implement structured data
Semantic Markup
- Use semantic HTML elements
- Proper heading hierarchy (h1, h2, h3)
- Descriptive link text
- Image alt attributes
Code Quality
Consistency
- Follow consistent patterns
- Use consistent naming conventions
- Maintain code style
- Document complex logic
Reusability
- Extract reusable components
- Create utility functions
- Share common types
- Avoid code duplication
Testing
- Test components with different content
- Test error cases
- Test edge cases
- Test with different locales
Documentation
Code Comments
- Document complex logic
- Explain non-obvious decisions
- Include examples
- Keep comments up to date
Type Documentation
/**
* Blog post content item
* @interface IPost
*/
interface IPost {
/** Post heading/title */
heading: string
/** URL-friendly slug */
slug: string
/** Post content (HTML) */
content: string
}
Common Pitfalls
1. Not Using TypeScript
Always use TypeScript for type safety.
2. Missing Error Handling
Always handle errors gracefully.
3. Not Caching
Leverage caching for performance.
4. Hardcoding Values
Use environment variables and configuration.
5. Not Testing
Test with different content and scenarios.
In this Article:
Was this article helpful?