Configuration System
FlatWP provides a centralized, type-safe configuration system for managing WordPress connections, rendering strategies, features, and site metadata.
Key Features
- Type Safety: Full TypeScript support with Zod schema validation
- Centralized: Single source of truth in
flatwp.config.ts - Validated: Automatic validation with helpful error messages
- Runtime Access: Convenient utility functions throughout your app
- Environment Variables: Automatic validation and parsing
Quick Start
1. Create Configuration
import { defineConfig, validateEnv } from '@flatwp/config';
export default defineConfig({
wordpress: {
graphqlUrl: validateEnv(
'NEXT_PUBLIC_WORDPRESS_API_URL',
process.env.NEXT_PUBLIC_WORDPRESS_API_URL
),
revalidateSecret: validateEnv(
'REVALIDATION_SECRET',
process.env.REVALIDATION_SECRET
),
},
});
2. Set Environment Variables
NEXT_PUBLIC_WORDPRESS_API_URL=https://cms.example.com/graphql
REVALIDATION_SECRET=your-secure-random-secret
3. Use in Your App
import { getContentISR } from '@/lib/config';
export const revalidate = getContentISR('posts').revalidate;
export default async function BlogPost({ params }: { params: { slug: string } }) {
// Your page implementation
}
What You Can Configure
WordPress Connection
- GraphQL API endpoint
- WordPress domain for images
- Revalidation webhook secret
- Preview mode secret
Rendering Strategies
Configure how different content types are rendered:
- Posts: ISR with on-demand revalidation
- Pages: Static generation
- Archives: ISR with time-based revalidation
- Homepage: ISR with short revalidation
- Custom Types: Your own post types
Features
Enable/disable and configure features:
- Preview Mode: Draft content preview
- Search: Client-side (Fuse.js) or server-side (Algolia)
- SEO: Auto-detect Yoast/RankMath
- Analytics: Vercel, Google Analytics, Sentry
Site Metadata
- Site URL for canonical URLs and SEO
- Site name for branding
- Site description for metadata
Configuration Options
Rendering Strategies
Three strategies available for content:
| Strategy | Description | Use Case |
|---|---|---|
| static | Generated at build time | Rarely-changing content |
| isr | Static with revalidation | Most WordPress content |
| ssr | Server-rendered per request | Real-time data |
Revalidation Options
Control when content updates:
false- On-demand only (via WordPress webhook)true- Default (60 seconds)number- Custom interval in seconds
Feature Flags
features: {
preview: true, // Enable preview mode
search: {
enabled: true,
provider: 'fuse', // or 'algolia'
},
seo: {
provider: 'auto', // or 'yoast', 'rankmath', 'none'
},
analytics: {
vercel: true,
google: 'G-XXXXXXXXXX',
sentry: 'https://...',
},
}
Documentation
Getting Started
Learn the basics of FlatWP configuration.
Configuration Reference
Complete API reference for all configuration options.
Rendering Strategies
Deep dive into static, ISR, and SSR rendering.
Runtime Usage
How to access and use configuration in your app.
Environment Variables
Complete reference for environment variables.
Migration Guide
Migrate from older configuration approaches.
Examples
Basic Configuration
import { defineConfig, validateEnv } from '@flatwp/config';
export default defineConfig({
wordpress: {
graphqlUrl: validateEnv(
'NEXT_PUBLIC_WORDPRESS_API_URL',
process.env.NEXT_PUBLIC_WORDPRESS_API_URL
),
revalidateSecret: validateEnv(
'REVALIDATION_SECRET',
process.env.REVALIDATION_SECRET
),
},
});
Advanced Configuration
import { defineConfig, validateEnv } from '@flatwp/config';
export default defineConfig({
wordpress: {
graphqlUrl: validateEnv(
'NEXT_PUBLIC_WORDPRESS_API_URL',
process.env.NEXT_PUBLIC_WORDPRESS_API_URL
),
revalidateSecret: validateEnv(
'REVALIDATION_SECRET',
process.env.REVALIDATION_SECRET
),
previewSecret: process.env.PREVIEW_SECRET,
},
rendering: {
posts: {
strategy: 'isr',
revalidate: false, // On-demand via webhook
generateStaticParams: true,
},
pages: {
strategy: 'static',
revalidate: false,
generateStaticParams: true,
},
archives: {
strategy: 'isr',
revalidate: 300, // 5 minutes
generateStaticParams: true,
},
homepage: {
strategy: 'isr',
revalidate: 60, // 1 minute
generateStaticParams: false,
},
custom: {
product: {
strategy: 'isr',
revalidate: 300,
generateStaticParams: true,
},
},
},
features: {
preview: {
enabled: !!process.env.PREVIEW_SECRET,
},
search: {
enabled: true,
provider: 'algolia',
algolia: {
appId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID!,
apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY!,
indexName: 'posts',
},
},
seo: {
provider: 'auto',
},
analytics: {
vercel: true,
google: process.env.NEXT_PUBLIC_GA_ID,
sentry: process.env.NEXT_PUBLIC_SENTRY_DSN,
},
},
site: {
url: process.env.NEXT_PUBLIC_SITE_URL,
name: 'My Awesome Site',
description: 'The best blog about web development',
},
});
Runtime Usage
import flatwpConfig from '../flatwp.config';
import { getISRConfig } from '@flatwp/config';
export const config = flatwpConfig;
export const wordpress = config.wordpress;
export const features = config.features;
export const site = config.site;
export function getContentISR(contentType: string) {
return getISRConfig(config, contentType);
}
export function isFeatureEnabled(feature: string): boolean {
switch (feature) {
case 'preview':
return typeof config.features.preview === 'boolean'
? config.features.preview
: config.features.preview.enabled;
case 'search':
return config.features.search.enabled;
default:
return false;
}
}
Benefits
Type Safety
Full TypeScript support with auto-completion:
import { config } from '@/lib/config';
// TypeScript knows all available properties
const url = config.wordpress.graphqlUrl; // ✓ string
const provider = config.features.search.provider; // ✓ 'fuse' | 'algolia'
Validation
Automatic validation with helpful errors:
// Missing required variable
❌ Missing required environment variable: NEXT_PUBLIC_WORDPRESS_API_URL
Hint: Set NEXT_PUBLIC_WORDPRESS_API_URL in your .env.local file
// Invalid URL
❌ wordpress.graphqlUrl: Must be a valid URL (e.g., https://example.com)
// Short secret
❌ wordpress.revalidateSecret: Must be at least 16 characters (currently 8)
Centralization
Single source of truth:
// Before: scattered configuration
const url = process.env.NEXT_PUBLIC_WORDPRESS_API_URL;
const revalidate = 60; // Hard-coded in multiple files
// After: centralized
import { wordpress, getContentISR } from '@/lib/config';
const url = wordpress.graphqlUrl;
const revalidate = getContentISR('posts').revalidate;
Best Practices
- Use
validateEnv()for required environment variables - Centralize all config in
flatwp.config.ts - Access via utilities in
lib/config.ts - Type everything - leverage TypeScript support
- Validate early - configuration errors fail fast at startup
- Document custom types - add comments for custom post types
- Test configuration - verify in staging before production
Troubleshooting
Configuration Errors
If you see validation errors:
- Read the error message carefully - they're designed to be helpful
- Check environment variables are set correctly
- Verify URLs include protocol (
https://) - Ensure secrets are at least 16 characters
- Review the configuration reference for correct syntax
Missing Features
If features aren't working:
- Check feature is enabled in config
- Verify required environment variables are set
- Check
isFeatureEnabled()returns true - Review feature-specific documentation
Runtime Access
If configuration values are undefined:
- Import from
lib/config.ts, notflatwp.config.ts - Check TypeScript types match expected values
- Verify configuration is valid (no startup errors)
- Use utility functions instead of direct access
Next Steps
- Getting Started - Set up configuration
- Configuration Reference - Explore all options
- Rendering Strategies - Optimize performance
- Environment Variables - Configure env vars