Check out a free preview of the full Modern Search Engine Optimization (SEO) course

The "Challenge 2: Solution" Lesson is part of the full, Modern Search Engine Optimization (SEO) course featured in this preview video. Here's what you'd learn in this lesson:

Mike walks through the solution to Challenge 2.


Transcript from the "Challenge 2: Solution" Lesson

>> We're going to go through the a solution to the second exercise, where we're adding Facebook Open Graph tags to improve the recognizability of these links online. And we're gonna make it so that we get a nice thumbnail, a nice description and title in a rich tile whenever these links are shared on Facebook.

So I'm going to begin. So the first thing I did was I just went to this slide here, where before we looked at all of the different meta tags. And I copied these into my editor here so I don't have to reach back for them later. Other than that, no tricks up my sleeves.

I don't currently have my server running. So I'm gonna fire that up. That's going to be run -e opengraph. And that'll start the OpenGraph exercise on localhost 3000. And what we see is a list of courses. And if we hover over each of these or even click on one of them, we can see that this is a different URL on a per course basis.

We should see a different image when we go to different ones, and we in fact do. So this is being driven by this router.js file. But ultimately the HTML is coming from these two hbs files in the views folder. And these are sort of HTML with handlebars that we can use to like mixed data into our HTML.

So I'm gonna copy these meta tags because we'll end up using whatever we can in each of these two files. So here I'm just gonna leave myself a comment, so we can stay organized. So Facebook, Or I'll just call it OpenGraph tags. Because it was rightly pointed out that more than Facebook uses this.

Or I'm gonna say, sorry, Begin OpenGraph and end OpenGraph. So I can find these really easily later on and I am gonna paste it in with all the wrong values, and we will just update those as we go along. So one thing is I'm not gonna actually use an image for this first slide, the list of courses.

Cuz I do not have a good one that would apply it to the whole list. This might be one where you'd like build a composite of several courses or maybe like your brand, you would use the image of your brand there. It doesn't really fit as well for this this thing here.

So we'll keep OpenGraph type as website. It's good to provide this although you saw in my website, I did not. I probably should go and fix that, but Facebook will nag you about this and you will get that warning until you put this here and make it go away.

So for the URL, I'm just gonna use the Heroku URL. Now, it would be nice if we could express this in a way where we could deploy it in a couple different places. And it would not be sort of sensitive to like this literal string being here, but this will do for now.

So this is the canonical URL. What this means is if I were to add like query params to this. So say we could filter through this list of courses by a partial name search, we could just pull up like the Ember courses. That query param would not be in this meta tag.

And so even if we shared that link with the query param and if someone likes that or shares it on, all of the SEO credit goes to the bear URL without any decoration on it. So in our title, we can just put a list of courses. And this is gonna be the description.

Courses I teach. Just put a little like tagline there something, and we're pretty much done with the index page, right? Now we could add some of the things that we had before like meta:description. Oops, I guess I can't do it that way. But I'm not gonna worry about that for this exercise.

So I'm gonna copy this block here. We're gonna do a slightly edited version of it for the course.hbs page. We'll just drop it here. Now, the URL in this case is gonna be dynamic, right? Cuz it's different for each course that we click on. I'm gonna balance something from index.hbs that we used to build the links, right??

This thing here. And I'm gonna use it course page like that. Cuz we're using this course information elsewhere. And it seems like that should work, right? And that matches what the URL will be when I deploy. The og type unfortunately, I don't have a more specific type that I can use for this kind of thing.

If at some point they were to say like course is now type, this would be fantastic. Because in the future if there's some Facebook app that lets you say, these are the things, the classes I wanna take. Now I could be part of that, and I could be recognized as being of that specific type.

And anything that relates to courses across Facebook's whole platform now will show up there. The title, I'm gonna use the same title we are putting in our h1 tag. And we also have a description that we can take advantage of there. In this case, and there's no way for you to know this, I have a description and a summary.

The summary is of a shorter length than the description. The description can be a couple paragraphs long, right? So I'm gonna just choose to use the summary. Again, there was no way for you to know this, but I have made something that that is designed to be short, and keyword-rich.

And that is a specific column in my database that is really all about SEO. And so I have a couple different variants of description there for different purposes, right? All right, and now time comes for an image. Now I did hear from someone that og:image URL, I did when we were reviewing this.

