Table of Contents

Moving to HTTPS on WordPress | CSS-Tricks

I just recently took CSS-Tricks “HTTPS everywhere”. That is, every URL on this site enforces the HTTPS (SSL) protocol. Non-secure HTTP requests get redirected to HTTPS. Here are some notes on that journey.

Why do it?

1. Get an SSL certificate

Not optional. This is how it works. I’ve done this a bunch of times in my life and it’s never overly comfortable. You just need to follow instructions closely. I’ve bought them in the past from discount providers and actually had it work fine, but it’s a more manual process.

CSS-Tricks is happily on Media Temple, and they provide SSL as a service, and I’m more than happy to pay for that to have it installed painlessly by professionals.

When the SSL certificate is installed properly, you should be able to visit your site (any URL) at either HTTP or HTTPS and have it come up fine. There may be errors on HTTPS though, and we’ll get to that.

2. Start with the Admin

In WordPress-land, you might as well get HTTPS going in the admin area first. It’s set up to handle it and there probably won’t be any errors. (I keep saying “errors”, I mostly mean “mixed content warnings” which I promise we’ll get to.)

To force HTTPS in the admin area, put this line in your wp-config.php file at the root of your WordPress install:

Make sure you test that HTTPS is working properly first! Go to https://yoursite.com/wp-admin/ to check. Otherwise you’ll be forcing URLs that don’t work and that’s bad. If you have trouble, remove that line right away.

All goes well, you’ll get a secure connection:

3. Try to get one page working on the front end

The next step is to get your front end on HTTPS. Forcing it all right away is probably going to be tough, so just start with one target page. For me, it was the signup page for The Lodge. That page can take credit cards, so really, it had to be HTTPS. This was the motivator for me early on to get this set up.

There is a plugin that can help with this: WordPress HTTPS (SSL). With that plugin, you get a checkbox on Posts/Pages to force it to be SSL.

4. Mop up Mixed Content Warnings

What you’re really trying to avoid is this:

That’s like: “Hey nice trying being HTTPS but you aren’t fully so NO GREEN LOCK FOR YOU!”

If you open the console, you’ll likely get messaging like this:

In this case, it was some images being used in a CodePen embed with an HTTP src.

But it could be anything. HTTP <script>s, HTTP CSS <link>s, HTTP <iframe>s. Anything that ends up making an HTTP request that isn’t HTTPS will trigger the error.

You just need to fix them. All.

5. Protocol Relative URLs! (or just relative URLs)

You know, those ones that start with //, like this:

Those are your friend. They will load that resource with whatever protocol the current page is. And links that are just relative to begin with will be fine, like:

I ended up finding them all over the place. I even had Custom Fields to fix:

6. Harder problem: images within legacy content

There are thousands and thousands of pages on this site, and lots and lots of images within those pages. Right in the content itself. There are a bunch on this very page you’re looking at. The problem is those images had fully qualified HTTP links on them.

I didn’t relish the idea of using some WordPress filter on content to kinda hotswap those URL’s out – I just wanted to fix the issue. I hired Jason Witt to help me with this. The first thing we did was run some SQL on the database to fix the URL’s. Essentially fixing the src of images to be protocol relative.

After backing up the database, and testing it locally, this worked great:

And another to catch single-quoted ones, just in case:

We even fixed the Custom Fields in much the same way:

7. Make sure new images are protocol relative

With the legacy content mopped up, we need to make sure new content stays OK. That means fixing the media uploader/inserter thingy so it inserts images with protocol relative URLs. Fortunately I already customize that to insert with <figure> tags, so it was just an adjustment of that. Jason ultimately helped me move a lot of my custom functions.php code into a plugin, so this is a little out of context, but I think you’ll get the picture and see the relevant filters and stuff:

8. Your CDN needs SSL too

If you have a CDN set up (I use MaxCDN through W3 Total Cache) that means the CDN is totally different server and URL and all that and it needs to be able to serve over HTTPS as well. Fortunately MaxCDN handles it.

9. Start forcing HTTPS everywhere

This is what I do in the .htaccess file at the root:

Once that is in place, you can turn off the plugin and remove the bit from the wp-config.php file, as those are redundant now.

You’ll also want to change the URL settings in General Settings to be https:// – so all the links in WordPress are constructed properly and redirects don’t need to come into play:

10. Keep mopping up

Inevitably after going HTTPS everywhere, you’ll find pages with mixed content warnings. You just need to keep investigating and fixing.

Good luck! (and let me know if I’ve fouled anything up)

Update! Speaking of mopping up… Content Security Policy (CSP) is a technology that might be incredibly helpful for you here. There is a directive for it, upgrade-insecure-requests, that can force the browser to use HTTPS for any HTTP resources it finds. A bit of a sledgehammer, but could be super useful.

This content was originally published here.