I have been messing around with Amazon’s CloudFront on this site for a couple months now. I had some basic Subs Filters setup that makes using CloudFront as a CDN really easy (and probably most CDN services). The Subs Filter module for Nginx works by filtering the HTML output before the client’s web browser gets it. So, basically these three lines act as a search/replace on that HTML output. So any time the uploads directory or any css/js file is referred to in the HTML of a page on my site, the filters change them to refer to my CloudFront distribution instead. And CloudFront handles it from there.
1 2 3 |
subs_filter //domain.tld/wp-content/uploads //d9ye22nzps5tq.cloudfront.net/wp-content/uploads; subs_filter //domain.tld/(.*)\.css //d9ye22nzps5tq.cloudfront.net/$1.css gir; subs_filter //domain.tld/(.*)\.js //d9ye22nzps5tq.cloudfront.net/$1.js gir; |
But the other day, I was setting up Let’s Encrypt on my site, which caused me to look at CloudFront again because I was getting some protocol mismatch errors. There were a few assets that weren’t being caught by the above subs filters. Noticing this led me down a rabbit trail of trying to figure out the simplest way to deliver everything possible in my WordPress install to CloudFront. I came up with these four subs filters and they’ve been working great!
1 2 3 4 |
subs_filter //lewayotte.com/wp-content/ //d9ye22nzps5tq.cloudfront.net/wp-content/; subs_filter //lewayotte.com/wp-includes/ //d9ye22nzps5tq.cloudfront.net/wp-includes/; subs_filter \/\/lewayotte.com\/wp-content\/ \/\/d9ye22nzps5tq.cloudfront.net\/wp-content\/; subs_filter \/\/lewayotte.com\/wp-includes\/ \/\/d9ye22nzps5tq.cloudfront.net\/wp-includes\/; |
Because of the way that WordPress works, there shouldn’t be any references to anything in the wp-content or wp-includes directories, except for deliverable assets, so these rules should be safe. I tried to do it in fewer lines, without referencing wp-content or wp-includes but it was too greedy and ended up causing some problems. I also had to reference the “escaped” versions of the URLs because WordPress refers to some escaped JavaScript URLs.
Side Note: You should bypass the Subs Filters in your /wp-admin. If you don’t, you could run into a problem where you edit a page with assets on your site that are caught by the Subs Filter and when you save will permanently change to your CDN. If you ever change CDN’s this could result in a bunch of broken asset references on your site. So, I do this with this code in my site’s Nginx configuration:
1 2 3 4 5 |
set $bypass_cdn "0"; if ( $request_uri ~* "/wp-admin" ) { set $bypass_cdn "1"; } subs_filter_bypass $bypass_cdn; |