Skip to main content

Getting Started with FlatWP Configuration

FlatWP uses a centralized, type-safe configuration system that makes it easy to configure WordPress connection, rendering strategies, features, and site metadata.

Overview

The configuration system provides:

  • Type Safety: Full TypeScript support with Zod validation
  • Centralized Settings: Single source of truth in flatwp.config.ts
  • Environment Variables: Automatic validation of required env vars
  • Runtime Access: Type-safe configuration access throughout your app
  • Helpful Errors: Clear validation messages when configuration is invalid

Quick Start

1. Create Configuration File

Create flatwp.config.ts in your app root:

flatwp.config.ts
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

Create .env.local with your WordPress credentials:

.env.local
# WordPress GraphQL endpoint
NEXT_PUBLIC_WORDPRESS_API_URL=https://your-wordpress-site.com/graphql

# Secret for revalidation webhooks (min 16 characters)
REVALIDATION_SECRET=your-secure-random-secret-here

# Optional: Preview mode secret
PREVIEW_SECRET=another-secure-random-secret

# Optional: Site metadata
NEXT_PUBLIC_SITE_URL=https://your-site.com
NEXT_PUBLIC_SITE_NAME=Your Site Name
tip

Generate secure secrets using:

openssl rand -base64 32

3. Create Runtime Config Helper

Create lib/config.ts to access configuration in your app:

lib/config.ts
import flatwpConfig from '../flatwp.config';
import { getISRConfig } from '@flatwp/config';

// Export validated config
export const config = flatwpConfig;

// Convenience exports
export const wordpress = config.wordpress;
export const features = config.features;
export const site = config.site;

// Get ISR configuration for content types
export function getContentISR(contentType: string) {
return getISRConfig(config, contentType);
}

// Check if features are enabled
export function isFeatureEnabled(
feature: 'preview' | 'search' | 'vercel-analytics'
): 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;
case 'vercel-analytics':
return config.features.analytics.vercel;
default:
return false;
}
}

4. Use in Your Pages

app/blog/[slug]/page.tsx
import { getContentISR } from '@/lib/config';

// Apply ISR settings from config
export const revalidate = getContentISR('posts').revalidate;

export default async function BlogPost({ params }: { params: { slug: string } }) {
// Your page implementation
}

Minimal Configuration

The absolute minimum configuration requires only WordPress connection settings:

flatwp.config.ts
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
),
},
});

All other settings will use sensible defaults:

  • Posts: ISR with on-demand revalidation
  • Pages: Static generation
  • Archives: ISR with 5-minute revalidation
  • Homepage: ISR with 1-minute revalidation
  • Preview: Enabled if PREVIEW_SECRET is set
  • Search: Client-side with Fuse.js
  • SEO: Auto-detect Yoast/RankMath

Typical Configuration

A more complete configuration for a production site:

flatwp.config.ts
import { defineConfig, validateEnv } from '@flatwp/config';

export default defineConfig({
// WordPress Connection
wordpress: {
graphqlUrl: validateEnv(
'NEXT_PUBLIC_WORDPRESS_API_URL',
process.env.NEXT_PUBLIC_WORDPRESS_API_URL
),
domain: process.env.NEXT_PUBLIC_WORDPRESS_DOMAIN,
revalidateSecret: validateEnv(
'REVALIDATION_SECRET',
process.env.REVALIDATION_SECRET
),
previewSecret: process.env.PREVIEW_SECRET,
},

// Rendering Strategies
rendering: {
posts: {
strategy: 'isr',
revalidate: false, // On-demand revalidation 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,
},
},

// Features
features: {
preview: {
enabled: !!process.env.PREVIEW_SECRET,
},
search: {
enabled: true,
provider: 'fuse',
},
seo: {
provider: 'auto', // Auto-detect from WordPress
},
analytics: {
vercel: process.env.NEXT_PUBLIC_VERCEL_ANALYTICS === 'true',
google: process.env.NEXT_PUBLIC_GA_ID,
},
},

// Site Metadata
site: {
url: process.env.NEXT_PUBLIC_SITE_URL,
name: process.env.NEXT_PUBLIC_SITE_NAME || 'My Site',
description:
process.env.NEXT_PUBLIC_SITE_DESCRIPTION ||
'A modern headless WordPress site',
},
});

Validation

The configuration is validated when your app starts. If there are errors, you'll see helpful messages:

❌ FlatWP Configuration Error:

Your flatwp.config.ts has validation errors:

➤ wordpress.graphqlUrl:
Must be a valid URL (e.g., https://example.com)

➤ wordpress.revalidateSecret:
Must be at least 16 characters (currently 8)

💡 Tips:
• Check your environment variables are set correctly
• Ensure all required fields have values
• Verify URLs are valid and secrets are at least 16 characters

📖 Documentation: https://flatwp.com/docs/configuration

Next Steps