A sitemap.xml file is crucial for search engines to understand your website's structure, helping them crawl and index content more efficiently. While plugins offer convenience, implementing a sitemap with pure code eliminates plugin dependency, reduces server load, and provides finer control. This guide explains how to automatically generate sitemap.xml in WordPress by adding a code file.
Implementation Steps
1. Create the sitemap.php File
First, create a new file named sitemap.php in your WordPress root directory. Copy and paste the following code into it.
<?php
/**
* WordPress Sitemap Generator
* Generates sitemap.xml including homepage, posts, pages, categories, and tags.
*/
require('./wp-blog-header.php');
header("Content-type: text/xml; charset=UTF-8");
header('HTTP/1.1 200 OK');
$posts_to_show = 1000; // Limit post count to avoid oversized file
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
?>
<!-- Homepage -->
<url>
<loc><?php echo esc_url(get_home_url()); ?></loc>
<lastmod><?php $ltime = get_lastpostmodified('GMT'); $ltime = gmdate('Y-m-dTH:i:s+00:00', strtotime($ltime)); echo $ltime; ?></lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
<?php
/* Posts */
$myposts = get_posts( "numberposts=" . $posts_to_show );
foreach( $myposts as $post ) {
setup_postdata($post);
?>
<url>
<loc><?php the_permalink(); ?></loc>
<lastmod><?php the_time('c'); ?></lastmod>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<?php
wp_reset_postdata();
}
?>
<?php
/* Pages */
$mypages = get_pages();
if(count($mypages) > 0) {
foreach($mypages as $page) {
?>
<url>
<loc><?php echo esc_url(get_page_link($page->ID)); ?></loc>
<lastmod><?php echo str_replace(" ", "T", $page->post_modified); ?>+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.6</priority>
</url>
<?php
}
}
?>
<?php
/* Categories */
$terms = get_terms(array('taxonomy' => 'category', 'hide_empty' => false));
$count = count($terms);
if($count > 0){
foreach ($terms as $term) {
$term_link = get_term_link($term);
if (is_wp_error($term_link)) continue;
?>
<url>
<loc><?php echo esc_url($term_link); ?></loc>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<?php
}
}
?>
<?php
/* Tags (optional) */
$tags = get_terms(array('taxonomy' => 'post_tag', 'hide_empty' => false));
foreach ( $tags as $tag ) {
$link = get_term_link($tag);
if (is_wp_error($link)) continue;
?>
<url>
<loc><?php echo esc_url($link); ?></loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
<?php
}
?>
</urlset>
Key Improvements:
- Security: Uses
esc_url()to escape output URLs. - Compatibility: Updated
get_terms()syntax for newer WordPress versions. - Structure: Properly uses
setup_postdata()andwp_reset_postdata()in post loops. - Standards: Removed non-standard mobile namespace for Sitemaps.org compliance.
- Comments: Added explanatory comments for clarity.
After creating the file, upload it to your WordPress root directory (same level as wp-config.php).
2. Configure Access Rules (URL Rewriting)
To access the sitemap via https://yourdomain.com/sitemap.xml, configure server rewrite rules.
Apache (.htaccess): Edit the .htaccess file in your root directory. Add this rule before existing WordPress rules:
# Sitemap Rewrite Rule
RewriteRule ^sitemap.xml$ /sitemap.php [L]
Nginx (e.g., via Baota Panel): In your site settings, select the "WordPress" rewrite rule from the "Pseudo-static" tab and restart Nginx. If issues persist, manually add a similar rewrite directive or consult your host.
3. Testing and Validation
- Disable other sitemap plugins to prevent conflicts.
- Access the sitemap at
https://yourdomain.com/sitemap.xml. - Verify the XML output contains your homepage, posts, pages, etc.
- Submit the sitemap URL to search engines like Google Search Console.
You now have a lightweight, plugin-free sitemap generator for WordPress, offering full control without external dependencies.