Skip to main content

Overview

GEO AI automatically generates Schema.org JSON-LD markup to help search engines and AI answer engines understand your content structure. Supports Article, Organization, WebSite, SearchAction, and more.
Schema markup can increase click-through rates by 30% by enabling rich snippets in search results.

Supported Schema Types

Article Schema

Automatically added to single posts. Includes headline, author, publish date, modified date, and publisher information.

Organization Schema

Appears on homepage. Defines your site as an organization with name, URL, and logo.

WebSite Schema

Added to homepage with SearchAction for sitewide search functionality.

BreadcrumbList Schema

Generated automatically by the breadcrumbs feature for navigation context.

Configuration

1

Access Schema Settings

Navigate to Settings → GEO AI → Schema
2

Enable Schema Types

Check the schema types you want to enable:
  • Article (for blog posts)
  • FAQ Page
  • HowTo
  • Organization
  • WebSite + SearchAction
3

Save Changes

Click Save Changes to activate schema output

Implementation Details

Core Schema Class

includes/class-geoai-schema.php
class GeoAI_Schema {
    private static $instance = null;

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        add_action( 'wp_head', array( $this, 'output_schema' ), 2 );
    }

    public function output_schema() {
        if ( ! GeoAI_Compat::get_instance()->should_output_meta() ) {
            return;
        }

        $defaults = get_option( 'geoai_schema_defaults', array() );
        $schema   = array();

        if ( is_front_page() && ! empty( $defaults['website'] ) ) {
            $schema[] = $this->get_website_schema();
        }

        if ( is_front_page() && ! empty( $defaults['organization'] ) ) {
            $schema[] = $this->get_organization_schema();
        }

        if ( is_singular( 'post' ) && ! empty( $defaults['article'] ) ) {
            $schema[] = $this->get_article_schema();
        }

        $schema = apply_filters( 'geoai_schema_output', $schema );

        if ( ! empty( $schema ) ) {
            echo '<script type="application/ld+json">' . "\n";
            echo wp_json_encode( 
                array( '@context' => 'https://schema.org', '@graph' => $schema ), 
                JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT 
            );
            echo "\n" . '</script>' . "\n";
        }
    }
}

WebSite Schema with SearchAction

includes/class-geoai-schema.php
private function get_website_schema() {
    return array(
        '@type'         => 'WebSite',
        '@id'           => home_url( '/#website' ),
        'url'           => home_url( '/' ),
        'name'          => get_bloginfo( 'name' ),
        'description'   => get_bloginfo( 'description' ),
        'potentialAction' => array(
            '@type'       => 'SearchAction',
            'target'      => array(
                '@type'       => 'EntryPoint',
                'urlTemplate' => home_url( '/?s={search_term_string}' ),
            ),
            'query-input' => 'required name=search_term_string',
        ),
    );
}

Organization Schema

includes/class-geoai-schema.php
private function get_organization_schema() {
    return array(
        '@type' => 'Organization',
        '@id'   => home_url( '/#organization' ),
        'name'  => get_bloginfo( 'name' ),
        'url'   => home_url( '/' ),
    );
}

Article Schema

includes/class-geoai-schema.php
private function get_article_schema() {
    $post = get_post();
    
    return array(
        '@type'            => 'Article',
        '@id'              => get_permalink() . '#article',
        'headline'         => get_the_title(),
        'description'      => wp_trim_words( get_the_excerpt(), 30 ),
        'datePublished'    => get_the_date( 'c' ),
        'dateModified'     => get_the_modified_date( 'c' ),
        'author'           => array(
            '@type' => 'Person',
            'name'  => get_the_author(),
        ),
        'publisher'        => array(
            '@type' => 'Organization',
            'name'  => get_bloginfo( 'name' ),
        ),
        'mainEntityOfPage' => array(
            '@type' => 'WebPage',
            '@id'   => get_permalink(),
        ),
    );
}

Schema Output Example

