Schema markup tells search engines what a page is. Rank Math handles standard schema; complex local business and service pages need custom JSON-LD injection.
Rank Math Schema Setup
- Rank Math > Titles & Meta > Local SEO — enter business name, address, phone, hours, coordinates
- Rank Math > Schema > Templates — assign schemas to post types
- Schema types to configure per page type:
- Home/About: Organization + LocalBusiness
- Service pages: Service
- Blog posts: Article
- FAQ sections: FAQPage
- Reviews: Review
NAP Consistency Rule
NAP (Name, Address, Phone) in Rank Math must exactly match GMB:
- Same business name — no abbreviations
- Same address format (St vs Street)
- Same phone format (include area code)
- Same hours to the minute
Custom JSON-LD — LocalBusiness (functions.php)
add_action('wp_head', 'inject_local_business_schema');
function inject_local_business_schema() {
if (!is_front_page() && !is_page('about')) return;
$schema = [
'@context' => 'https://schema.org',
'@type' => 'LocalBusiness',
'name' => 'ACME Roofing',
'image' => 'https://example.com/logo.png',
'telephone' => '+1-555-123-4567',
'address' => [
'@type' => 'PostalAddress',
'streetAddress' => '123 Main St',
'addressLocality' => 'Miami',
'addressRegion' => 'FL',
'postalCode' => '33101',
'addressCountry' => 'US',
],
'geo' => [
'@type' => 'GeoCoordinates',
'latitude' => 25.7617,
'longitude' => -80.1918,
],
'openingHoursSpecification' => [[
'@type' => 'OpeningHoursSpecification',
'dayOfWeek' => ['Monday','Tuesday','Wednesday','Thursday','Friday'],
'opens' => '08:00',
'closes' => '18:00',
]],
'url' => home_url('/'),
'priceRange' => '$$',
];
echo '<script type="application/ld+json">'
. wp_json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
. '</script>';
}
Service Schema (Service Post Type)
add_action('wp_head', function() {
if (!is_singular('service')) return;
$schema = [
'@context' => 'https://schema.org',
'@type' => 'Service',
'name' => get_the_title(),
'description' => get_the_excerpt(),
'provider' => [
'@type' => 'LocalBusiness',
'name' => get_bloginfo('name'),
],
'areaServed' => [
'@type' => 'City',
'name' => 'Miami',
],
];
echo '<script type="application/ld+json">'
. wp_json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
. '</script>';
});
FAQ Schema
function inject_faq_schema(array $faqs): void {
$items = array_map(function($faq) {
return [
'@type' => 'Question',
'name' => $faq['question'],
'acceptedAnswer' => ['@type' => 'Answer', 'text' => $faq['answer']],
];
}, $faqs);
$schema = ['@context' => 'https://schema.org', '@type' => 'FAQPage', 'mainEntity' => $items];
echo '<script type="application/ld+json">'
. wp_json_encode($schema, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
. '</script>';
}
Validation
- Test at: https://search.google.com/test/rich-results
- Validate JSON-LD syntax at: https://jsonld.com/json-ld-validator/
- Check for errors in Google Search Console > Enhancements