HeadlineHero AI
AI-powered headline generator for WordPress using OpenAI GPT-4o-mini. Generate catchy, SEO-friendly headlines directly from the Gutenberg editor.
by Rehan Adil · github.com/rehanadil/headlinehero-ai · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/rehanadil/headlinehero-ai/archive/refs/heads/main.zipHeadlineHero AI - WordPress Plugin
AI-powered headline generator for WordPress using OpenAI GPT-4o-mini. Generate catchy, SEO-friendly headlines directly from the Gutenberg block editor.
Project Status
✅ Completed Files
Configuration & Build Setup
- ✅
package.json- NPM dependencies and build scripts - ✅
.gitignore- Git ignore rules - ✅
phpunit.xml- PHPUnit test configuration - ✅
jest.config.js- Jest test configuration
PHP Backend (Complete)
- ✅
headlinehero-ai.php- Main plugin file with WordPress plugin header - ✅
includes/class-headlinehero-ai.php- Main plugin class (singleton pattern) - ✅
includes/class-settings.php- Settings page and Options API - ✅
includes/class-rest-api.php- REST API endpoints - ✅
includes/class-openai-client.php- OpenAI API integration - ✅
includes/class-assets.php- Asset enqueuing - ✅
includes/class-cache.php- Headline caching (5-minute TTL) - ✅
includes/class-history.php- Headline history tracking
Admin Pages (Complete)
- ✅
admin/views/settings-page.php- Settings page template - ✅
admin/css/admin-style.css- Admin page styling
React Frontend (Foundation)
- ✅
src/index.js- Entry point, registers plugin - ✅
src/sidebar.js- Main PluginSidebar component
🚧 Remaining Files to Create
React Custom Hooks
- ⏳
src/hooks/usePostContent.js- Extract post title & first 500 words - ⏳
src/hooks/useHeadlineGenerator.js- API calls & state management - ⏳
src/hooks/useHistory.js- Load headline history - ⏳
src/hooks/useFavorites.js- Manage favorites in localStorage
React Components
- ⏳
src/components/HeadlineGenerator.js- Main generator component - ⏳
src/components/HeadlineList.js- Display all headlines - ⏳
src/components/HeadlineItem.js- Single headline with "Use This" button - ⏳
src/components/GenerateButton.js- Generate button with loading state - ⏳
src/components/ErrorNotice.js- Error display - ⏳
src/components/HistoryPanel.js- Historical headlines (optional advanced feature) - ⏳
src/components/FavoritesPanel.js- Favorites panel (optional advanced feature) - ⏳
src/components/CharacterCounter.js- Character limit display (optional)
Utility Functions
- ⏳
src/utils/api.js- API helper functions - ⏳
src/utils/validation.js- Input validation - ⏳
src/utils/textExtraction.js- Text extraction from blocks
Styling
- ⏳
src/styles/sidebar.scss- Sidebar component styles
Documentation
- ⏳
readme.txt- WordPress.org standard readme - ⏳ PHPDoc and JSDoc comments in all files
Testing
- ⏳
tests/php/test-rest-api.php- REST API tests - ⏳
tests/php/test-openai-client.php- OpenAI client tests - ⏳
tests/php/test-cache.php- Cache tests - ⏳
tests/js/HeadlineGenerator.test.js- Component tests - ⏳
tests/js/useHeadlineGenerator.test.js- Hook tests - ⏳
tests/js/validation.test.js- Validation tests
Quick Start Guide
1. Install Dependencies
npm install
This will install all WordPress packages defined in package.json.
2. Development Build
Start the development server with hot reloading:
npm start
3. Production Build
Create optimized production build:
npm run build
This compiles React code to /build directory.
4. Install Plugin in WordPress
- Copy the entire
headlinehero-ai-wp-pluginfolder towp-content/plugins/ - Go to WordPress Admin > Plugins
- Activate "HeadlineHero AI"
- Go to Settings > HeadlineHero AI
- Enter your OpenAI API key
- Select your default tone preference
5. Use the Plugin
- Create or edit a post in the block editor
- Look for the "HeadlineHero AI" sidebar panel (lightbulb icon)
- Write at least 10 words in your post
- Click "Generate Headlines"
- Select one of the 5 generated headlines by clicking "Use This"
Architecture Overview
PHP Backend
Singleton Pattern: The main plugin class uses a singleton pattern to ensure only one instance exists.
REST API Endpoints:
POST /wp-json/headlinehero/v1/generate- Generate headlinesGET /wp-json/headlinehero/v1/history/{post_id}- Get historyDELETE /wp-json/headlinehero/v1/history/{post_id}- Clear history
Security:
- REST API authentication (automatic with WordPress)
- Capability check:
current_user_can('edit_posts') - Input sanitization:
sanitize_text_field(),wp_kses_post() - Output escaping:
esc_html(),esc_attr(),esc_url() - API key stored in wp_options (not exposed to frontend)
Caching:
- Headlines cached in post meta for 5 minutes
- Cache invalidated on post save
- Reduces API costs and improves performance
History:
- Last 10 generation sessions stored per post
- Includes tone, timestamp, and headlines
- Retrievable via REST API
React Frontend
Component Structure:
index.js (entry point)
↓
sidebar.js (PluginSidebar)
↓
HeadlineGenerator (main component)
├─ GenerateButton
├─ HeadlineList
│ └─ HeadlineItem (× 5)
├─ ErrorNotice
├─ HistoryPanel (optional)
├─ FavoritesPanel (optional)
└─ CharacterCounter (optional)
Custom Hooks:
usePostContent- Extracts title and first 500 words from editoruseHeadlineGenerator- Manages API calls and stateuseHistory- Loads headline historyuseFavorites- Manages favorites in localStorage
State Management:
- Uses WordPress
@wordpress/datafor editor state - Local component state for UI
- localStorage for favorites
Features
Core Features (Implemented in Backend)
✅ Generate 5 AI-powered headlines from post content ✅ Three tone options: Professional, Clickbaity, Minimalist ✅ Smart caching (5-minute TTL) ✅ Headline history tracking (last 10 sessions) ✅ Secure API key storage ✅ REST API with proper authentication
Frontend Features (Need React Components)
⏳ One-click headline application ⏳ Tone selector in sidebar ⏳ Loading spinner during generation ⏳ Error handling with user-friendly messages ⏳ Favorites system (localStorage) ⏳ Character limit warnings ⏳ History panel (collapsible)
API Key Configuration
Option 1: Settings Page (Recommended)
- Go to Settings > HeadlineHero AI
- Enter your OpenAI API key
- Save settings
Option 2: wp-config.php (For Local Development)
define('HEADLINEHERO_API_KEY', 'sk-your-api-key-here');
Development Workflow
Linting
npm run lint:js # Lint JavaScript
npm run lint:css # Lint CSS
Formatting
npm run format # Format code with Prettier
Testing
npm run test:unit # Run Jest tests
phpunit # Run PHPUnit tests
Tone Variations
Each tone generates different styles of headlines:
Professional:
- Authoritative and credible
- Clear and informative
- SEO-optimized
- Example: "How to Improve WordPress Security: A Complete Guide"
Clickbaity:
- Curiosity-inducing
- Emotional triggers
- Urgency and mystery
- Example: "You Won't Believe These 5 WordPress Security Tricks"
Minimalist:
- Concise and elegant
- Maximum meaning, minimum words
- Direct and impactful
- Example: "WordPress Security Essentials"
Next Steps for Completion
Priority 1: Core React Components (Required for Basic Functionality)
-
Create
src/hooks/usePostContent.js:- Use
@wordpress/datato get current post - Extract title:
select('core/editor').getEditedPostAttribute('title') - Extract content:
select('core/editor').getEditedPostAttribute('content') - Get first 500 words of plain text
- Return:
{ title, content, postId, wordCount }
- Use
-
Create
src/hooks/useHeadlineGenerator.js:- State:
headlines,loading,error generateHeadlines(title, content, tone)function- Use
apiFetchto call REST API - Handle loading/error states
- Return:
{ headlines, loading, error, generateHeadlines }
- State:
-
Create
src/utils/api.js:generateHeadlines(title, content, tone, postId)- API wrapper- Error parsing and formatting
-
Create
src/utils/validation.js:validatePostContent(title, content)- Check minimum requirements- Return:
{ valid: boolean, error: string }
-
Create
src/utils/textExtraction.js:extractPlainText(content)- Strip HTML/blocksgetFirstNWords(text, n)- Get first N words
-
Create
src/components/HeadlineGenerator.js:- Use
usePostContentanduseHeadlineGeneratorhooks - Render tone selector (SelectControl)
- Render generate button
- Display loading spinner
- Show error notices
- Render HeadlineList when headlines available
- Use
-
Create
src/components/HeadlineList.js:- Map
headlinesarray toHeadlineItemcomponents - Pass callbacks for "Use This" action
- Map
-
Create
src/components/HeadlineItem.js:- Display single headline
- "Use This" button
- Use
dispatch('core/editor').editPost({ title: headline })to update title
-
Create
src/components/GenerateButton.js:- Button with loading state (show Spinner when loading)
- Disabled if no API key or insufficient content
-
Create
src/components/ErrorNotice.js:- Use
@wordpress/componentsNotice component - Display error messages
- Optional "Go to Settings" button for API key errors
- Use
Priority 2: Build and Test
-
Install dependencies:
npm install -
Build assets:
npm run build -
Test in WordPress:
- Activate plugin
- Configure API key
- Create a post
- Test headline generation
Priority 3: Advanced Features (Optional)
-
Favorites System:
- Create
src/hooks/useFavorites.js - Create
src/components/FavoritesPanel.js - Store in localStorage
- Create
-
History Panel:
- Create
src/hooks/useHistory.js - Create
src/components/HistoryPanel.js - Fetch from REST API
- Create
-
Character Counter:
- Create
src/components/CharacterCounter.js - Color-coded warnings
- Create
-
Styling:
- Create
src/styles/sidebar.scss - Custom styles for components
- Create
Priority 4: Testing & Documentation
-
Write Tests:
- PHPUnit tests for backend
- Jest tests for React components
-
Create readme.txt:
- WordPress.org standard format
- Installation instructions
- FAQ section
- Changelog
-
Add Documentation:
- PHPDoc for all PHP functions
- JSDoc for React components
- Inline comments for complex logic
File Naming Conventions
- PHP classes:
class-name-here.php - React components:
ComponentName.js(PascalCase) - React hooks:
useHookName.js(camelCase with 'use' prefix) - Utilities:
utilityName.js(camelCase) - Styles:
name-here.scss(kebab-case)
Troubleshooting
Build files not found
If you see "Build files not found" error in WordPress:
npm install
npm run build
API key not working
- Verify key starts with
sk- - Check it's entered correctly in settings
- Test connection from OpenAI platform
Headlines not generating
- Check browser console for errors
- Verify API key is configured
- Check WordPress REST API is accessible
- Ensure post has at least 10 words
Plugin not appearing in editor
- Verify you're using Gutenberg (block editor)
- Check plugin is activated
- Look for lightbulb icon in top right
Support & Contributing
- Issues: https://github.com/rehanadil/headlinehero-ai/issues
- Documentation: See
/Users/rehanadil/.claude/plans/parsed-frolicking-cupcake.md - License: GPL v2 or later
Credits
Built with:
- WordPress Gutenberg
- OpenAI GPT-4o-mini
- @wordpress/scripts
- React
Version: 1.0.0 Author: Rehan Adil License: GPL v2 or later