WordPress Integration
Replace default WordPress sitemaps with SitemapHost using WP-CLI, webhooks, or a custom plugin
This guide covers how to integrate SitemapHost with a WordPress site. You will learn how to collect URLs from WordPress, push them to SitemapHost, disable the built-in or Yoast sitemap, and automate updates via WP-CLI or webhooks.
Prerequisites: A SitemapHost account, a configured domain, and an API key. See the Quick Start guide if you haven't set these up yet.
Why Use SitemapHost with WordPress?
WordPress generates sitemaps via its built-in wp-sitemap.xml (since WP 5.5) or through plugins like Yoast SEO. However, these have limitations:
- Performance -- Sitemap generation on each request can slow down large sites
- No CDN delivery -- Served from your origin server, adding load
- Limited splitting -- WordPress splits by content type but not by optimized chunk sizes
- No search engine notification -- You need additional plugins for IndexNow or GSC auto-submit
- Headless WordPress -- If your frontend is decoupled (Next.js, Gatsby, etc.), WP sitemaps point to the wrong URLs
SitemapHost solves all of these. Push your URLs once, and we handle hosting, splitting, CDN delivery, and search engine notifications.
Option 1: WP-CLI Script
The most straightforward approach for WordPress. Use WP-CLI to extract all published posts and pages, then push them to SitemapHost.
Create the script
Save this as push-sitemap.sh in your WordPress root:
#!/bin/bash
# push-sitemap.sh -- Push WordPress URLs to SitemapHost
SITEMAPHOST_API_KEY="${SITEMAPHOST_API_KEY:-sk_live_xxxxxxxxxxxxxxxx}"
SITEMAPHOST_DOMAIN="${SITEMAPHOST_DOMAIN:-sitemap.yoursite.com}"
SITE_URL="${SITE_URL:-https://yoursite.com}"
# Fetch all published post URLs using WP-CLI
echo "Collecting URLs from WordPress..."
# Get pages
PAGES=$(wp post list --post_type=page --post_status=publish --fields=ID,post_name,post_modified --format=json)
# Get posts
POSTS=$(wp post list --post_type=post --post_status=publish --fields=ID,post_name,post_modified --format=json)
# Build JSON payload using a helper script
php -r "
\$pages = json_decode('$PAGES', true);
\$posts = json_decode('$POSTS', true);
\$urls = [];
foreach (\$pages as \$page) {
\$permalink = trim(shell_exec('wp post url ' . \$page['ID']));
\$urls[] = [
'loc' => \$permalink,
'lastmod' => date('Y-m-d', strtotime(\$page['post_modified'])),
];
}
foreach (\$posts as \$post) {
\$permalink = trim(shell_exec('wp post url ' . \$post['ID']));
\$urls[] = [
'loc' => \$permalink,
'lastmod' => date('Y-m-d', strtotime(\$post['post_modified'])),
];
}
echo json_encode([
'domain' => '$SITEMAPHOST_DOMAIN',
'sizeLimit' => 'gsc-optimized',
'urls' => \$urls,
]);
" > /tmp/sitemap-payload.json
echo "Pushing $(cat /tmp/sitemap-payload.json | php -r 'echo count(json_decode(file_get_contents("php://stdin"), true)["urls"]);') URLs to SitemapHost..."
curl -s -X POST https://dash.sitemaphost.app/api/sitemap/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: $SITEMAPHOST_API_KEY" \
-d @/tmp/sitemap-payload.json
rm /tmp/sitemap-payload.json
echo ""
echo "Done!"Run it:
chmod +x push-sitemap.sh
./push-sitemap.shSchedule with cron
Add a cron job to run the script periodically:
# Run every 6 hours
0 */6 * * * cd /var/www/html && ./push-sitemap.sh >> /var/log/sitemap-push.log 2>&1Option 2: PHP Helper Function
For more control, add a PHP function to your theme's functions.php or a custom plugin:
<?php
/**
* Push all published URLs to SitemapHost
*/
function sitemaphost_push_urls() {
$api_key = defined('SITEMAPHOST_API_KEY')
? SITEMAPHOST_API_KEY
: 'sk_live_xxxxxxxxxxxxxxxx';
$domain = defined('SITEMAPHOST_DOMAIN')
? SITEMAPHOST_DOMAIN
: 'sitemap.yoursite.com';
$urls = [];
// Get all published pages
$pages = get_posts([
'post_type' => 'page',
'post_status' => 'publish',
'numberposts' => -1,
]);
foreach ($pages as $page) {
$urls[] = [
'loc' => get_permalink($page->ID),
'lastmod' => get_the_modified_date('Y-m-d', $page),
];
}
// Get all published posts
$posts = get_posts([
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => -1,
]);
foreach ($posts as $post) {
$urls[] = [
'loc' => get_permalink($post->ID),
'lastmod' => get_the_modified_date('Y-m-d', $post),
];
}
// Include custom post types
$custom_types = get_post_types(['public' => true, '_builtin' => false]);
foreach ($custom_types as $type) {
$custom_posts = get_posts([
'post_type' => $type,
'post_status' => 'publish',
'numberposts' => -1,
]);
foreach ($custom_posts as $post) {
$urls[] = [
'loc' => get_permalink($post->ID),
'lastmod' => get_the_modified_date('Y-m-d', $post),
];
}
}
// Push to SitemapHost
$response = wp_remote_post(
'https://dash.sitemaphost.app/api/sitemap/generate',
[
'headers' => [
'Content-Type' => 'application/json',
'X-API-Key' => $api_key,
],
'body' => json_encode([
'domain' => $domain,
'sizeLimit' => 'gsc-optimized',
'urls' => $urls,
]),
'timeout' => 30,
]
);
if (is_wp_error($response)) {
error_log('SitemapHost push failed: ' . $response->get_error_message());
return false;
}
$body = json_decode(wp_remote_retrieve_body($response), true);
error_log('SitemapHost: Pushed ' . count($urls) . ' URLs');
return $body;
}
Define constants in wp-config.php
// wp-config.php
define('SITEMAPHOST_API_KEY', 'sk_live_xxxxxxxxxxxxxxxx');
define('SITEMAPHOST_DOMAIN', 'sitemap.yoursite.com');Option 3: Webhook on Publish
Automatically push to SitemapHost every time a post is published or updated:
<?php
/**
* Push sitemap to SitemapHost when a post is published or updated.
* Add this to functions.php or a custom plugin.
*/
add_action('publish_post', 'sitemaphost_on_publish', 10, 2);
add_action('publish_page', 'sitemaphost_on_publish', 10, 2);
function sitemaphost_on_publish($post_id, $post) {
// Avoid triggering on autosaves or revisions
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (wp_is_post_revision($post_id)) return;
// Schedule a full sitemap push (debounced with a transient)
if (false === get_transient('sitemaphost_push_pending')) {
set_transient('sitemaphost_push_pending', true, 60);
// Schedule the push for 60 seconds from now to batch rapid edits
wp_schedule_single_event(time() + 60, 'sitemaphost_do_push');
}
}
add_action('sitemaphost_do_push', 'sitemaphost_push_urls');
This approach debounces rapid edits -- if you publish 5 posts in quick succession, it only pushes once.
Named Sitemaps for WordPress
Organize your WordPress URLs into separate sitemaps by content type:
<?php
function sitemaphost_push_named_sitemaps() {
$api_key = SITEMAPHOST_API_KEY;
$domain = SITEMAPHOST_DOMAIN;
// Push pages sitemap
$pages = get_posts(['post_type' => 'page', 'post_status' => 'publish', 'numberposts' => -1]);
sitemaphost_push('pages', array_map(function($p) {
return ['loc' => get_permalink($p->ID), 'lastmod' => get_the_modified_date('Y-m-d', $p)];
}, $pages));
// Push blog sitemap
$posts = get_posts(['post_type' => 'post', 'post_status' => 'publish', 'numberposts' => -1]);
sitemaphost_push('blog', array_map(function($p) {
return ['loc' => get_permalink($p->ID), 'lastmod' => get_the_modified_date('Y-m-d', $p)];
}, $posts));
// Push products sitemap (WooCommerce)
if (post_type_exists('product')) {
$products = get_posts(['post_type' => 'product', 'post_status' => 'publish', 'numberposts' => -1]);
sitemaphost_push('products', array_map(function($p) {
$images = [];
$thumb_id = get_post_thumbnail_id($p->ID);
if ($thumb_id) {
$images[] = [
'loc' => wp_get_attachment_url($thumb_id),
'title' => get_post_meta($thumb_id, '_wp_attachment_image_alt', true),
];
}
return [
'loc' => get_permalink($p->ID),
'lastmod' => get_the_modified_date('Y-m-d', $p),
'images' => $images ?: null,
];
}, $products));
}
}
function sitemaphost_push($sitemap_name, $urls) {
wp_remote_post('https://dash.sitemaphost.app/api/sitemap/generate', [
'headers' => [
'Content-Type' => 'application/json',
'X-API-Key' => SITEMAPHOST_API_KEY,
],
'body' => json_encode([
'domain' => SITEMAPHOST_DOMAIN,
'sitemapName' => $sitemap_name,
'sizeLimit' => 'gsc-optimized',
'urls' => array_values($urls),
]),
'timeout' => 30,
]);
}
Disabling Built-In WordPress Sitemaps
Disable WordPress Core Sitemaps (WP 5.5+)
Add to your functions.php:
// Disable WordPress core sitemaps entirely
add_filter('wp_sitemaps_enabled', '__return_false');Disable Yoast SEO Sitemaps
If you use Yoast SEO, disable its sitemap generation:
- Go to Yoast SEO > Settings > Site Features
- Toggle XML sitemaps to Off
Or programmatically:
// Disable Yoast sitemaps
add_filter('wpseo_sitemaps_enabled', '__return_false');Disable Rank Math Sitemaps
// Disable Rank Math sitemaps
add_filter('rank_math/sitemap/enabled', '__return_false');Disable All in One SEO Sitemaps
Go to All in One SEO > Sitemaps and toggle the sitemap feature off.
Update robots.txt
Point your robots.txt to your SitemapHost URL. You can do this via WordPress:
// functions.php
add_filter('robots_txt', function($output, $public) {
$output .= "\nSitemap: https://sitemap.yoursite.com/sitemap.xml\n";
return $output;
}, 10, 2);Or edit your physical robots.txt file:
User-agent: *
Allow: /
Sitemap: https://sitemap.yoursite.com/sitemap.xmlHeadless WordPress
If you use WordPress as a headless CMS with a separate frontend (Next.js, Gatsby, Nuxt), the sitemap URLs should point to your frontend domain, not the WordPress admin URL.
<?php
// For headless WordPress: override the permalink base
define('SITEMAPHOST_FRONTEND_URL', 'https://yoursite.com');
function sitemaphost_headless_push() {
$frontend_url = SITEMAPHOST_FRONTEND_URL;
$posts = get_posts([
'post_type' => 'post',
'post_status' => 'publish',
'numberposts' => -1,
]);
$urls = array_map(function($post) use ($frontend_url) {
// Build frontend URL from slug instead of using get_permalink()
return [
'loc' => $frontend_url . '/blog/' . $post->post_name,
'lastmod' => get_the_modified_date('Y-m-d', $post),
];
}, $posts);
// Push to SitemapHost
wp_remote_post('https://dash.sitemaphost.app/api/sitemap/generate', [
'headers' => [
'Content-Type' => 'application/json',
'X-API-Key' => SITEMAPHOST_API_KEY,
],
'body' => json_encode([
'domain' => SITEMAPHOST_DOMAIN,
'sizeLimit' => 'gsc-optimized',
'urls' => $urls,
]),
'timeout' => 30,
]);
}
Next Steps
- API Reference -- Full request/response documentation
- Multi-Sitemap Support -- Organize URLs by content type
- Image Sitemaps -- Include WordPress featured images