As we’re now running a plugin shop here on yoast.com, selling our Video SEO plugin, Tag optimizer and soon more, we also have a checkout page. I wanted that checkout page to run on https, for obvious reasons: people fill out their email and, depending on their payment method, their credit card details there. That deserves more security. It turned out not to be as simple as I wanted it to be, but I fixed it. This posts documents my mistakes and issues with my WordPress SSL setup in the hope of preventing you from making them.
You might think: couldn’t I just always load that image over SSL? Yes you could, but that’d be slower, which is why I chose not to do it.
Getting an SSL certificate on your server
This is by far the geekiest bit of this entire process, and not something I want to explain completely. In fact, I didn’t even do this myself. Just like all other VPS.net customers, you can get a free Comodo SSL certificate, all you have to do is file a support request for your VPS. It’s one of the reasons why I think VPS.net delivers the best WordPress hosting out there. BTW, they’re running a special at VPS.net, giving away Amazon gift cards for new VPSes, so if you’ve been thinking about switching, now’s a better time than any to switch to VPS.net.
I had already set up the free certificate a while back, as I wanted to run my WordPress admin over https, but I decided to go for a Extended Validation certificate today. This is a certificate that doesn’t just show an SSL icon in the browsers location bar but actually gives a green background for it and adds the company’s name, like so:

Of course this isn’t needed for every site, but I think it’s worth testing if you sell products. It provides just that bit of extra trust that can be so needed for online transactions.
Next: forcing SSL on that one page
There are plugins that can do this for you, most notably WordPress HTTPS, but as I wanted a bit more control and understanding of what was happening, I decided to code it manually. The code consists of two bits, this bit forces the checkout page to be on https all the time and at the same time redirects all pages that do not need to be SSL to an http URL:
function yst_ssl_template_redirect() {
if ( is_page( 123 ) && ! is_ssl() ) {
if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI']), 301 );
exit();
} else {
wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301 );
exit();
}
} else if ( !is_page( 123 ) && is_ssl() && !is_admin() ) {
if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
wp_redirect(preg_replace('|^https://|', 'http://', $_SERVER['REQUEST_URI']), 301 );
exit();
} else {
wp_redirect('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301 );
exit();
}
}
}
add_action( 'template_redirect', 'yst_ssl_template_redirect', 1 );
If you’re sure the URL will always be “clean”, as in, without parameters, this can be even simpler, but in this case I needed it to work with the URL parameters that Easy Digital Downloads uses. The number 123 is the ID of the checkout page, you should of course replace with your own page ID if you use this code.
Now we also want get_permalink to return the right URL, so let’s filter its output:
function yst_checkout_page_ssl( $permalink, $post, $leavename ) {
if ( 123 == $post->ID )
return preg_replace( '|^http://|', 'https://', $permalink );
return $permalink;
}
add_filter( 'pre_post_link', 'yst_checkout_page_ssl', 10, 3 );
This way if something links to the checkout page, the redirect isn’t even needed as the link is already an https link.
MaxCDN, W3 Total Cache & SSL: a golden trio
My favourite WordPress CDN provider MaxCDN, works great with W3 Total Cache. It does so even with SSL, if you know how to set it up. It’s very bloody simple too once you know it: for each CNAME, you enter not just the CNAME, but you follow it by a comma, and then enter the SSL version. For me, this looks like this (click for larger version):
This settings makes W3 Total Cache use the first hostname for http requests, and the second one for https. With a rather image heavy site like this one that’s a golden thing.
Broken SSL: fixing links in theme files
If you load a page over SSL, all the other files that are loaded on that page should also be loaded over SSL for it to not be “broken”. This means that every single image, javascript file, stylesheet etc. needs to be loaded over SSL. WordPress will fix a lot of this for you, but you’ll probably encounter some issues, as did I, causing a broken SSL icon in the location bar, as shown above here.
In my case, within my theme’s stylesheet, I was loading a google web font file. That shouldn’t be an issue, of course, but I was loading that font file over http, instead of using what’s called a protocol relative link. Every time you’re embedding images, javascript or CSS files, you should be using a protocol relative link. Instead of linking to:
http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600
I’m now linking to:
//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600
As you can see, I left out the http:, this will make the browser use the current protocol to fetch that file. This means that when a user is on plain http, it’ll use that, which is faster, but if the user is on https, it’ll use the safe https link.
Bonus: WordPress SSL setup for the admin panel
Now that you’ve set all this up, you might as well use that SSL certificate for your admin too. That part is actually pretty easy. Just drop this in the wp-config.php:
define('FORCE_SSL_ADMIN', true);
That’ll force the entire admin over SSL, which is what you want in most cases. If that is too slow for you though, you could also decide to just force the login page over SSL:
define('FORCE_SSL_LOGIN', true);
This will force the login and registration pages to be SSL. I think you should go for the first option though, and run your entire admin over SSL.
Conclusion: WordPress SSL setup is easy, do it!
With all these tips, there’s really no reason anymore why you couldn’t run any page where a user submits private data on SSL. So, just do it!


