Graphic depicting the differences in rendering patterns between Astro and WordPress.
Headless WordPress

Andrew Kepson

October 16, 2024

Astro vs. WordPress: Rendering Patterns of the Modern Web

The author of this blog post, Andrew Kepson, standing in front of the Rocky Mountains in Colorado.

Andrew Kepson

October 16, 2024

Those working with WordPress are familiar with its dynamic rendering process: pages are built with PHP, pulling content from the database, and serving it on-demand to users. Today, imagine a different way of building websites: one that generates all of your pages as static HTML at build time, before users request them.

In this article, we will look at some of the differences between building websites with WordPress and Astro. The goal is not an exhaustive exploration of all aspects of development with these complex tools. Rather, the goal is examine how the workflow of building sites is conceptually different, and how to apply knowledge from WordPress into a new context: Astro.

A graphic depicting server-side versions static rendering in web development.

How Rendering Works in WordPress

Anyone who has built a site with WordPress knows that it is all about templates and dynamic content. WordPress uses PHP – a server-side scripting language – to generate pages on the fly. Each time a user requests a page, the server pulls data from the underlying SQL database, processes it, and renders the page on the server – sending the rendered HTML back to the user’s browser, along with whatever other resources are necessary.

This approach allows for a great amount of flexibility – posts can be updated or added, plugins can be installed, and styling or JavaScript updated, and the site reflects those changes immediately. It also means that every time the pages is loaded, WordPress has to run that code again, querying the database and generating the template. This is why many WordPress sites utilize caching plugins, which will be discussed further in later paragraphs.

Introduction to Astro’s Rendering Approach

Astro approaches rendering very differently. Instead of generating pages on the fly, Astro pre-builds the site into static HTML files at build time, meaning nearly all of the heavy lifting happens well before any users visit the page. The result is a blazing-fast website that can be hosted on a server, distributed via a Content Delivery Network (CDN), or even served by an Edge network, which caches the pre-built files closer to users for minimal delay. Additionally, JavaScript and CSS files are optimized, bundled, and minimized at build time, further enhancing performance.

One of the features that makes Astro unique is it’s “island architecture” approach. Every Astro component is its own island, and JavaScript is loaded only for the interactive pieces where it is needed, leaving the rest of the page as plain HTML. This makes for a light, efficient page load, where content is visible immediately, and interactivity is added in only where necessary.

A graphic depicting Astro's "island architecture" which allows developers to unify static and dynamic content.

While Astro feels very familiar to JavaScript developers, with a syntax reminiscent of JSX in frameworks such as React.js, it is also refreshingly lightweight compared with JS frameworks that are typically overkill for most websites, loading numerous resources that are not necessary for many types of commercial websites.

In contrast to WordPress’ server-driven approach, Astro is all about building as much as possible in advance, and using server power at runtime only when necessary. This shift in mindset when building sites does not mean that everything we have learned in WordPress goes out the window; rather, we can actually apply the patterns we have learned in a slightly different way.

Static Site Generation (SSG) in Astro vs. WordPress

Astro’s primary rendering mode is Static Site Generation (SSG). This is the process described above: the entire site is built as static HTML during the build process. The files can then be served to users without needing a server to generate them on the fly. This is ideal for websites where content does not change constantly, such as most blogs, portfolios, small business websites, and documentation sites.

In comparison, WordPress can achieve a somewhat static experience by using caching plugins or other specialized tools that convert WordPress sites into static files. When a WordPress site utilizes caching, the first time a page is rendered, its content is stored on the server or a CDN. This cached version is then sent to users for subsequent requests, bypassing the need to dynamically generate the page each time. However, WordPress remains fundamentally a dynamic CMS and is always connected to the database—even when caching is used—since plugins, user roles, and dynamic features may still require database interactions.

When using Astro for SSG, you are moving all of the work to build the site to a time and place of your choosing, and then sending a highly optimized build version to users later.

Server-Side Rendering (SSR) in Astro

While Astro’s default approach is static, it also offers Server-Side Rendering (SSR) as an option for developers who need to handle dynamic content. Astro allows developers to generate specific pages dynamically, only when they are requested, which is very similar to how WordPress operates, though Astro uses Node.js and fetching rather than PHP and a database.

With SSR in Astro, you can pull real-time data, handle personalized content, and display changing information – while maintaining exceptional performance. Since the default configuration is still static, you have complete control over which pages are rendered on the server. This allows us to keep the performance benefits of SSG for the majority of the site, and use SSR only when necessary.

A graphic depicting Server-Side Rendering with Astro.

Astro vs. WordPress: A Template Code Example

