How to Create a Custom XML Sitemap in WordPress without Plugins

In this comprehensive guide, we’ll walk you through the process of creating a custom XML sitemap for your WordPress website. A sitemap is like a roadmap for search engines, guiding them through the intricate maze of your content. It plays a crucial role in enhancing your site’s visibility and ensuring that search engines index your pages efficiently.

A sitemap is essentially a list of all the pages on your site, providing search engines with essential information about your content, such as when it was last updated, how often it changes, and how important it is. This matters because search engines use this data to crawl and index your site, leading to better search engine optimization (SEO) and improved visibility in search results.

Create a Custom Page Template

In your child theme, create a new file named custom-sitemap.php. Open the file and use PHP comments to define the template header.

<?php
/*
 * Template Name: Custom Sitemap
 */
?>
Code language: PHP (php)

Code Explanation:

  • The PHP comment /* ... */ is used to provide information about the purpose of this file. In WordPress, this information is recognized as the template name.

Retrieve and Output Sitemap Data

In the custom-sitemap.php file, add the following code to retrieve and output the sitemap data.

<?php
// Set the content type header to indicate that the file being output is in XML format.
header( 'Content-Type: application/xml' );

// Outputs the XML declaration with the specified version and encoding.
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
		xmlns:xhtml="http://www.w3.org/1999/xhtml"
		xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
		xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
		xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
	<?php
	// Retrieves posts of specified types (post, page, custom_post_type) using the get_posts function.
	$custom_posts = get_posts(
		array(
			'post_type'   => array( 'post', 'page', 'custom_post_type' ),
			'numberposts' => -1,
		)
	);

	// Initiates a loop to iterate through each post, creating a sitemap entry for each.
	foreach ( $custom_posts as $custom_post ) :
		?>
		<url>
			<!-- Outputs the post URL within the <loc> tag, ensuring proper escaping with esc_url. -->
			<loc><?php echo esc_url( get_permalink( $custom_post->ID ) ); ?></loc>
			
			<!-- Outputs the last modification date within the <lastmod> tag, ensuring proper escaping with esc_html. -->
			<lastmod><?php echo esc_html( get_the_modified_date( 'c', $custom_post->ID ) ); ?></lastmod>
			
			<!-- Specifies the frequency of change for search engines. In this example, it's set to weekly. -->
			<changefreq>weekly</changefreq>
			
			<!-- Specifies the priority of the page relative to other pages on the site. -->
			<!-- The choice of priority is subjective and depends on the importance of the page within your site hierarchy. -->
			<!-- The value ranges from 0.0 to 1.0, where 1.0 is the highest priority. -->
			<!-- Setting it to 0.8 suggests a relatively high priority, but you can adjust based on your content hierarchy. -->
			<priority>0.8</priority>

			<!-- Checks if there is a custom field (custom_field_name) associated with the post. -->
			<!-- If a custom field exists, its value is included in the sitemap within a <customField> tag. Proper escaping is applied. -->
			<?php
			$custom_field_val = get_post_meta( $custom_post->ID, 'custom_field_name', true );
			if ( $custom_field_val ) {
				echo '<customField>' . esc_html( $custom_field_val ) . '</customField>';
			}
			?>

			<!-- Add more custom elements as needed -->

		</url>
	<?php endforeach; ?>
</urlset>

Code language: PHP (php)

