Crossroad Development

two roads crossed to make an X

Headless WordPress with Astro

2023-02-13

Using WPGraphQL plug-in for WordPress, you can get higher granular output, compared to the built-in REST API, and the ability to add comments or ‘mutate’ content or comments. Chris Bongers has a great guide in his blog at Open Replay. However, I ran into some issues with Astro 1 or 2, because I believe the guide was written before the 1.0 release.

To begin, spinning up your own WP server is usually not the best move if it is only going to be used to fetch some JSON data. For example, an AWS instance capable of running MariaDB, and everything else for WordPress is going to run about ten dollars a month, where as a node server where you plan to run your Astro server-side renderer, would be about four fifty a month. There exists a range of free options from 000webhostapp or atwebpages, I encourage you to do some research and compare how much bandwidth and storage you suspect you’ll need for the given project. Then, I do not use tailwind, so I skipped that step as well. I think it is a great framework and it works for many people’s mental model, to just add classes as they need new styles, but I am so used to a class for a general object and some direct styling for the ID if required. Also, if you are unsure how to use the dotenv set up, write the API endpoint to a variable directly, WPGraphQL should let anyone mutate your posts if they stumble onto the endpoint. So, finally some differences in actual implementation. In the POST request, I left out variables, because in both calls, it wasn’t getting passed anything and didn’t need to be there.

const res = await fetch(API_URL, {
    method: 'POST',
    headers,
    body: JSON.stringify({query}),
  });

Compared to the original call.

  const res = await fetch(API_URL, {
    method: 'POST',
    headers,
    body: JSON.stringify({ query, variables }),
  });

Then, you must return props as well as params with the newer version of Astro.

export async function getStaticPaths() {
  const pagesWithSlugs = await getAllPagesWithSlugs();
  return pagesWithSlugs.edges.map((nodes) => {

    return {
      params: { slug: nodes.node.slug },
      props: {stuff: nodes.node.slug},
    };
  });
}

As opposed to the original article.

export async function getStaticPaths() {
  const pagesWithSlugs = await getAllPagesWithSlugs();
  return pagesWithSlugs.edges.map(({ node }) => {
    return {
      params: { slug: node.slug },
    };
  });
}

You’ll see the reason for this change is that Astro can’t select the params, and it has to be passed props. Like this.

const stuffs = Astro.props.stuff;
const page = await getPageBySlug( stuffs );

Which differs from the original

const { slug } = Astro.request.params;
const page = await getPageBySlug(slug);

Other than that I really recommend playing around with the GraphQL IDE to build more complex queries, including the date, author, or avatar. Then try playing with mutations to set up commenting. Look out for that post in the future.

Comments


Keep in mind this guide is assuming you want to server side generate your content, but I really see the headless WordPress application of this requiring a server side rendered solution. Astro’s docs explain this well enough but the dynamic routes are more tricky this way. I will probably do a few follow up guides in this area.

--John Murrayprofile picture