How to configure nginx for Yoast SEO sitemaps

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.

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.

8 Comments
Show all Most Helpful Highest Rating Lowest Rating Add your review
  1. 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;

  2. 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?

  3. Will this work with subdirectory sites? meaning, example.com/subdirectory

Leave a reply

Super Speedy Plugins
Logo