March 2, 2017

NGINX Trailing Slashes for WordPress

Disclaimer: I imported this post from WordPress to Jekyll on 9/2/23. Forgive the misformatting until I get a chance to clean it up.

Just a quick tip that was not easily discoverable on the inter-webs.

Trailing Slash Primer

An URL without a trailing slash looks like: /nginx-trailing-slashes-wordpress

An URL with a trailing slash looks like: /nginx-trailing-slashes-wordpress/

The decision to include the slash or not for basic web pages seems to be somewhat subjective and up for debate. Certainly, sites should pick one and be consistent for SEO purposes; Google does not like duplicate content. Amongst WordPress circles (including sites like wordpress.com, yoast.com, and tommcfarlin.com), the consensus seems to be to include the trailing slash for posts and pages. Files and API calls (more on the latter below) should not contain a trailing slash.

NGINX Rewrite Rule

Conventional Rewrite

There are lots of examples for a NGINX rewrite rule to force WordPress pages always to have the trailing slash. Variations of the following seem to be the most popular, and I have been using this rule for some time with success.

rewrite ^([^.]*[^/])$ $1/ permanent;

via Bob Monteverde

Excluding WordPress REST API Calls

However, with the inclusion of the new WordPress REST API in WordPress Core, the rewrite rule above breaks things. I discovered this when trying to enable the Markdown feature of Jetpack. I watched API calls in the Chrome console get redirected to include a trailing slash and then fail. I was unable to discover a solution with Google-fu, but with some help from the local Slack community, I pieced together the ‘if()’ below. It seems to do the trick.

##
# Always Include Trailing Slash (less REST API calls and files)
##

if ($request_uri !~ "^/wp-json") {
rewrite ^([^.]*[^/])$ $1/ permanent;
}

Shout out to Ed in the MemTech Slack for pointing me in the right direction.