Rational SEO provides 100% of the technical SEO requirements for modern sites with 0% of the database bloat, UI clutter, or performance drag.
Philosophy
Rational SEO rigorously rejects features that do not directly influence search engines or social crawlers:
- No Content Scoring – No traffic lights, readability checks, or keyword density counters
- No Dashboard – No “SEO Overview” widget or React-powered admin home
- No Analytics – No ranking tracking or Google Search Console API integrations
- No Frontend Assets – Zero CSS or JS files loaded on the frontend
- No 404 Logging – Never writes 404 hits to the database
Features
Meta Tags
- Custom title tags with configurable separator
- Meta descriptions (manual or auto-generated from excerpt/content)
- Robots meta (index/noindex control)
- Canonical URLs
- Google and Bing verification meta tags
Social Media
- Open Graph tags (og:title, og:description, og:image, og:url, og:type, og:locale, og:site_name)
- Twitter Cards (summary or summary_large_image)
- Per-post social image override
Structured Data
- JSON-LD schema output using @graph format
- Organization or Person schema (configurable)
- WebSite schema with publisher linking
- WebPage schema
- Article schema on posts/pages with author, dates, and images
XML Sitemaps
- Sitemap index at /sitemap.xml
- Per-post-type sitemaps with pagination
- Transient caching with stale-while-revalidate
- Content freshness filtering (exclude old content)
- Post type exclusions
Editor Integration
- Meta box on all public post types
- Custom SEO title and description fields
- Focus keyword field with real-time presence indicators (title, description, first paragraph, URL slug)
- Noindex toggle per post
- Canonical URL override
- Social image override
- Taxonomy term SEO fields (title, description, noindex, canonical)
Post Type Archives
- Custom SEO title and description for each post type archive
- Configure via Settings > Rational SEO > Archives tab
AI Assistant (optional)
- AI-powered focus keyword suggestions
- AI-generated SEO titles and meta descriptions
- One-click “Suggest All” for keyword, title, and description together
- Uses OpenAI GPT-4o-mini (requires your own API key)
- Data sent only when you click — never in the background
External Services
This plugin connects to the following external services:
RationalWP Plugin Directory
This plugin fetches a list of available RationalWP plugins from rationalwp.com to display in the WordPress admin menu. Only the menu file version number is sent as a cache-busting query parameter. No user data is transmitted. The response is cached locally for 24 hours.
- Service URL: https://rationalwp.com/plugins.json
- Terms of Service: https://rationalwp.com/terms/
- Privacy Policy: https://rationalwp.com/privacy/
OpenAI API (optional)
This plugin provides optional AI-powered SEO suggestions using the OpenAI API. When a site administrator configures an OpenAI API key in Settings > Rational SEO > General, users can click “Suggest” or “Generate” buttons in the post editor to receive AI-generated focus keywords, SEO titles, and meta descriptions.
Data is only sent when a user explicitly clicks an AI suggestion button. The data sent includes the post title and up to 2000 characters of post content (stripped of HTML), along with the user’s own API key for authentication. No data is sent automatically or in the background.
- Service URL: https://api.openai.com/v1/chat/completions
- Terms of Use: https://openai.com/policies/terms-of-use/
- Privacy Policy: https://openai.com/policies/privacy-policy/
Hooks for developers
RationalSEO exposes a complete set of filters and actions so themes and plugins can customize or extend output without forking the plugin. All hooks were introduced in version 1.0.6.
Short-circuit filters
Return non-null to short-circuit default resolution; return null to fall through to internal logic.
These filters let you override the data that RationalSEO resolves internally. Return a non-null value to bypass the built-in logic entirely, or return null to let RationalSEO proceed as normal.
rationalseo_og_image_data— Return a (partial) image data array; missing keys are filled with safe defaults. Signature:($pre, $context).rationalseo_meta_description— Return a string to override the meta description. An empty string''means “explicitly no description” and suppresses the tag. Signature:($pre, $context).rationalseo_post_seo_meta— Return an array of post SEO meta to override the database lookup. Signature:($pre, $post_id).rationalseo_term_seo_meta— Return an array of term SEO meta to override the database lookup. Signature:($pre, $term_id).
Per-value filters
These filters run on the resolved value just before it is output. All use the signature ($value, $context).
rationalseo_document_title— string. The<title>tag value before output.rationalseo_canonical_url— string. Therel=canonicalURL before output.rationalseo_robots— array. The robots directives array (joined with,for output).rationalseo_og_locale— string.og:localevalue before output.rationalseo_og_type— string.og:typevalue (e.g.website/article) before output.rationalseo_og_title— string.og:titlevalue before output.rationalseo_og_description— string.og:descriptionvalue before output.rationalseo_og_url— string.og:urlvalue before output.rationalseo_og_site_name— string.og:site_namevalue before output.rationalseo_twitter_card_type— string.twitter:cardvalue before output.rationalseo_twitter_title— string.twitter:titlevalue before output.rationalseo_twitter_description— string.twitter:descriptionvalue before output.
Skip filters
Return a truthy value to suppress an entire output block. Signature: ($skip, $context).
rationalseo_skip_meta_description— Skip the meta description tag entirely.rationalseo_skip_canonical— Skip the canonical link tag entirely.rationalseo_skip_open_graph— Skip all Open Graph tags entirely.rationalseo_skip_twitter_cards— Skip all Twitter Card tags entirely.
Example — disable Open Graph on the entire site:
add_filter( 'rationalseo_skip_open_graph', '__return_true' );
Action injection points
These actions fire immediately before and after each social meta block is emitted. They fire only when the block is not skipped via the corresponding skip filter. Signature: do_action( '...', $context ).
rationalseo_before_open_graph— Fires before the Open Graph tags are output.rationalseo_after_open_graph— Fires after the Open Graph tags are output.rationalseo_before_twitter_cards— Fires before the Twitter Card tags are output.rationalseo_after_twitter_cards— Fires after the Twitter Card tags are output.
Example — append a custom og:* tag after the standard Open Graph block:
add_action( 'rationalseo_after_open_graph', function( $ctx ) {
// Append extra og:* tags here.
echo "<meta property="og:custom" content="value" />n";
} );
The $context array
All per-value filters, skip filters, and action hooks receive a $context array as their last argument. It is built by the internal build_context() method and always contains the following keys:
mode— string. One of:front_page,home,singular,archive_term,archive_post_type,archive_author,archive_date,search,404,fallback.queried_object— mixed. Result ofget_queried_object()at resolution time. May beWP_Post,WP_Term,WP_Post_Type,WP_User, ornull.post_id— int. Queried post ID when on a singular view;0otherwise.term_id— int. Queried term ID when on a taxonomy archive;0otherwise.
Worked example
Override og:type to event for a custom post type, leaving all other post types unchanged:
add_filter( 'rationalseo_og_type', function( $type, $context ) {
if ( 'singular' === $context['mode'] && 'tribe_events' === get_post_type( $context['post_id'] ) ) {
return 'event';
}
return $type;
}, 10, 2 );
(tribe_events is illustrative — works for any CPT slug.)