I suggested that that might be an equivalent that you could use, turns out that's not correct. You just want og:image. And instead of using the square.url, if you look at the structure of this data here, let's take a look. So inside this image info object, let's just grab this one as an example.

You can see we've got several different sizes, and we have width, height and URL for each of these different sizes of image. So I'm gonna use FB share, which is the one I've built for Facebook. And you can see I've built my API here with SEO in mind, and with the idea of being able to have statically sized images in mind.

So that we know exactly what width and height this thing is gonna be. And we're gonna get into error pages later on. This is another place where we wanna make sure that things are rendered fast, just like Facebook wants to render things fast. And they wanna basically size everything before that image actually finishes downloading.

And then once it lands, it's not gonna cause your layout to be altered in any way. You're not gonna have content shifting around. Because this thing that came in was larger than expected. So that should be a good place to start there. And then we're going to add in our width and height.

Image:width, and then basically the same thing with height. All right, so this should be good. Now let's make a commit. All right, so now we've made it like a new version of our app here. Before I push, you'll notice that like my app is currently it's showing the first exercise we were working on.

All day what we're going to be able to do is switch to different exercises by just changing that environment variable exercise that we initially set. So this is the same thing you use as the argument to -e when you run your app locally. What it'll end up doing is restart the app.

And if I do a refresh here, you'll see that it'll give me my starting point for the list of courses. There we go. So now we're gonna push this new version up to GitHub with git push heroku master. And we can see that it's gonna go and do its thing.

Pretty quick, so the build is done. It's compressing it, and should be available now. So I'm gonna just refresh because it takes a little bit longer the first time you do a new deploy, it has to sort of start things up. And we'll go back to the open graph debugger, and I'm gonna grab one of my URLs here, let's do an image we haven't seen yet, let's do this.

All right, so there's elixir fundamentals, so we're gonna paste that here, hit enter. And the first thing you'll notice is it's saying, I've never fetched this information before. So this is what you'll get for brand new apps. I'm sure all of you ran into this, fetch new information.

All right, and now we can see there's our image that just came in. You noticed if you were looking closely, the frame was exactly the right size for the image, and then it kinda came in and filled it up. And here are all the OpenGraph tags that it found.

So they're all what we put in there. We have nothing more than what Facebook is looking for here. And if we go up to the top, we have one warning here that says, it wants a Facebook app ID. This is not Critical, this is one warning that it's safe to ignore, particularly if you're not registered with the Facebook app platform.

If you have like a login with Facebook button, then you will have an app ID that corresponds to the setup required for that. And you'd put your app ID there and it might give you a little like decoration with a little tiny logo or something. Connecting your brand and your app on the Facebook platform, even if it's just login with Facebook to whatever is shared here.

I do wanna demonstrate that I can add a query param to this URL. This is a brand new URL, never been fetched before. And because of the way we set this up, the canonical URL here it's gonna be exactly what it should be, right? So regardless of whether we're dealing with the mobile view, or whether it's the admins view of this thing.

Anything that would like be the extra decoration on this URL, all of our SEO credibility built on that same link. And that is the OpenGraph solution. So I'm gonna start committing these solutions that I come up with to a brand called solution. And you can check them out if you wanna compare it with what you ended up doing.

>> So I noticed you're using query params in your image URLs.
>> Yes.
>> So that you get around the fact that URL never changes, they will never refetch it.
>> It absolutely is to get around with that. So you'll notice, and this by the way it's something that AWS supports.

So I'm hosting my images on Amazon Web Services S3, and I am putting CloudFront in front of that, which is their CDN. So these images end up having a version next to them. So that version query params is based on the modification time of that file in S3.

So this is a way of sort of getting around Facebook's, like once you give me a URL, I will never update it. And in particular because the names, if you look at this image URL, it's very common when you have an image associated with a record to have like the ID of that record baked into that image URL.

So if you give me a course ID, I can give you the URL for this image. So I don't really have the freedom to have a different URL here. As long as I have a record 6, this is the one URL for this particular size of this image.

And so the version query param necessary in order to bust the cache. If I upload a new version, like say Elixir changes their logo and I wannaupdate my thing, then that would be what I would use, but good eye. Good eye and a common strategy to deal with this kind of problem.

And by the way Facebook would not have a problem with this because their whole idea is like they wanna detect changes. They just don't want to refetch images each and every time with the assumption that they could be modified at any time. So this is me giving them a totally appropriate signal that I'm sure they would appreciate if all developers did something like this.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now