WordPress is a great website platform that I use and develop on every day, but, it has its weaknesses. It requires a database that is accessed dozens (or hundreds?) of times every time a page is loaded, which can slow down page load times. It’s kind of a wasteful use of server resources if your content doesn’t change very much. And it can have security issues.
What if you could use WordPress, but have all of the advantages of a static HTML site? The solution I’m talking about is to set up a staging WordPress install and render the pages out as static HTML files to the live production site using a plugin.
I tried this with a few of my blogs and I’ll walk you through the process!
The Big Caveat
Before I go any further, I want to be clear about the big limitation of rendering your WordPress site to HTML. Namely, you will lose all server-side functionality! Here’s a partial list of stuff that won’t work on your static WordPress files:
- server-based comment forms
- server-based contact forms
- almost any plugin that uses a submit form
- “most popular posts” widget
- site search
- events signup plugins
- e-commerce plugins
- membership plugins
- RSS feed (unless you find a workaround or write some code.. anyone who knows an easy solution please comment!)
- and many other plugins that require dynamic server functionality!
Obviously, this eliminates a lot of types of websites from being able to use this solution!
But there are workarounds. Some of server-based features not available to static sites can be achieved with client-side solutions. For example, you can implement commenting using Disqus (or other client-side commenting services) instead of using the native WordPress commenting system.
Types of Sites Which Are Ideal for this Solution
Here are some types of websites which might be ideal for static site generation:
- Purely informational sites
- Online corporate brochures
- Landing pages or “Coming Soon” pages
- Blogs (using client-side commenting)
- Sites that need to load really fast
- Sites that need exceptional security, or that will be especially targeted by hackers (i.e., political sites, celebrity sites, etc.)
Basically, if your site is purely informational or purely informational with client-side comments, the rendered static site should work fine.
There are some really huge benefits of serving static HTML files to your visitors instead of a database-driven site.
1. Insanely Faster Load Time
The load time speedup you can get is really insane. In my experiments, my WordPress site’s average load time was 4-6 seconds; not bad. When I rendered it to HTML, the load time went down to under a second! And this was on cheap shared hosting!
Your WordPress theme might make dozens or even over a hundred database calls to render your site. All of that activity takes time and results in slower load time. Caching plugins help, but do not completely eliminate all database calls, or the fact that PHP has to execute on the server. Static HTML files have none of that.
2. Improved Site Reliability
If you’ve worked with WordPress sites for a while, you’ve undoubtedly seen the dreaded “Unable to connect to database” error that occurs when your database server goes down. When that happens, your WordPress site goes down too.
Static HTML sites don’t have this source of unreliability. I’ve noticed that more than half of the time when my WordPress-based sites are down, my pure HTML sites still work! Reliability of static sites is more than twice that of database-driven sites, in my experience.
Now, with the static WordPress solution, your source site will still use a database, so you won’t be able to edit if your database server goes down. But, at least your live site will still be up!
3. Lower Server Load
Since your static site is so easy to render compared to a database-driven site, it will have a much lower server load. This means you can use cheaper hosting with less memory and CPU power. I’m using low-cost GoDaddy shared hosting and getting under 1-second load times with my static WordPress-rendered site.
4. Way Better Security
SQL injection is one of the biggest security vulnerabilities out there. Static sites don’t have this vulnerability because there is no exposed database to hack. There is also no PHP code running. There are no exposed plugins to hack!
Of course, your staging WordPress site still has all of the disadvantages of needing a database. But, at least you won’t be exposing those limitations to the whole world, and you can take extra measures to hide your source WordPress site, such as hiding it behind an .htaccess password. For ultimate security, you can have your source WordPress install on your local computer (but this eliminates the convenience of the one-click deployment, just FYI).
5. Free Staging Server
Rendering out your WordPress site and only displaying the rendered static files to the public gives you this bonus feature: a free staging server! In other words, you can play with your WordPress site without affecting the public-facing site. If you hose your WordPress site, your static site will still be faithfully working. Publish your site only when it’s completely ready for prime time.
6. Easy Deployment to Different URLs
Moving WordPress from one URL to another is a pain if you have to do it often. Maybe your website is for an annual event that has the current year in the URL. The Simply Static plugin allows you to deploy your site to different URLs with just a few settings and clicks!
How to Do It
Here are some plugins that can turn your WordPress site into a static site:
- Simply Static
- Export WP Page to Static HTML/CSS – I have not tried this one but it has good reviews!
Below I’ll show how to turn your existing WordPress site into a static site using the Simply Static WordPress plugin. I’ve also tried WP2Static. There are things I like about that plugin, but in the end, I chose Simply Static because it generated files much quicker.
1. Copy Your Live WordPress Site
First, you’ll have to make a copy of your production WordPress site to its new staging location. This can be either offline on your local computer, or in the cloud on the same web server as your live site. There are pros and cons to each.
If you have your WordPress install on your local computer, you can work on it with no Internet connection, which is kind of cool. And, your WordPress install will be safe from hackers. But, it will take a bit more effort to push the rendered files to the server. You might need to use Filezilla to drag the files up manually (I’m sure there is a better solution out there though).
If you have your WordPress install on the same server as your live site, pushing the rendered files is a one-click affair using the “Simply Static” plugin that I use. This is really great, and makes the process almost effortless.
I like to use the Duplicator plugin to copy sites. But, there are many other plugins available for copying WordPress sites.
2. Install Simply Static
When you’ve set up your WordPress staging site, install the Simply Static plugin. This wonderful plugin renders your entire WordPress site to HTML files. At the same time, it replaces the base URLs in the WordPress database with the URL of your destination. Really cool!!
From here on out, I’m going to assume that you’ve put your staging WordPress site in a subdirectory of your live site. For example, you could put your WordPress site in “/wordpress”. We’ll hide it later.
Another note: I did all of these steps successfully on GoDaddy hosting, as well as localhost. But, I wasn’t able to get either Simply Static or WP2Static to work on SiteGround hosting. If I find a fix, I’ll add it to this article.
3. Set up Simply Static and Generate a Test Site
- Go to Simply Static -> Settings in your WordPress admin.
- In the Destination URLs section, select “Use absolute URLs”. Note that you should select absolute URL paths or else the meta tags in the head will be relative, which is not good.
- Enter the URL of a subdirectory of your main site for now, i.e., “http://yoursite.com/test”. Remember to delete this directory after after your testing is done.
- For Delivery Method, select “Local Directory”.
- In the Local Directory field, complete the path to your local directory.
Go to Simply Static -> Generate and press the big blue button. Generation launch will take a few minutes. Thoroughly test the newly generated site at “yoursite.com/test”.
4. Add Missing Pages
In my case, I had some pages that were in the WordPress site but not in the static version. That was because there were no absolute links to those pages in my site, so the Simply Static plugin couldn’t find them. Simply Static won’t find pages linked by relative URLs.
Fortunately, it’s easy to add these pages manually by entering the URLs into the Simply Static plugin at Simply Static -> Settings -> Include/Exclude. Add the URLs of the missing pages to the “Additional URLs” tab.
Or, you can go back into your WordPress site and change any relative links to absolute links. Be sure to use the URL of your WordPress staging site, not the production URL.
Regenerate the site to see if the pages appeared, and repeat if necessary.
5. Add Your Sitemap
I use the Yoast SEO plugin to generate site maps for my WordPress site. Site maps are used by search engines to help crawl your site. While not absolutely necessary, a site map is recommended for good SEO.
You’ll have to add the URLs of your sitemap pages to the “Additional URLs” section of the Simply Static settings page. See the Yoast plugin for more information on where your site map is located. Here are some examples:
After the site is launched, confirm they appear in the production site and enter the URLs of your site map files into Google Webmaster Tools if you haven’t done so previously. They should be the same as they were before you went static.
6. Set Up Your 404 Page
Regular WordPress will provide a 404 “not found” page when a user tries to access a page or post that doesn’t exist. When you render your site to HTML, you lose that feature. But, it’s not hard to set up. You’ll need FTP access to our server. Here are the steps to do it.
- Create a 404 “not found” page in WordPress. Take note of the slug.
- Next, you’ll have to tell the Simply Static plugin to render this page, because there are no links to it. Log into the WordPress admin and go to Simply Static -> Settings -> Include/Exclude -> Additional URLs and add the staging URL of your 404 page.
- Re-generate your static files and push them to production.
- FTP to your server and go to your production site’s root.
- Add this line to your .htaccess file:
ErrorDocument 404 /404-page-slug/
where the text between the slashes is the slug of your 404 page.
Test by typing in a nonexistent URL on your production site. Your 404 page should come up!
7. Set Up Your robots.txt File
If you’ve set up your 404 page and modified your .htaccess file per the previous step, you technically don’t need to do this, but if you haven’t, you MUST do this step or else Google won’t index your site! (Google’s crawlers will try to find robots.txt and will get an Internal Server Error). Just create a blank robots.txt file your root and you’ll be good.
8. Hide Your WordPress Site
If your staging WordPress site is in a subdirectory on your live server, it will still be visible to the world, so you’ll need to hide it.
The first thing I tried was installing an “Under Construction” plugin to hide my WordPress site. Then, I rendered out my site and it consisted of one page – the Under Construction page! Haha.
So, the next thing I did was to protect my staging install with HTTP Basic Authentication. It turns out that the makers of the Simply Static were thinking the same thing. They built in support for Basic Authentication right into the plugin!
Setting up Basic Authentication will require you to FTP to your server and set up an .htpasswd file in your root directory. Google for instructions on how to do that. Here’s a site which generates your password hash.
Once set up, go to Simply Static -> Settings -> Advanced, and enter your username and password at the HTTP Basic Authentication section.
Note that if you’re concerned about security you should have SSL set up for your staging site as well.
9. Delete Test Directory
Finally, remove your test directory and any other temporary directories or files that you created.
10. Launch Your Site
When all of your pages are rendering properly to static HTML, you can move your old production WordPress files from the root to a temporary subdirectory, then try pushing your staging WordPress files to your site’s root directory.
First change the destination URL to your site’s root in the Simply Static settings.
Then go to Simply Static -> Generate and press the big blue button to launch your site to production!
Voila! You should now have a static site derived from WordPress! Load time should be lighting fast!
Any time you need to update your site, just update your WordPress site like you normally would. When you’re ready to publish, just click the “Generate Static Files” button!
Another Option: Static WordPress Hosting
Since I originally wrote this article, another option has come up: Strattic WordPress hosting. Basically, you set up your WordPress site on their servers, and they provide the machinery to convert it to a static site, and that site is what end-users see.
At $45/month for one site, it’s expensive compared to traditional hosting. You could get some really kickass servers on Cloudways for less than that, but of course, you’d have to do all of the setup whereas Strattic does it for you.
Miriam Schwab from Strattic commented below to give more details on what Strattic offers:
Any questions? How did it go for you? Let me know your thoughts below. – Brian
Please Leave a Question or Comment
Hi Brian. Some time ago I wrote an article about speeding up WP2Static. It’s very powerful but it requires some extra configuration. https://wpowls.co/articles/speeding-up-wp2static/
Hi Brian, great post! And thanks for mentioning Strattic! A lot of the issues you mentioned in your post that people would face when running their WP sites as static are not an issue on Strattic:
Strattic supports a number of server-based contact forms out of the box – Gravity Forms, CF7 and Elementor Forms. We support site search by converting it to Algolia automatically on publish, and we take care of all the RSS feeds. We also automatically create the 404 page on the static version of the site, XML sitemaps, robots.txt and 301 redirects.
Also on Strattic we take care of the entire environment from end-to-end: the isolated WP site which shuts down when not in use; the static hosting; CDN and SSL.
So yeah, Strattic may be more expensive than a service like Cloudways (maybe for some sites, but definitely not for all) but our users get everything out of the box, and all they have to do is manage their content, and then click one button to deploy.
Anyway, just wanted to clarify :)
Thanks for the information Miriam!!
Something not covered in your post that is important in my opinion…can you still use your existing theme if you go the static route?
Yes, you should be able to use any theme with this technique, though I have only tested with the Divi theme.
Some sites that are built with page builders may not publish well to static due to the inability of the crawler to identify CSS files and the like that are sometimes generated on the fly. This was a challenge we had at Strattic too but we figured it out and rolled out support for pretty much all WordPress page builders.
Hi, big thanks for your post about Simply Static, it is a terrific solution in order to make a WordPress Site load reaaaaaally really fast (which is basic for SEO purposes).
I have had lots of issues when selecting “Use absolute URLs”… I don´t know why but since my site is using the Divi Theme it breaks the layout really bad therefore I use the other option “Use relative URLs”…
however you recommend the following:
In the Destination URLs section, select “Use absolute URLs”. Note that you should select absolute URL paths or else the meta tags in the head will be relative, which is not good.
Is there a turnaround for that last you wrote?
I don´t want my meta tags to be relative… Do that really affects SEO in a bad way?
Thanks a lot Brian,
– Rodrigo F.
Hmmm, I did use Simply Static on a Divi theme, and it worked fine with absolute URLs, but that was over a year ago. It’s possible a recent update broke it.
Similarly, you should confirm the meta tags are still relative… it’s possible they fixed it. If not, contact the plugin developer.
I’m not sure if Google can deal with relative tags or not, but I’ve never see a site with relative tags. It’s not something I wanted to experiment with on my own sites!
It’s way easier to just generate the site maps with Yoast, include them, and then let Simply Static use the absolute links in the site maps to find all your posts and pages. I would switch the order in your directions and make a note of that to save time
Would the Simply Static WP plugin output a static page or site of a headless WP CMS setup?
It outputs a static HTML page.
Pardon, will the plug in work in a headless WP setup?
Sorry, i didn’t understand the question correctly originally. I don’t think it would work in a headless WP setup.
What’s a good solution for the /feed/ (RSS) file? Do you redirect ./feed/index.html in .htaccess?
That is actually a great question… The RSS feed generated by WordPress would have absolute links pointing to pages in the source site, not the static site. Those could be redirected using .htaccess, but that’s not really ideal.
There is probably a way to write some code to fix it, but it would take some research. Anyone have an answer?
Only problem I had was with the index.xml file not being found, which was solved by adding it to DirectoryIndex. One other thing, the shortlink seems to be present in the “id” field, but that doesn’t seem to matter.
DirectoryIndex index.html index.php index.xml
Is it possible to have both static html pages and some of the WordPress pages on different URL?
I wish to use static pages for most of the website and the WordPress contact forms and eCommerce shopping cart processing pages for subscriptions.
You cannot have both static and dynamic pages originating from the same WordPress install using this plugin.
However, you could have static pages on one URL, and dynamic on another URL, subdirectory, or subdomain by installing a separate instance of WordPress there.
Hi, do you recommend using this for Woocommerce? If I don’t want it to touch woocommerce pages, is there a way to make only the front page and certain individual pages static, and the rest dynamic?
No, this won’t work for WooCommerce. This plugin doesn’t have a way to only make certain pages static.
The only way to do this would be to have a separate subdirectory or subdomain for the WooCommerce store part which was dynamic, while the rest of the site was static.
Great walkthrough Brian. Do you have any recommendations for email solutions that will work after generating html from wordpress?
Thank you for your comments!
If you don’t want to use an anchor tag with “mailto:”, I would create a PHP script to do the emailing. Here’s an example: http://www.freecontactform.com/email_form.php
If you don’t want to write code, there are probably some services if you google around.