payload-forgeai
v0.12.0
Published
A plugin for Payload CMS to generate content with AI
Readme
Payload Forge AI
AI-powered field generation plugin for Payload CMS. Automatically generate field content using OpenAI, with support for context-aware generation based on other fields in your document.
Features
- 🤖 AI-powered field generation using OpenAI
- 🔗 Context-aware generation using other field values
- 📝 Custom prompts per field
- 🎯 Support for relationships, selects, and all field types
- 🗂️ Nested field support with dot notation (e.g.,
meta.title) - ⚡ Simple integration with existing Payload collections
Installation
npm install payload-forgeai
# or
pnpm add payload-forgeai
# or
yarn add payload-forgeaiEnvironment Variables
Create a .env file in your project root:
OPENAI_API_KEY=your_openai_api_key_here
# Optional: Enable debug logging
# PAYLOAD_FORGEAI_DEBUG=trueConfiguration
Add the plugin to your payload.config.ts:
import { payloadForgeAi } from 'payload-forgeai'
export default buildConfig({
plugins: [
payloadForgeAi({
apiKey: process.env.OPENAI_API_KEY,
collections: {
posts: {
fields: [
{
name: 'title',
prompt: 'Write a compelling title for this blog post',
},
{
name: 'content',
context: ['title', 'category'],
prompt: 'Write engaging content for this blog post',
},
],
},
},
}),
],
})Usage
Basic Field Generation
Configure a field for AI generation:
{
name: 'title',
prompt: 'Write a catchy title that is max 60 characters',
}The plugin automatically includes the current field value in the context, instructing the AI to generate something different when regenerating. This is useful for getting variations.
To disable this behavior and allow the AI to consider the current value without the "generate different" instruction:
{
name: 'title',
prompt: 'Write a catchy title that is max 60 characters',
generateDifferent: false, // AI can generate similar content
}Nested Fields
The plugin supports fields at any level of nesting using dot notation:
payloadForgeAi({
apiKey: process.env.OPENAI_API_KEY,
collections: {
articles: {
fields: [
{
name: 'meta.title', // Field inside a 'meta' group
prompt: 'Write an SEO-optimized title',
},
{
name: 'meta.description',
context: ['meta.title', 'content'],
prompt: 'Write a meta description',
},
],
},
},
})This works with:
- Group fields:
meta.title - Tabs:
content.main.heading - Collapsible fields:
advanced.settings.value
Context-Aware Generation
Use other fields as context for more relevant AI generation:
Simple Context (by field name)
{
name: 'content',
context: ['title', 'category'],
prompt: 'Write the main content for this article',
}Custom Context Prompts
Provide custom prompts for how each context field should be used:
{
name: 'content',
context: [
{
field: 'title',
prompt: 'The article title is',
},
{
field: 'category',
prompt: 'The category for this post is',
},
{
field: 'author',
prompt: 'Written by author',
},
],
prompt: 'Write engaging content based on the context above',
}Working with Relationships
The plugin automatically fetches and populates relationship fields:
// In your collection
fields: [
{
name: 'author',
type: 'relationship',
relationTo: 'users',
},
{
name: 'bio',
type: 'textarea',
},
]
// In your AI config - Use full author object
{
name: 'bio',
context: [
{
field: 'author',
prompt: 'Author details',
},
],
prompt: 'Write a professional bio',
}
// Or extract specific fields from the relationship
{
name: 'bio',
context: [
{
field: 'author',
fields: ['name', 'email'], // Only include name and email
prompt: 'Author details',
},
],
prompt: 'Write a professional bio and mention the author name',
}
// Use nested prompts - BOTH outer and inner prompts are used
{
name: 'content',
context: [
{
field: 'author',
prompt: 'The author information', // Outer prompt - used as header
fields: [
{
field: 'name',
prompt: 'Written by', // Inner prompt - used for this specific field
},
{
field: 'email',
prompt: 'Contact', // Inner prompt - used for this specific field
},
],
},
],
prompt: 'Write content with author attribution',
}
// AI receives:
// The author information:
// Written by: John Doe
// Contact: [email protected]Selecting Specific Fields
Use the fields array to extract only specific properties from context:
{
name: 'summary',
context: [
{
field: 'author',
fields: ['name'], // Only include the author's name
prompt: 'Written by',
},
{
field: 'metadata',
fields: ['tags', 'category'], // Extract specific nested properties
},
],
prompt: 'Write a summary with author attribution',
}Nested Field Selection
For complex nested objects, you can use recursive field configuration with prompts at each level:
{
name: 'description',
context: [
{
field: 'product',
prompt: 'Product details', // Outer prompt (used as fallback for nested fields without prompts)
fields: [
'name', // Will use: "Product details - name: value"
'price',
{
field: 'manufacturer',
prompt: 'Made by', // This prompt overrides the parent
fields: ['name', 'country'], // Will use: "Made by - name: value" and "Made by - country: value"
},
{
field: 'specs',
fields: [
{
field: 'weight',
prompt: 'Product weight', // Custom prompt for this specific field
},
],
},
],
},
],
prompt: 'Write a product description',
}How nested prompts work:
- ALL prompts are used - both outer and nested prompts are included in the context
- Outer prompts act as section headers/introductions
- Nested prompts describe individual fields
- Example output:
Product details: name: Widget X Made by: name: ACME Corp country: USA Product weight: 2.5kg - This allows fine-grained control over how each piece of data is presented to the AI
Configuration Options
Plugin Options
type PayloadForgeAiConfig = {
apiKey: string // Your OpenAI API key
disabled?: boolean // Disable the plugin
collections?: {
[collectionSlug: string]: {
fields: PayloadForgeAiFieldConfig[]
}
}
}Field Configuration
type PayloadForgeAiContextField =
| string // Simple field name
| {
field: string // Field name to use as context
prompt?: string // Custom prompt for this context field
fields?: PayloadForgeAiContextField[] // Recursively extract nested fields
}
type PayloadForgeAiFieldConfig = {
name: string // Field name to enable AI generation
prompt: string // Instructions for the AI
context?: PayloadForgeAiContextField[] // Fields to use as context
generateDifferent?: boolean // If true (default), instructs AI to generate different from current value
}Examples
Blog Post with Category and Author Context
payloadForgeAi({
apiKey: process.env.OPENAI_API_KEY,
collections: {
posts: {
fields: [
{
name: 'title',
context: ['category'],
prompt: 'Write a title (max 8 words)',
},
{
name: 'excerpt',
context: ['title', 'category'],
prompt: 'Write a brief excerpt (max 150 characters)',
},
{
name: 'content',
context: [
{ field: 'title', prompt: 'Article title' },
{ field: 'category', prompt: 'Category' },
{ field: 'excerpt', prompt: 'Summary' },
{
field: 'author',
fields: ['name'], // Only use author's name
prompt: 'Written by',
},
],
prompt:
'Write comprehensive content (300-500 words) and include author attribution at the end',
},
],
},
},
})Product Description with Related Data
payloadForgeAi({
apiKey: process.env.OPENAI_API_KEY,
collections: {
products: {
fields: [
{
name: 'description',
context: [
{ field: 'name', prompt: 'Product name' },
{ field: 'category', prompt: 'Category' },
{ field: 'price', prompt: 'Price' },
{ field: 'features', prompt: 'Key features' },
],
prompt: 'Write a compelling product description',
},
{
name: 'seoTitle',
context: ['name', 'category'],
prompt: 'Write an SEO-optimized title (max 60 chars)',
},
{
name: 'seoDescription',
context: ['name', 'description'],
prompt: 'Write an SEO meta description (max 160 chars)',
},
],
},
},
})Environment Variables
Create a .env file in your project:
OPENAI_API_KEY=your_openai_api_key_hereHow It Works
- The plugin adds a "Generate" button to configured fields in the Payload admin UI
- When clicked, it gathers context from other fields in the document
- Includes the current field value (if any) and instructs the AI to generate something different (configurable)
- Sends the context and prompt to OpenAI via your API endpoint
- Returns the generated content and populates the field
Development
Running the Dev Environment
# Install dependencies
pnpm install
# Create .env file
cp .env.example .env
# Add your OpenAI API key to .env
# OPENAI_API_KEY=your_key_here
# Start the dev server
pnpm devTesting
pnpm testDebugging
If you're experiencing issues with field path resolution or nested fields not being found, you can enable debug logging:
# Add to your .env file
PAYLOAD_FORGEAI_DEBUG=trueThis will log detailed information about:
- Field path searches
- Which fields are being checked
- Container field traversal (collapsible, tabs, groups)
- Field resolution success/failure
The debug logs will appear in your server console when the plugin initializes and when validating field configurations.
License
MIT
Support
For issues and questions, please open an issue on GitHub.
