Back to projects
Headless NextJS + WordPress Theme

Headless NextJS + WordPress Theme

Mary A. Hayne / August 6, 2024

Headless WordPress with ACF

This project is a fully customizable, headless WordPress theme built with React, Next.js, and GraphQL. As a long-time fan of headless CMS architecture, I wanted to build a theme that takes full advantage of WordPress’s powerful content management features without the traditional often-fraught PHP front-end layer.

The motivation behind this project was twofold:

  1. to deliver a lean, secure, and flexible content-entry platform that leverages modern JavaScript frameworks like React, as well as the stellar optimization caching options of the latest NextJS release, thereby reducing the security risks and performance issues traditionally associated with WordPress.

  2. Integrate ACF Flexible content templates, at the request of a client who wanted to retain them after the development resources he had invested in them.

Key Features & Contributions

  • Dynamic ACF Integration & Page Templates: Leveraged Advanced Custom Fields (ACF) to create flexible content templates. I integrated a variety of modular layouts, including sections, tabs, columns, and cards. This allows content editors to build and customize pages dynamically without touching the codebase. The ACF templates were designed to support the flexibility and adaptability required for building a variety of page structures.

  • Next.js 14 with App Router & Server Components: Embraced new Next.js 14 features such as the app router and server components, improving routing and optimizing server-rendered data fetching. I tackled challenges around nested data fetching in statically generated pages using Next.js’s dynamic = 'force-dynamic' setting to ensure smooth dynamic content rendering.

  • TailwindCSS: To enhance maintainability and flexibility, I adopted TailwindCSS, taking a deep divethe first time. This utility-first CSS framework enabled me to keep styles minimal and customizable, boilerplate if you will, ensuring that the theme remains lightweight and easy to modify for various projects.

  • Static Generation & Data Fetching with GraphQL: Built out a robust content delivery mechanism using GraphQL queries to fetch data from WordPress. The frontend was bootstrapped with create-next-app, and static pages were generated for improved performance and SEO. Responding to another client request, I also implemented archive pages as regular page post types, to enable introductory content above the loop.

  • Security & Local Development Setup with Docker: Configured local development using Docker, isolating WordPress, the database, and the Node.js server in separate containers. This setup ensured consistency across development environments and reduced the complexity of managing multiple local dependencies.

Challenges & Solutions

  • Handling Nested Data Fetching Issues: Encountered errors during the deployment/build process due to nested data fetching in statically generated pages. By leveraging Next.js’s dynamic = 'force-dynamic' option, I dynamically rendered pages that required nested data, eliminating server-side build errors. Presto! It seems Next thinks of everything.

  • Customizing TailwindCSS for Generated Content: Utilized the @tailwindcss/typography plugin to automatically style generated content like blog posts. This approach allowed me to maintain a consistent look and feel across dynamically generated pages without extensive custom CSS.

Tech Stack

  • WordPress: Headless CMS
  • Next.js 14+: React-based framework with App Router & Server Components
  • TypeScript: For strict typing and enhanced developer experience
  • GraphQL: For efficient and flexible data querying
  • TailwindCSS: Utility-first CSS framework
  • Docker: For consistent and isolated local development environments
  • @tailwindcss/typography: Adds typographic styles for generated content
  • image-size: Retrieves image sizes from files to improve loading strategies

Repository & Further Detail

You can explore the codebase and how I solved specific challenges in the GitHub repo.