Dear Yoast!
Thanks for sharing your experience! It is always refreshing seeing things from your perspective.
I have used these Holy Trio; MaxCDN, W3 Total Cache & SSL on sites and can readily say that they really work. Almost all the site got 98% loading speed and barely drop below 95%.
We have just finishing building a WordPress MU site running on SSL and even though I haven’t configured W3 Total Cache and MaxCDN yet, I a;ready have W3 installed.
Can you throw some words of wisdom on how I can configured this without running into any problem on MU? Both for Page Speed/Optimization and Security?
Wishing the best of the day!
Thank You!
This was perfect timing for me since I just started setting up an SSL WordPress site yesterday. I didn’t know about the Protocol Relative Links. That’s brilliant!
Likewise! I was just about to start looking into how to do this for my own website. Perfect timing! Thanks a lot for the detailed write up.
Ps: Any news on the local SEO plugin?
Great timing, thank you so much for writing this Joost.
I recently set up a site with VPS and MaxCDN but was getting issues with the SSL. This post solves my woes :)
Cheers
Great! I had been looking for it the past few days and finally I believe I found the best resource online about it!
And the conclusion is correct, indeed it is easy if you read a well explained tutorial like yours…
Really had no idea on this one. I am new to the concept of SSL but your tutorial was a a great help for me to understand it and use it by myself to an extent. Thanks for sharing!
We run a pretty big network, and would like to run SSL on all the sites. They obviously all use the same IP address, how would we get a different SSL cert for each one?
I’d talk to someone at an SSL cert provider about that, I honestly can’t tell you.
Topher,
You mention a network, so if you’re using WordPress Multisite, then you may be interested in reading my comments (http://yoast.com/wordpress-ssl-setup/#comment-129855) as I just investigated this myself.
Very useful. I’d almost given up on forcing an SSL encryption on my site!
It is really brilliant post for SSL WordPress Webisite, I am very glad to say that it is really very informatics info in this blog post, I am very impressed.
How much slower is serving https really?
I’m sure it is slightly slower, I’m just curious about whether it is slow enough to make an actual difference to the user experience.
Years ago I experimented with SSL sites using PDAs. If I remember correctly one additional roundtrip is made to the server (handshake) for a request. So if the ping times are poor, using SSL could indeed experience a poorer user experience. For landlines probably the performance drop is minimalistic.
One useful suggestion: To prevent images from being served with “http://” on a page accessed with “https” and the browser complaining about unsecure content being accessed, do the following:
In Settings -> Media, specify the “Full URL path to files” to “/wp-content/uploads”.
This makes the files being accessed without the protocol.
Credit goes to tunemaster from here: http://wordpress.org/support/topic/absolute-relative-path-for-images
Any recommendation for buying cheap SSL certi ?
This is intriguing. I’d considered setting up SSL on my admin side for a while, but was put off by the fact that I needed different SSL certificates for every site on my Multisite network. However, after doing a little more research, I understand that you can force the admin areas of mapped domain network sites to run through the subdomain of the main site, rather than their mapped domain by using a plugin like SSL Subdomain for Multisite (http://wordpress.org/extend/plugins/ssl-subdomain-for-multisite/). This means that you only need to get a wildcard SSL certificate for the main network domain, which runs at about $100/yr. Not bad, and especially worthwhile if you have high traffic sites, or at least 10 sites on the network.
I appreciate your tutorial. It seems more and more websites are going SSL and it’s a smart move. I strongly believe hosting is extremely important and please don’t call me for this however I use managed WordPress web synthesis rocks I hope you don’t mind me saying this man but there are very good solutions for people but don’t want to spend hundred dollars a month for SSL Zippy Kid offers managed WordPress hosting a dedicated IP and SSL for $10 more a month meaning a total of $35 that gets you 100,000 page views and a NetDNA CDN (Netdna is the same company as Max CDN however is considered their enterprise level offer don’t get me wrong MaxCDN is awesome but netDNA is faster) the reason I’m saying this and guys I’m hosting on WP Engine have accounts with pagely in addition to web synthesis they’re all great so is VPS.net it’s just were talking about in my opinion the best way to host WordPress is managed this is my opinion I also believe if you are going to only spend $35 a month tell me can you really beat that and I am not promoting anything you know as well as I do and they don’t give money for recommendations so I’m saying this to help people that might not have 100 bucks a month plus the extra 10 bucks per dedicated IP and certificates I must say I think that’s a a great deal for people that are looking to have a netDNA/MaxCDN content delivery network as you suggest SSL CERT installed for them and quality hosting. if you disagree with me please tell me why and if you could shed some light on the quote below this is from global sign they are a good company to the best my knowledge for SSL however they apparently are more concerned about speed considering the information below I don’t know if it’s true I just asking you?
“Web developers are concerned about the impact that SSL security will have on their website’s loading times. Through a partnership with CloudFlare, GlobalSign provides enhanced reliability when delivering certificate statuses, and enables SSL secure sites to load many times faster.”
All the best my friend,
Tom