One of the main reasons for using WordPress for a site is SEO, next to ease of content editing. With the help of plugins like Yoast you can easily add seo for your content per page basis.
Context
For my project I’m using WordPress as my CMS and Yoast for SEO, using WpGraphql for data fetching and NextJS as my frontend stack.
With the help of WPGraphQL for Yoast SEO plugin. Huge shout out to Ash Hitchcock for this. You can get the Yoast SEO data in WPGraphQL and use it in your frontend.
Get SEO data via graphql
If you ever used WpGraphql this will look very familiar to you. For any page, post or any other custom post type you have all have this SEO field and with in that all the fields provided by Yoast.
query PageQuery {
page(id: "/", idType: URI) {
title
uri
seo {
title
metaDesc
canonical
metaKeywords
metaRobotsNofollow
opengraphModifiedTime
....
}
}
}
This is great now you can take this info and put it in your frontend sites head.
Easiest way to get the full SEO info
The above step is fine but what if we want all the SEO tags that Yoast generates/adds in each WordPress page. There is a field called fullHead
that gives the raw SEO as a string for each page/post. We can use this in our sites head and this even have the structured data or application/ld+json
included in it.
query PageQuery {
page(id: "/", idType: URI) {
title
uri
seo {
title
fullHead
}
}
}
Only one small problem
There is just one small problem with the above approach, If you check the string returned by fullHead
closely you will see it points to the WordPress site not your frontend url. So if we can find a way to replace the WordPress urls with our frontend urls but not the media urls then we can use this and we dont have to manually add each tags.
The solution
Lets break down the problem so we know clearly what we have to do.
- Replace all the wordpress urls with our frontend url.
- We want to keep the media urls (eg: og:image) same.
let wpUrl = 'https://yourwpsite.com';
let siteUrl = 'https://frontendsite.com';
export default function seoStringParser(data) {
data = data.replaceAll(wpUrl, () => siteUrl);
data = data.replaceAll(`${siteUrl}/wp-content`,
() => `${wpUrl}/wp-content`);
return data;
}
The above function is going to recive the SEO string and we are going to do two replaces. First replaceAll is going to just replace the wp url with fronend url, this solves one problem, all the links are now pointing correctly except the media urls now they are wrong. So we have a second replaceAll that will select ${siteUrl}/wp-content
(here /wp-content
in the end will help us to select only the media items) and replace it back with the wordpress url.
Add the Yoast data in your nextJS site
Finally, Now if you check the string its ready to put in our frontend sites head.
import Head from "next/head";
import parse from "html-react-parser";
import seoStringParser from "~/utils/seoStringParser"
export default function PageSEO({ seoData }) {
let { title, fullHead } = seoData;
return (
<Head>
<title>{title}</title>
{parse(seoStringParser(fullHead))}
</Head>
);
}
Feel free to reach out to me if you have any questions.