By Jepser Bernardino, on Feb 27, 2019

From WordPress to static site—the Contentful way

Six years ago, I started my blog using WordPress. As front-end development changed over the years, my way of working with projects changed too. By then, WordPress was widely used across the internet.

As I updated my website, I tried using tools to modernize it. I had started by adding gulp.js and Sass, then rebuilt it using webpack. It was a difficult task, and I eventually came to the conclusion that most of my issues could be solved by changing my tech stack.

The challenges of my old WordPress site

Code is tied to content

Since Wordpress templates tied content to appearance, changing the layout and design meant also having to adapt content to a new look. With this in mind, I decided to create my views with an alternative approach. I wanted to avoid WordPress template tags, so I created models that handled WordPress related functions and provided agnostic data structures.

The view-model issue could be solved by using WordPress Rest API, but that’s an extra step in the process for a feature that should just work from the start.

Replication of environments

I wanted to work on changes and preview them in a local environment. To do that using the same content and configuration as the live site, I had to export a new database dump and import it to my local environment every time.

Later, I found a great tool called WP Migrate DB Pro. However, aside from having to pay for a stand-alone license, I also had to avoid overwriting the production site with local changes and vice-versa.

Intermingled content and code

With WordPress, it's difficult to change the appearance of the website (for example, switching themes) without affecting the way content is presented. Changes in the data model or plug-in updates would require triggering a new deploy of the whole site, making it expensive and time consuming.

Even for a simple site like mine, it would take days to build a new theme, optimize content for it and maintain the plug-in ecosystem surrounding it all. Given that my website has content that is low in complexity and non-daily content updates, it could be handled using static files.

Security maintenance

WordPress does a good job at fixing bugs and patching security issues. However, it does have consistent vulnerabilities and sites still get hacked. I’ve found that keeping up with installation and plug-in updates keeps my site secure, but it is a huge chore.

The requirements for the new blog

There were several main needs I had for the next solution that would power my website:

  • Allows me to work with content on separate local and production environments
  • Runs light on resources and is intuitive to work with
  • Works with the latest frameworks and tools in my content management workflow

Separation of code and content

I wanted to have a defined line between changes to code and content. Having my front end separated from the content would allow me to have a single source of truth and an easy-to-replicate environment.

Frontend in JS

I work primarily with JavaScript, specifically with React. Not having to switch between programming languages when working on my site or in my day-to-day work is a huge time saver. Having a single language work with both server- and client-side is also a plus. Now I don’t have to separate using PHP for the backend and JavaScript to deal with the front end.

Static, please

I have previously worked on a project where we used static site generators. I was pleased with the results, and our users also liked the speed increase thanks to being served statically-generated files. Since my site was relatively simple, it made sense for me to have it served as static files.

Automated deployments

I spent a lot of time trying to implement continuous deployment on my WordPress setup, as it was more complicated than I expected. Every tool for automated deployment in WordPress had a high price to pay.

For the new site, both continuous integration and continuous delivery are a necessity. Continuous integration allows for automatic tests that ensure any new code doesn’t break the site. Meanwhile, continuous delivery facilitates automatic creation of new versions of the site and ensures pull requests are effortlessly merged with the master.

The solution

TL;DR

  • Contentful for content management
  • Next.js as the framework to manage my React application
  • TravisCI for their continuous integration and deployment service
  • Now as a hosting provider

Choosing Contentful

I ultimately chose Contentful for the following features:

  • Preview API. I can configure my app to fetch drafts simply by changing the URL and credentials, making it easier to test new content without changing the database from local to production.
  • Webhooks are missing in WordPress. With webhooks, it's easy to notify third party services like Travis to create a new build each time the content changes in production.
  • Integrated CDN. I don’t have to pay for a CDN anymore.
  • SaaS. I don't have to worry about my content infrastructure, updating plug-ins or security patches in my site.
  • Custom models (called content types). Contentful has a UI for creating custom field models with a lot of options and which is flexible enough for the majority of cases.
  • Developer-friendly. Contentful has several SDKs for different tastes. In my case, I found that the JS SDK has simple yet powerful interface.

DX with Contentful

I want to emphasize that moving from a self-hosted WordPress to Contentful helped increase my productivity. I can now focus on results instead of the process.

The Preview API already makes it easy to work with local environments, but with Contentful’s environments for spaces feature, testing new content models is effortless.

Updating the site after a change in the project (code) was easy, but the tricky part was getting a new build up after changing the content. For that, I configured a Lambda function which sends a custom request to TravisCI. After setting that up, I just had to add the Lambda URL to a webhook, which triggered a new build every time the content was updated.

The SDK removed the constraints of having to learn API structure and the complexity of authenticating over preview and live APIs.

Next.js, an isomorphic React framework

Next.js is a React framework that helps developers create robust applications in a simple but opinionated way. It can export the project to static files, which helped me create my static site from the content delivery API. It also runs the app as a Node.js application. Whenever you make changes, results can be previewed immediately without having to wait for the build to finish.

Travis CI, continuous deployment service

During the days when my site was on WordPress, I used Deploybot to create the site build and deploy it to a remote server using SFTP. When I changed over to a JavaScript stack, I felt more comfortable using Travis since I also used it in my day-to-day work. It’s as simple as adding the configuration file and letting Travis do its thing. Plus, I qualified for the free tier since they don't charge for public repositories.

Now, my hosting service

Now is a hosting service by Zeit, the same people behind Next.js. Zeit has a team of outstanding developers that create products for other developers. I consider their developer experience one of the best on the market.

Now allows you deploy practically any type of application, whether it’s in Docker, Node or just a static site (as it was in my case). It also works perfectly with Next.js.

Now also has a CLI, which is perfect for performing deploys and creating new instances of your application from its console. It is also free for small projects and doesn’t cost much for medium-sized projects.

With a couple of lines in the package.json file, you can easily deploy your site to Now.

It's difficult to let a good friend go, but WordPress will be okay without me. Delegating your content to a service really enables you focus on what matters. As a front-end engineer, my biggest priority is being able to code and ship efficiently.

With my new static site implementation, I’m able to do just that. No more keeping up with an endless stream of updates or having to debug the way content presentation whenever I make a change in the backend.

If you are interested in a more technical breakdown of my site, you can check out the project repo in Github.

Jepser Bernardino
Barcelona, Spain

Software engineer from Guatemala, currently working @Typeform.

Community Contributor
Become a contributor