If you’ve been following my WordPress fast stack guides, you’ll know I’m a big fan of nginx for the speed and scalability it provides. Some of you asked how to configure nginx with that stack guide to work with Yoast SEO sitemaps. The guide below covers our stacks, but will also work for any nginx users.
Table of Contents
Add the Yoast sitemap rewrite rules to your sites-available config file
With our rocket stack guide, the nginx file you need to edit will be:
/etc/nginx/sites-available/rocketstack.conf
So – either edit that file through FileZilla, or log into your server using SSH and run the following:
vi /etc/nginx/sites-available/rocketstack.conf
The only thing that really matters in terms of where to place the following code is to make sure it goes inside your server { … } blocks. With our guide there are two of these, one for HTTP and one for HTTPS, so you’ll need to paste this code twice.
# Rewrites for Yoast SEO XML Sitemap
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
location ~ ([^/]*)sitemap(.*).x(m|s)l$ {
## this rewrites sitemap.xml to /sitemap_index.xml
rewrite ^/sitemap.xml$ /sitemap_index.xml permanent;
## this makes the XML sitemaps work
rewrite ^/([a-z]+)?-?sitemap.xsl$ /index.php?xsl=$1 last;
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
## The following lines are optional for the premium extensions
## News SEO
rewrite ^/news-sitemap.xml$ /index.php?sitemap=wpseo_news last;
## Local SEO
rewrite ^/locations.kml$ /index.php?sitemap=wpseo_local_kml last;
rewrite ^/geo-sitemap.xml$ /index.php?sitemap=wpseo_local last;
## Video SEO
rewrite ^/video-sitemap.xsl$ /index.php?xsl=video last;
}
Once you’ve edited the file, save it, then exit your editor.
Test for errors then restart nginx
On your server (putty, ssh etc), run the following command to double check you didn’t break your nginx config before you restart:
nginx -t
Once it has confirmed the file is ok, you can restart nginx using:
service nginx restart
Test your sitemap
From your wp-admin, visit SEO->General->Features tab then scroll to the sitemap and click the (i) button. It’ll tell you the URL for your sitemap.
Alternatively, just visit yourdomain.com/sitemap.xml or yourdomain.com/sitemap_index.html.
A tidier way to do this
I’ve added an extra Yoast-specific snippet to our Rocket Stack github repo. So, another way to do this would be to download those snippets and then have just this line inside both your server blocks:
include snippets/yoast-sitemaps.xml
You can find instructions to downloading our repo in our full WordPress Rocket Stack guide.
Summary
If you are using other sitemap plugins, there should be nginx-specific instructions that come with it to tell your web-server how to rewrite the pretty permalinks to feed the correct parameters to your sitemap generation plugin.
In the guide above, I’ve shown how to do this for Yoast specifically, but similar steps will work for all sitemap plugins.
Yep restarted service and zippo!
Here is the conf:
# This config file uses nginx fastcgi-cache
fastcgi_cache_path /var/www/cache/evolutionit levels=1:2 keys_zone=evolutionit:100m inactive=60m;
server {
listen 80;
server_name evolutionitservice.com;
root /var/www/evolutionit;
index index.php index.htm index.html;
access_log /var/log/nginx/evolutionit_access.log;
error_log /var/log/nginx/evolutionit_error.log;
include snippets/gzip.conf
#include snippets/yoast-sitemaps.xml;
include snippets/acme-challenge.conf;
# Rewrites for Yoast SEO XML Sitemap EJS
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
location ~ ([^/]*)sitemap(.*).x(m|s)l$ {
## this rewrites sitemap.xml to /sitemap_index.xml
rewrite ^/sitemap.xml$ /sitemap_index.xml permanent;
## this makes the XML sitemaps work
rewrite ^/([a-z]+)?-?sitemap.xsl$ /index.php?xsl=$1 last;
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
## The following lines are optional for the premium extensions
## News SEO
rewrite ^/news-sitemap.xml$ /index.php?sitemap=wpseo_news last;
## Local SEO
rewrite ^/locations.kml$ /index.php?sitemap=wpseo_local_kml last;
rewrite ^/geo-sitemap.xml$ /index.php?sitemap=wpseo_local last;
## Video SEO
rewrite ^/video-sitemap.xsl$ /index.php?xsl=video last;
}
# Exclusions
include snippets/exclusions.conf;
# Security
include snippets/security.conf;
# Static Content
include snippets/static-files.conf;
# Fastcgi cache rules
include snippets/fastcgi-cache.conf;
include snippets/limits.conf;
include snippets/nginx-cloudflare.conf;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-params.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# Skip cache based on rules in snippets/fastcgi-cache.conf.
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
# Define memory zone for caching. Should match key_zone in fastcgi_cache_path above.
fastcgi_cache evolutionit;
# Define caching time.
fastcgi_cache_valid 60m;
#increase timeouts
fastcgi_read_timeout 6000;
fastcgi_connect_timeout 6000;
fastcgi_send_timeout 6000;
proxy_read_timeout 6000;
proxy_connect_timeout 6000;
proxy_send_timeout 6000;
send_timeout 6000;
#these lines should be the ones to allow Cloudflare Flexible SSL to be used so the server does not need to decrypt SSL
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
server {
listen 443 ssl default_server;
server_name evolutionitservice.com;
root /var/www/evolutionit;
index index.php index.htm index.html;
#Include Yoast Sitemap Config
# include snippets/yoast-sitemaps.xml;
# Rewrites for Yoast SEO XML Sitemap EJS
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
location ~ ([^/]*)sitemap(.*).x(m|s)l$ {
## this rewrites sitemap.xml to /sitemap_index.xml
rewrite ^/sitemap.xml$ /sitemap_index.xml permanent;
## this makes the XML sitemaps work
rewrite ^/([a-z]+)?-?sitemap.xsl$ /index.php?xsl=$1 last;
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
## The following lines are optional for the premium extensions
## News SEO
rewrite ^/news-sitemap.xml$ /index.php?sitemap=wpseo_news last;
## Local SEO
rewrite ^/locations.kml$ /index.php?sitemap=wpseo_local_kml last;
rewrite ^/geo-sitemap.xml$ /index.php?sitemap=wpseo_local last;
## Video SEO
rewrite ^/video-sitemap.xsl$ /index.php?xsl=video last;
}
access_log /var/log/nginx/evolutionit_ssl_access.log;
error_log /var/log/nginx/evolutionit_ssl_error.log;
#once you have SSL certificates using LetsEncrypt you can alter the paths in the two lines below to reflect your domain and uncomment the lines by removing the leading # symbol
#ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Exclusions
include snippets/exclusions.conf;
# Security
include snippets/security.conf;
# Static Content
include snippets/static-files.conf;
# Fastcgi cache rules
include snippets/fastcgi-cache.conf;
include snippets/limits.conf;
include snippets/nginx-cloudflare.conf;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include snippets/fastcgi-params.conf;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# Skip cache based on rules in snippets/fastcgi-cache.conf.
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
# Define memory zone for caching. Should match key_zone in fastcgi_cache_path above.
fastcgi_cache evolutionit;
# Define caching time.
fastcgi_cache_valid 60m;
#increase timeouts
fastcgi_read_timeout 6000;
fastcgi_connect_timeout 6000;
fastcgi_send_timeout 6000;
proxy_read_timeout 6000;
proxy_connect_timeout 6000;
proxy_send_timeout 6000;
send_timeout 6000;
#these lines should be the ones to allow Cloudflare Flexible SSL to be used so the server does not need to decrypt SSL if you wish
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-NginX-Proxy true;
It looks like your first server {} block for port 80 does not have the closing brace. ‘}’ is missing.
I have been using your config stacks for a few websites and had no issues but I cannot get the nginx rewrites to actually work on this one site. I have gone and looked at all configs and setup and find no reason it shouldn’t work but the sitemaps only show on /?sitemap=1 then the sub sitemaps will 404 on me. What am i doing wrong here?
I’m not sure – can you share your nginx config file? Maybe a different rule is being matched first?
I presume you restarted nginx after adding the sitemap rewrite rules?
Any update on my configs?
Replied – sorry about delay – looks like you have 2 missing }’s
Will this work with subdirectory sites? meaning, example.com/subdirectory
Hi – yes – it should do. Let me know if it doesn’t work for you and I’ll investigate.