To highlight the differences between working with WordPress vs. Astro, let’s look at a real world example of a basic page template. In WordPress, we would set up a PHP file that brings in the reusable parts of the template, like the header and footer, and uses the loop to render the appropriate content for the specific page:

<?php
// single.php (or a custom page template in your theme)
get_header();

if ( have_posts() ) :
    while ( have_posts() ) : the_post(); ?>
        <article>
            <h1><?php the_title(); ?></h1>
            <p>Published on <?php the_date(); ?></p>
            <div><?php the_content(); ?></div>
        </article>
    <?php endwhile;
else :
    echo '<p>No content found</p>';
endif;

get_footer();
?>

By comparison, in Astro we would fetch the data we need in the frontmatter section of our Astro template, including any other components that we need. In this case, our Layout component is a wrapper which will automatically put our main content in the proper place. Then we simply pass the data to our template, which specifies how it should be rendered:

---
const post = await fetchWordPressPost();

const { title, date, content } = post;

import Layout from '@components/Layout.astro';
---

<Layout title={title}>
	<article>
	    <h1>{title}</h1>
	    <p>Published on {date}</p>
	    <div>{content}</div>
	</article>
</Layout>

If we needed to use SSR for this template, we would update it to dynamically fetch the necessary data by pulling the page’s identifier from the URL params:

---
import { fetchPostData } from '../lib/api.js';

// Get the post slug from the URL
const { slug } = Astro.params;

// Fetch post data dynamically from an API
const post = await fetchPostData(slug);

const { title, date, content } = post;

import Layout from '@components/Layout.astro';
---

<Layout title={title}>
	<article>
	    <h1>{title}</h1>
	    <p>Published on {date}</p>
	    <div>{content}</div>
	</article>
</Layout>

Posts Loop Example

Another common case for developing sites is to loop over an array of data – for example, building out a blog archive page. In WordPress we would do this by querying our database for a set of posts and using a loop in our template:

<?php
get_header();

$query = new WP_Query([
    'post_type' => 'post',
    'posts_per_page' => 10
]);

if ( $query->have_posts() ) :
    while ( $query->have_posts() ) : $query->the_post(); ?>
        <article>
            <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
            <p>Published on <?php the_date(); ?></p>
            <div><?php the_excerpt(); ?></div>
        </article>
    <?php endwhile;
else :
    echo '<p>No articles found</p>';
endif;

wp_reset_postdata();

get_footer();
?>

In Astro, we can achieve the same result by fetching our array of posts in the frontmatter, and then looping over the posts in a JavaScript map:

---
import { fetchPosts } from '@lib/api'

const posts = await fetchPosts();
---

<h1>Latest Articles</h1>

{posts.map((post) => (
    <article>
        <h2><a href={`/posts/${post.slug}`}>{post.title}</a></h2>
        <p>Published on {post.date}</p>
        <div>{post.excerpt}</div>
    </article>
))}

A Hybrid Solution: Headless WordPress with Astro

Many developers and companies are drawn to the content management capabilities of WordPress, and want the familiarity of the CMS platform, even though they do not necessarily want the front end built with WordPress. If this is you, you might consider a hybrid approach: headless WordPress with Astro. In this setup, WordPress remains the content backend, while Astro is used to generate static pages that can be served on a highly performance Edge network or other CDN. This gives the best of both worlds: a robust, open-source CMS, with Astro’s lightweight page delivery and exceptional performance. In fact, at the time of this writing, this very post you are reading is built with Astro and headless WordPress.

By leveraging WordPress’ REST API or WPGraphQL, you can fetch content with Astro and build static pages, only querying headless WordPress at build time. This completely decouples the front and back end as far as users are concerned, leveraging principles of composable web development to separate concerns.

Final Thoughts

When choosing between Astro and WordPress, as always with web development, the best tool for the job depends on the project’s needs, goals, and available resources. WordPress offers powerful and flexible dynamic rendering out of the box, which has made it the default choice for nearly half of the internet in the early 2020s. On the other hand, Astro offers a streamlined, static-first approach, with an excellent developer experience that is already familiar to JS developers, and easy for PHP developers to quickly leverage.

Whether you are exploring Astro vs. WordPress for the first time, or looking at combining the two for a headless WordPress setup, understanding the nuances of how these platforms handle rendering is the first step in making an informed decision about where to go with your next project. So I encourage you to experiment, test, and find a setup that you love working with for you next project!

Are you looking to build projects with Astro, WordPress, or have questions about either? Feel free to reach out anytime!

October 16, 2024

This post is powered by headless WordPress.