Code Explanation:

  • header('Content-Type: application/xml');:
    • Sets the HTTP header to inform the browser that the content being sent is in XML format.
  • <?xml version="1.0" encoding="UTF-8"?>:
    • Outputs the XML declaration with the specified version and encoding.
  • <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"...:
    • Initiates the XML structure for the sitemap with namespaces for different elements like XHTML, image, news, and video.
  • $custom_posts = get_posts(array(...:
    • Retrieves posts of specified types (post, page, custom_post_type) using the get_posts function.
  • foreach ($custom_posts as $custom_post) ::
    • Initiates a loop to iterate through each post, creating a sitemap entry for each.
  • <loc><?php echo esc_url(get_permalink($custom_post->ID)); ?></loc>:
    • Outputs the post URL within the <loc> tag, ensuring proper escaping with esc_url.
  • <lastmod><?php echo esc_html(get_the_modified_date('c', $custom_post->ID)); ?></lastmod>:
    • Outputs the last modification date within the <lastmod> tag, ensuring proper escaping with esc_html.
  • <changefreq>weekly</changefreq>:
    • Specifies the frequency of change for search engines. In this example, it’s set to weekly.
  • <priority>0.8</priority>:
    • Specifies the priority of the page relative to other pages on the site. It’s set to 0.8 in this example.
    • Priority Explanation: The priority attribute indicates the importance of a particular URL relative to other URLs on your site. It’s a value between 0.0 and 1.0, with 1.0 being the highest priority. The choice of priority is subjective and depends on the structure of your site. Setting it to 0.8 suggests a relatively high priority, but this can be adjusted based on your content hierarchy. For example, your homepage might have a higher priority than individual posts.
  • <?php...:
    • Checks if there is a custom field (custom_field_name) associated with the post and includes it in the sitemap within a <customField> tag. Proper escaping is applied.
    • Custom Field Explanation: Custom fields provide a way to include additional information about your posts. In this example, the code checks for a custom field named ‘custom_field_name’ associated with each post. If the custom field exists, its value is included in the sitemap within a <customField> tag. This can be useful for providing search engines with extra metadata or classifications related to your content.
  • </url>:
    • Closes the <url> tag for each sitemap entry.
  • endforeach;:
    • Ends the loop for iterating through each post.
  • </urlset>:
    • Closes the <urlset> tag, completing the XML structure for the sitemap.

Upload the Template to Your Child Theme

Save the custom-sitemap.php file and upload it to your child theme directory.

Create a WordPress Page and Visit the Sitemap Page

In the WordPress admin, navigate to Pages and create a new page. Assign the “Custom Sitemap” template to this page. Visit the page you created (e.g., https://yoursite.com/custom-sitemap) to view your custom sitemap.

Submit Your Sitemap to Search Engines

Sign in to your Google Search Console account. Select your website property. Navigate to the “Sitemaps” section. Enter the sitemap URL (e.g., https://yoursite.com/custom-sitemap) and submit it. Repeat the process for other search engines like Bing.

That’s it! You’ve successfully created a custom XML sitemap for your WordPress site without relying on plugins. By submitting your sitemap to search engines, you’re ensuring that they have the necessary information to index your site effectively, leading to improved visibility in search results.

Leave your feedback and help us improve ๐Ÿถ

We hope you found this article helpful! If you have any questions, feedback, or spot any errors, please let us know in the comments. Your input is valuable and helps us improve. If you liked this article, please consider sharing it with others. And if you really enjoyed it, you can show your support by buying us a cup of coffee โ˜•๏ธ or donating via PayPal ๐Ÿ’ฐ.

More free knowledge, because why not?

2 Comments

  • How is it different from xml sitemaps created from SEO plugins like Yoast or Rankmath?

    Reply
    • Hi Thanh Thai,

      Great question! The custom XML sitemap created in this tutorial differs from those generated by SEO plugins like Yoast or RankMath in a few ways:

      Control and Customization:
      The tutorial provides a hands-on approach, allowing you to have direct control over the content and structure of your XML sitemap. You can tailor it to meet the specific needs of your website.

      Plugin Independence:
      Unlike SEO plugins that automate the sitemap creation process, the tutorial demonstrates how to achieve this without relying on any plugins. This can be appealing to users who prefer a lightweight setup without additional plugin dependencies.

      Specificity to Your Requirements:
      Customization in the tutorial extends to including custom fields associated with your posts in the sitemap. This provides a way to include additional metadata or classifications that may be specific to your content.

      Learning and Understanding:
      Creating a custom XML sitemap manually allows you to understand the inner workings and structure of the sitemap. It’s a valuable learning experience for those who want a deeper understanding of how XML sitemaps function.

      While SEO plugins offer convenience and are suitable for many users, creating a custom XML sitemap can be a preferred choice for those who seek more hands-on control, minimal reliance on plugins, and specific customization options.

      Hope this clarifies the differences!

      Reply

Your thoughts matter, leave a reply ๐Ÿ’ฌ

Your email address will not be published. Required fields are marked *