Transcript from the "Add SEO Meta with React Helmet" Lesson
>> Where we left off was we had just pulled in the site metadata that we'd created in our Gatsby config. So, we pulled in this title here, and we're querying for it using Gatsby's graphqL layer and displaying it in a little bit of a header here. So that is giving us this great experience where we have our home link in a header controlled by this Gatsby config.
[00:00:27] So anywhere that we use this, if we edit the config, it's gonna get updated. Nice and handy, that's pretty great. So the next thing that I wanna do is we still haven't solved this problem where we're just showing the URL in the title bar. I want this to show something useful on the homepage.
[00:00:44] I want it to show this Frontend Masters Intro to Gatsby, I wanna include a meta description. I wanna include that image that we created so that if you share this on Twitter, you'll actually be able to see that image shared, right? So we wanna make sure that our sites have all the SEO benefits and meta tags that they need to be shared on Facebook, LinkedIn, Twitter, etc, etc.
[00:01:07] So let's do that. What we're gonna do first is we are going to install a React project called react-helmet. This is a package that is designed for modifying the head of documents generated by React. And the head tag is where we're gonna put title tags, meta tags, so on and so forth.
[00:01:44] We're gonna stop our server. Npm install, react-helmet, and gatsby-plugin-react-helmet. And as these install, here they go, we can head back over here into our Gatsby config. And now we're going to use another field in our config, which is plugins. And plugins is an array, so we can put whatever we want in here, and I'm going to add Gatsby plugin react-helmet.
[00:02:15] Okay, so here is Gatsby plugin react-helmet, it's now added to our Gatsby config, which means we can use it. So let's restart that dev server. And as of right now, nothing has happened. If I wait for this to go, here we go, refresh the page, no changes. So we're gonna go into our index file and we're gonna make this thing work.
[00:02:45] So the way that we do that is I'm gonna add a bunch of Seo tags. And we're gonna need this for every page, right? So let's take advantage of something that React does and let's make this into a component. Let's not hard code this whole thing out. So I'm going to create a components folder.
[00:03:07] And inside of that, I'm gonna create a file called seo.js. And inside of this, we're going to do the dance with React, import everything as React from react. And we're also going to use helmet, so let's import helmet from react-helmet. And finally, we're gonna need that data that we put in the static config, the site config.
[00:03:35] So let's import useStaticQuery and graphql again from Gatsby, all right? Now, we can export a function that we are gonna call Seo, and I don't want React to yell at me about not pascal casing my component. Which is why I'm not capitalizing the E and O, even though it deeply pains me to do that.
[00:03:57] And inside of this, we're gonna accept some props, because we wanna pull in title, description, etc, as something you can customize in this. So let's do that, we're gonna have the ability to pull in, actually, you know what? Let's just call these props. And I'll show you why momentarily.
[00:04:18] So first and foremost, let's get our data again. So we're gonna get data and that is gonna be the result of useStaticQuery, and that's gonna use graphql. And this time, I do actually want all of those fields, so I'm gonna go back out to my graphical, and we're gonna do site.
[00:04:37] And I do want the description image and site URL. So let me grab all of that. And again, we wanna give our queries a unique name because otherwise, Gatsby will complain that we've done something confusing. So let's call this GetSiteMetadata, all right? And then down here, I'm going to, Call these our defaults.
[00:05:04] So by default, we don't provide any arguments, we're gonna use the metadata from Gatsby's config. So we're gonna get this as data?.site?.sitemetadata; and then we're gonna pull out each one. So for the title, we wanna check if a title was set. If the title was set, we're gonna use it.
[00:05:34] Otherwise, we'll use the default start title, right? And the reason I'm using props here is because I don't wanna have to have title equals, and then here would be actual title, or something like that. We don't wanna have to double declare. So by leaving it as a props object, we don't have to worry about that, it can just be title, title, title.
[00:05:56] Let's do the same thing for the description, And for the image. Whoops. Description and this one, It's gonna be image. And then finally down here, we're gonna do a little bit of magic, cuz we want the URL, we're gonna do a canonical URL. And the way that we're gonna do canonical URL is we're gonna use the URL and we'll get the props.path.
[00:06:34] So props.path will be the full link to our page, or it'll be just an empty like a slash. And we're gonna set the base as the site URL, right? And so what that'll do is it'll make the canonical URL a full HTTP URL, which is what we want.
[00:06:57] And now that I think about it, we wanna do the same thing for the image. So I'm going to, let's do the same thing here, new URL, because the image again, in a social sharing that needs to be a full URL. It can't just be like \images\whatever, it needs to be http and so on.
[00:07:16] So we're gonna use the props image or the default image, and that will also use as a base the defaults' site URL. And that gives us a fully qualified URL. And the nice thing about this is if you put in here a full URL, it'll just override this base.
[00:07:35] So the the URL API is smart enough to handle that. But if we wanna put in relative path, this makes sure that it still works. So now that we've got our title, description, image, and URL, we can actually start using these. So let's return some react. The first thing we're gonna do is set up a helmet component.
[00:07:55] And helmet is kind of, it's like a head tag but not quite. So it's got a little bit of its own API. But for the most part, we can just use it like a standard head tag, so we'll add in a title. Let's add in a meta name="description', and we'll give that one a content of the description.
[00:08:25] And we wanna do a link rel"canonical", and this will solve that trailing slash problem, because this URL will be the same and we'll get a canonical URL. So we can set the href to be our URL. And finally, if there is an image, because there might not be, then we're gonna set a meta name of image and the content will be the image, right?
[00:08:59] Okay, so, and then we need to make that here. And the reason that I make this optional is that it is possible, but maybe you don't want a default image and so you leave this empty in your Gatsby config. And then that way means we don't put a broken image up as your image.
[00:09:21] So next, we wanna set up for Facebook. So let's do property="og:url", and that's gonna be content=(url). We can do this again, let's do a type and you can do a lot of things with these. I'm doing a pretty general purpose, this will be fine. And you can do a little more research if you wanna do it exactly the right way for rendering the title, og title will be that.
[00:09:55] The description, Right, and then we want, what else? Yeah, we need one of these image ones. So let's copy this one actually. And this one will be an og:image, and its content will be image. All right, so that's Facebook and a lot of other services, but we also wanna make sure that we're doing Twitter.
[00:10:22] All right, so let's add one more. We're gonna do a name of twitter:card. And because we're assuming we're gonna have an image, we're gonna make this a summary_large_image, right? Then we're gonna set meta:"name", and that'll be twitter:title. And all of these could be, you could make these configurable where you could Set custom stuff on Twitter and custom stuff on Facebook.
[00:10:49] I don't like doing that mainly because it makes me lazy and I never do it. So then I just have all this config that I don't wanna deal with, and then I get overwhelmed and either ignore it entirely or end up letting my site languish. Because I can't bear the thought of having to update all this content.
[00:11:09] So let's do another one of those image ones. This one is gonna be called twitter:image. Okay, so now what we've created is we have grabbed out default metadata. We are exporting a prop called Seo that accepts props with the title description image in path. And we are returning all of the Seo tags that we might need to manage not just the browser display, but also what shows up on Google, what shows up on Facebook, what shows up on Twitter.
[00:11:42] And a whole lot of other services will read these open graph, so like LinkedIn and stuff like that. So we're customizing the way that our site is gonna look across social media. Once we have saved that, we can head on over to our index page. And we're gonna import Seo from /components/seo.
[00:12:07] I include the extension because, yes, modules include the extension and eventually, we'll get away from Babel and Webpack. And that'll mean that we will need extensions for local files. It's optional, you don't need to do it. If you don't agree with me, that's fine, just leave it out.
[00:12:24] Once we have the Seo component, then we can come down here and let's just use it, right? And so, on the home page, we wanna use this defaults, so we just drop that thing right in. Boom, no changes. Then we can come over here, reload, and let's take a look at what showed up under the hood.
[00:12:45] Let me move this over to the side again. And if we look at our elements, we can see in our head, we've got a title. We've got a description. We've got our canonical, which is bad because we have this placeholder domain. But that's okay, we can fix that later.
[00:13:02] We've got our image which is actually going to the right place. We've got the open graph URL, what type it is, all the things that we need for these sites to show up properly on social media are now in place, right? And that is really, really handy, and it used all of our defaults.
[00:13:20] So we've got the like in the description, Intro to Gatsby Course Projects, that's what we wanted. So now let's go look at the about page, so we didn't make any changes here. So you notice that it kept the one from the homepage. This is something that gets a little bit weird, which is why it's important to make sure if you add Seo tags, update them.
[00:13:45] Because once they're added, React and react-helmet, and Gatsby, they're not gonna unset stuff, they're just gonna look for changes. So if you set Seo tags, make sure you add them to all your pages. You can do this through front-matter or whatever. So let's go ahead and get this added to the about page as well.
[00:14:03] And this time, we're gonna do it with some changes. So let's go to about, I'm gonna import this Seo tag from /components/seo.js. And then down here, I'm going to wrap this whole thing in a fragment so that I don't have to put my Seo tag inside of my main tag.
[00:14:26] We'll do Seo, whoa, thank you, autocomplete, all right? So we'll do Seo, we'll do the title, and I want this to be about this site. And for a description, we can put something like more information about this site. Now we've got, here's our Seo, here's our actual site content, if I refresh the page, we can see that it's showing up properly.
[00:14:57] Let's look at these elements again. Here's the head, and we'll watch as I navigate, you'll see these kinda light up and change. So there we go. Let's see the title change we can see some of these react components changed. You see him jumping around at the bottom here, right?
[00:15:18] So, we can see that as we're navigating around, the social sharing data is updating and changing around for us. So, that is an Seo component, right?