Pål N. Bakken
Web Developer & Photographer

Building my personal website using Next.js, WordPress, and GraphQL

Pål
37 views
images of the logos of Next.js and Wordpress

I'm seeking new opportunities

Based in Norway: offering services in web development and photography.

I'm open for full time employment or freelance projects.

If you'd like to discuss potential opportunities or collaboration, please don't hesitate to get in touch.

I’ve been tinkering away on a project that’s felt fitting for me, a website that doubles as a developer blog and (eventually) a photography gallery. After mulling over various options, I decided to build it using Next.js for the frontend and WordPress as a headless CMS. It’s been quite the ride, and although content wise things are pretty bare bones, I’m pleased with how the underlying system functions and I’m pretty excited for bringing all the pieces together in the near future.

Why Next.js and WordPress?

So, why this combo? Well, Next.js is an absolute powerhouse when it comes to building fast, responsive websites. Its support for server-side rendering and static site generation means I can deliver content quickly and efficiently. I’ve been using it for personal work since the days of /pages and now with the /app router it’s more powerful to use than ever.

As for WordPress, I’ve always appreciated its robust content management capabilities. By using it as a headless CMS, I get the best of both worlds: a familiar interface for managing content and the freedom to design the front-end exactly how I want it.

Setting up WordPress as a headless CMS

WordPress is traditionally known as an all-in-one website solution. It’s one of the most widely used platforms on the internet, and it’s easy to see why. It’s dead simple to set up, the publishing and management panel is intuitive and easy to use, and it’s absolutely free.

However, using WordPress as a front-end client wasn’t quite the fit for me. As a web developer, building my personal website using a site builder felt like taking the easy way out. I wanted the flexibility and control to craft every aspect of the user experience.

Moreover, WordPress can sometimes be slow and clunky on the front-end. This isn’t necessarily a knock against WordPress itself – it’s often due to the heavy themes and numerous plugins that are commonly used to add functionality. These can introduce a lot of additional code and assets that the browser has to load, which can significantly impact performance. The default way WordPress renders content involves multiple database queries and PHP processing on each page load, which can add overhead and slow down response times.

That’s where the idea of using WordPress as a headless CMS came in. By decoupling the front-end from the back-end, I could leverage WordPress’s robust content management capabilities without being tied to its traditional theming system. This setup allows me to create a custom front-end with Next.js while still managing content through WordPress’s familiar interface.

Now, I didn’t have to install GraphQL to use WordPress as a headless CMS – WordPress comes with a REST API right out of the box. The REST API is powerful and easy to use for fetching content. However, I decided to experiment with WPGraphQL to explore different technologies and see how GraphQL could enhance my data fetching experience. It’s been a fun learning opportunity and adds an extra layer of flexibility to the project.

Fetching content at build time

One of the coolest features of Next.js is Incremental Static Regeneration (ISR). I set up my Next.js app to fetch content from WordPress at build time. This means the site generates static pages for lightning-fast performance but also updates them every hour to reflect any new content I add. It’s like having the best of both worlds – speed and freshness.

Building the front-end

As a front-end developer by training, crafting a good-looking and user-friendly interface was a priority for me. Design isn’t just about aesthetics – it’s about how users interact with and experience the site. With that in mind, I set out to build a front-end that is both visually appealing and intuitive to navigate.

Embracing minimalism

I opted for a minimalist design philosophy. The idea is “less is more,” especially while the site is still a work in progress. A clean, uncluttered interface helps keep the focus on the content itself, whether that’s blog posts or, eventually, photography. It also enhances usability by reducing distractions and making navigation straightforward.

Dynamic routing

One of the standout features I utilized is Next.js’s dynamic routing. This allowed me to create individual pages for each blog post – and in the future, for photo galleries – without having to manually set up routes for each one. By defining dynamic segments in the URL, the app automatically generates pages based on the content fetched from WordPress. This makes navigation smooth and intuitive, both for me as a developer and for users exploring the site.

Styling

To keep the styling organized and maintainable, I used CSS modules. This approach scopes CSS to specific components, preventing styles from leaking and causing unexpected issues elsewhere. The styling is simple, focusing on typography and whitespace to create a pleasant reading experience.

Given the variety of devices people use today, making the site responsive was essential. I ensured that the layout adapts gracefully to different screen sizes, from large desktop monitors to small smartphone screens. This way, everyone gets a consistent experience regardless of how they’re accessing the site.

Image optimization

For the photography gallery (which is still under construction – sorry about that!), I’m taking advantage of Next.js’s built-in Image component. This component automatically optimizes images for different devices and screen resolutions, which is a big win for performance and user experience. High-quality images can be a burden on load times, so this feature will help keep things snappy.

Focus on user experience

Overall, the goal is to create an interface that feels natural and effortless to use. I paid attention to details like:

  • Navigation: Simple menus and clear calls-to-action make it easy to find content.
  • Accessibility: Proper use of semantic HTML and ARIA roles ensures the site is usable for everyone, including those who rely on screen readers.
  • Performance: By keeping the design minimal and optimizing assets, the site loads quickly, which is crucial for retaining visitors.

Hosting the website

The simplest solution for deploying a Next.js app is with Vercel, the creators of Next.js. In this case however, I also had a WordPress install I needed to host, and I liked the idea of managing everything in one place. The answer then, was to roll up my sleeves and host everything on my own Virtual Private Server (VPS). There’s something satisfying about having full control over the server environment. Plus, it gives me the flexibility to configure things exactly how I want.

Setting up the VPS involved configuring Nginx as a reverse proxy for the Next.js app and setting up SSL certificates for HTTPS. The WordPress backend is hosted on the same VPS, and since it’s a headless setup, the front-end and back-end are decoupled but still play nicely together.

What’s next?

I’m planning to delve deeper into specific aspects of this project in upcoming posts:

  • Setting Up WPGraphQL and ACF: A step-by-step guide on configuring WordPress for an optimal headless setup.
  • Optimizing Next.js Performance: Tips and tricks I learned along the way.
  • Hosting on a VPS: A deep dive into setting up your own server for hosting a Next.js and WordPress application.
  • Finishing the photo gallery: I promise, it’s coming!

If there’s anything in particular you’d like me to cover, feel free to let me know!

Wrapping up

Building this site has been pretty rewarding in the way of giving me a creative outlet to learn and experiment with.

If you’re considering building your own site with a similar stack, I highly recommend giving Next.js and WordPress a shot. The flexibility and performance are hard to beat – plus, hosting it on your own VPS gives you total control.

- Pål