For a blog post, GEO AI outputs:
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Article",
      "@id": "https://example.com/my-post/#article",
      "headline": "How to Optimize WordPress for AI Search",
      "description": "Learn proven strategies to optimize your WordPress site for AI-powered search engines including Google AI Overviews and Perplexity.",
      "datePublished": "2025-03-01T10:00:00+00:00",
      "dateModified": "2025-03-04T15:30:00+00:00",
      "author": {
        "@type": "Person",
        "name": "John Doe"
      },
      "publisher": {
        "@type": "Organization",
        "name": "My WordPress Site"
      },
      "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://example.com/my-post/"
      }
    }
  ]
}
</script>

Extending Schema Output

Add custom schema types using the filter:
add_filter( 'geoai_schema_output', 'add_custom_schema' );

function add_custom_schema( $schema ) {
    if ( is_singular( 'product' ) ) {
        $schema[] = array(
            '@type' => 'Product',
            '@id'   => get_permalink() . '#product',
            'name'  => get_the_title(),
            'description' => get_the_excerpt(),
            'offers' => array(
                '@type' => 'Offer',
                'price' => get_post_meta( get_the_ID(), '_price', true ),
                'priceCurrency' => 'USD',
                'availability' => 'https://schema.org/InStock',
            ),
        );
    }
    
    return $schema;
}

Compatibility Mode

If using another SEO plugin (Yoast, Rank Math, SEOPress), enable Coexist Mode to prevent duplicate schema output.

Enabling Coexist Mode

1

Go to Settings

Navigate to Settings → GEO AI → General
2

Set Compatibility Mode

Select “Coexist (Suppress Overlapping Outputs)”
3

Save

Click Save Changes
When coexist mode is active:
  • GEO AI detects other SEO plugins
  • Suppresses its own schema output if conflicts exist
  • Preserves AI-specific features (audits, Answer Cards)

Validation

Validate your schema markup:

Google Rich Results Test

Test how Google sees your structured data

Schema.org Validator

Validate against official schema.org specs
1

Copy Page URL

Get the full URL of any published page or post
2

Test with Google

3

Review Results

Check for errors or warnings and fix any issues
4

Validate Schema

Use Schema.org Validator for additional checks

Common Schema Types

Use for: Blog posts, news articles, editorial contentRequired properties:
  • headline
  • datePublished
  • author
  • publisher
Enables: Article rich snippets in search results
Use for: Pages with frequently asked questionsRequired properties:
  • mainEntity (array of Question/Answer pairs)
Enables: Expandable FAQ dropdowns in search resultsStatus: Planned for v1.2
Use for: Step-by-step guides and tutorialsRequired properties:
  • name
  • step (array of HowToStep)
Enables: Rich step-by-step snippets with imagesStatus: Planned for v1.2
Use for: E-commerce product pagesRequired properties:
  • name
  • image
  • offers (price, availability)
Enables: Product rich snippets with pricing and ratingsStatus: Planned for v1.2
Use for: Local business websitesRequired properties:
  • name
  • address
  • telephone
Enables: Local business knowledge panelsStatus: Planned for v1.2

Best Practices

Use Specific Types

Use the most specific schema type available. “Article” is better than generic “CreativeWork”.

Complete All Required Properties

Fill in all required properties for your schema type to ensure valid markup.

Include Images

Add featured images to posts. Schema can include image URLs for better rich results.

Keep Dates Accurate

Update modified dates when making significant content changes.

Avoid Spam

Don’t add irrelevant schema types or false information. Google may penalize spam.

Test Regularly

Validate schema after theme changes or plugin updates.

Troubleshooting

Check:
  • Schema types are enabled in Settings → Schema
  • Compatibility mode is configured correctly
  • View page source to verify <script type="application/ld+json"> is present
Cause: Multiple SEO plugins outputting schemaSolution: Enable Coexist Mode or disable schema in other plugins
Common issues:
  • Missing required properties (headline, datePublished)
  • Invalid date formats (use ISO 8601)
  • Missing publisher information
Solution: Use Google Rich Results Test to identify specific errors

Breadcrumbs

Add BreadcrumbList schema

AI Audit

Schema validation in audits

Social Cards

OpenGraph structured data

Build docs developers (and LLMs) love