Save time with your Jamstack Headless WordPress and Next.js integration. The guide I wish I had when first starting out Here
About a year ago I created a post about connecting a wordpress installation to React.js.
For some reason that post has brought 1000’s of eyeballs to my site in terms of traffic…I guess a lot of people are trying to do the same thing.
I’ve been meaning to convert my site over to Next.js and take advantage of GetStaticPaths/Props for months but life just gets in the way.
This week I finally took that off my ToDo list. I’ll try and keep this short and sweet.
I was fetching my wordpress posts everytime someone loaded my React SPA and saving that to a context provider, the site is small so not a big deal of api calls…..but
My wordpress installation has an SSL cert set up, but this thing expires every 2/3 months.
Every time that cert expired, my fetch attempt would fail and the posts wouldn’t show up.
Statically generating these posts and pages would save me a tonne of worry and time, so let’s get into how it’s done.
I’ve already covered this but here’s what we need;
You may be able to skip the next three if you’re just fetching regular posts, but I’m working with custom post types, so i can add my own features to the API.
We’re going to dynamically fetch all of the posts that live in a specific route of your site and also grab more than the default which I think was 25 at some point in time.
URL: Non custom post type:
Here’s a list of all the default end points for WP API, you’ll probably need /posts or /pages.
URL: Custom post type
Update the url below to match your website and after the v2 you’ll need the custom post type name that you’ve chosen.
https://website.com/wp-json/wp/v2/CUSTOMPOSTTYPE?per_page=100
Then per page we want at least 100, which I think is the max without pagination
For my site, I wanted mysite.com/blog/dynamic-content-here, so I started with creating a ‘blog’ folder in my next.js Pages folder, then added a dynamic js file with the square brackets.
Pages -> blog -> [slug].js
The name in these brackets needs to match params object you’re returning in getStaticPaths which you’ll see below.
export async function getStaticProps({ params }) {
const post = await fetch(
`https://yourwebsite.com/wp-json/wp/v2/react_blog?slug=${params.slug}`
).then((response) => response.json());
return {
props: { post: post },
revalidate: 1,
};
}
export async function getStaticPaths() {
const results = await fetch(
"https://yourwebsite.com/wp-json/wp/v2/react_blog?per_page=100"
).then((response) => response.json());
const paths = results.map((post) => {
return {
params: { slug: post.slug },
};
});
return { paths, fallback: "blocking" };
}
Paths function is going to fetch from my custom post type called react_blog and grab, at most, 100 posts from there.
Convert all of that into JSON and save it to results.
We’re then mapping over results and creating out params objects. These are then passed to Static Props where we do almost the exact same thing, but this time with a single url.
I fetch the content from that URL and send an object called props up to the component.
I haven’t found a nice way to do this, other than using dangerouslySetInnerHTML which just sounds bad 🙂
const Blog = ({ post }) => {
// post comes in as array with single object
const content = post[0];
return (
<>
<div dangerouslySetInnerHTML={{ __html: content.content.rendered }}></div>
</>
)
}
export default Blog;