AHA! JavaScript SEO Moments: 8 Common JS SEO Issues & How to Overcome Them

Updated on: 
January 25, 2023
Sam Torres
Sam Torres

The "Learn JavaScript for SEO Cohort" was a group learning experiment led by our own Sam Torres in conjunction with others from our beloved Women in Tech SEO community. The following is the final, recorded presentation of the group's learnings, as led by Sam. In it, we'll review the 8 most frequently occurring issues with JavaScript SEO we've personally encounteredas well as how to resolve them.

My AHA Moments with JS SEO

Video Transcript:

All rightso this is just something I put together for the cohorts about things that I've run into, things that I see. Ideally to try and help! So hopefully it does, if it doesn't, I apologize.

So just some things to know about this. And so that, like I said, this is just a summary of my experiences, the things I've commonly run into. It's definitely thought of from an SEO first perspective, and less from me "wearing my developer hat".

What This Presentation Is and Isn't

What this JS SEO presentation is and isn't

Video Transcript: 

I will tell you, it's not going to help you learn JavaScript development, it's not a comparison of the different frameworks, it certainly does not cover all possible topics, that would be pretty much impossible. Then there could also be mistakes. So these are just things that worked for me. But it doesn't mean they're perfect. And also things updateso if we refer to this in a year, things might be different. So just -just so you know.

Slide Text: 

What this presentation is: 

  • A summary of what I've learned/experienced
  • Common questions or errors I've run into, and the solutions I found for them that worked at the time
  • Free
  • Prioritized for SEO

What this presentation is not: 

  • A guide to learning JavaScript Development
  • Comparison of JS Frameworks
  • Expansive or all-encompassing
  • Infallible

JS Frameworks We're Discussing

JaveScript frameworks we're discussing with in the context of SEO

Video Transcript: 

As far as the frameworks we're going to take a look at, we're gonna look atI'm calling it foundational JavaScript, it's usually just JavaScript sites, or in development, we typically call that "Vanilla JavaScript." React, and then they have a tool called Gatsby. And then we're going to talk about Angular and Vue.

So React, Angular, and Vue are the three most popular JavaScript-based frameworks. But there are dozens if not hundreds more. I wanted to cover these three, since these are the ones that we'll typically be running into as SEOswho just come across JavaScript sites.  

Slide Text: 

Frameworks we're discussing:

  • Foundational JS
  • React (and Gatsby)
  • Angular
  • Vue

Please know that there are dozens more JS Frameworksthese are just the ones I've most run into (and/or coded myself)

The JavaScript Auditing Process

The JS SEO Auditing Process basics

Video Transcript: 

When I'm going through and find out, you know, as far as my process goes with these things, the first thing I always have to do is identify the stackso I have to identify which technology is being used. I use a Chrome extension called Wappalyzer. Highly recommend it. We can take a look at it after the slidesof just what it looks like.

Also, anytime you need it, and it can make you sound really impressive, because clients will be like, how in the world did you know what my website's built on? And you just look like a wizard. So let's all be wizards!

Then I'll do site crawls. So I either use Screaming Frog or Ahrefs with a JS rendering, and look for any kind of errors that may come up. And then also really important is investigating how things are being rendered.

What does Google Search Console have as far as the content for that page? Because there's definitely times where maybe your content's being crawledbut not indexed, maybe some of it's being crawled. You know, really being able to identify where those nuances are is pretty critical to diagnosing your issues.

Learn More: Our Ultimate Guide to the JavaScript Auditing Process for SEO.

Slide Text: 

My process:

  • Identify the Stack: I use a Chrome extension called Wappalyzer
  • Site Crawl: Using Screaming Frog or Ahrefs with the JS rendering, I'll look for any errors
  • Investigate in GSC: Knowing whether your content is being crawled at all is essential to diagnosing issues

JavaScript SEO Issue #1: Only a Portion of the Page/Content is Getting Crawled or Indexed

We've all been there.

Video Transcript (2:49): 

So to dive into our first problemso are you seeing that only a portion of your page or content is getting crawled and indexed? So maybe this is like you've gone into Google Search Console, and you see that the page URL is there, but it's only getting about 40% of the content? Chances are, there's a JavaScript error.

And then also, so you guys know, I've put these little like "pills" at the top {of the slide images}, so that I can tell you which framework it applies to.

But when you look in Inspectand that should be Google Chrome Inspectbasically looking at the Chrome Dev Tools, and then if you see something like this on it, it could be causing a JavaScript error that is making the rest of the page unparsable. As a rule, JavaScript is very unforgiving when it comes to languages. Also, its error handling essentially sucks.

Possible Culprit: Javascript Errors

Possible Culprit: JavaScript Errors - example error

Video Transcript: 

Error handling is basically the message that's delivered to youas far as telling you what's wrongso really, the only solution you have at this point is to ask your developer, "Hey, what does this mean?" Now, I will say, like this one, if you see an uncaught syntax errorso syntax errors are actually errors,  but if you see something at the top of the console, because you'll usually see a few more messages here. If it's at the very top 9 times out of 10,  in my experience, it's just an alert and not really an "error."

So just know that your dev might say that, and it's probably pretty founded. Now, of course, developers are inherently lazythat's why we code things, to do the work for us! So if you have any questions about that, of course, pose the question in Women in Tech SEO, I'm sureI'm sure you'll get some answers. And then also, just to note, as someone who is a developer, just remember when you're "framing" this and how you communicate, like, "Hey, what does this mean?" It can make someone go immediately on the offensive and not want to help you. You know, as much as we're always having to work with our clients or internal teams to really comfort them and make sure they know that (a)we are the experts, and they come to us to have those answers, we need to have the mindset with our developersTHEY are the experts.

They just may not know how to implement it according to the way we want to, which is why we have to talk. So that's the first problem.

Slide #1 Text: 

Possible Culprit: JavaScript Errors.

{Screenshot of Inspect > Console - Uncaught SyntaxError}

If you're seeing some content in GSC Inspect but not all, you could have a JS error that's causing it to be unparsable (unreadable).

"Find these errors by checking the Console in Chrome Dev Tools while on the page in question."

Slide #2 Text: 

Possible Culprit: JavaScript Errors.

JS is unforgiving, and its error handling leaves much to be desired. Solution? Raise it to the developer.

  • "Remember that how this issue is framed could make a dev go immediately on the defensive. Tell them what you’re seeing in GSC and ask if that could be a cause. As much as we want clients and internal teams to recognize that we’re the experts, remember that your developer is the JS expert."
  • "In my experience, 9/10 of errors that occur at the top of the console are just alerts and not necessarily errors. So be prepared for your dev to say that. Unsure that you believe the dev? Ask the experts in Women in Tech SEO."

JavaScript SEO Issue #2: Entire URLs, Pages or Whole Sections of a Site Aren't Being Crawled

Not the gumdrop buttons!

Video Transcript (5:19): 

Next problem, maybe you have entire pages or sections of your site that aren't being crawled. Does anybody actually know what "not the gumdrop buttons" comes from? I need to deliver this to an American audience. It's from Shrek, I have a lot of like, pop culture references in here that I shouldn't have put in, but they're there.

Possible Culprit: Bad Linking Approach

JS SEO culprit: bad linking approach

Video Transcript: 

So first off, you could have a "bad linking approach." So kind of the same that we would have with any website, if you don't have links to the contentand it makes it really impossible for Google to find it. And then of course, we've talked about this quite a bit, at length, as far asyou have to use anchor tags, and these other methods of like a router link or a span or onClickthose are not functional.

Unfortunately, developersfrom everything I can tell that go to school or Bootcampthey don't really get, or "set a standard" on how it should be used. So to a developer, all of these methods are totally valid! So our job as SEOs is: we need to provide documentation, and then I also have a link to Google's documentation, and I straight up pull the screenshot from there. So that makes it a lot easier. Developers love documentation. If they don't... that's pretty weird.

Slide Text: 

Possible Culprit: Bad Linking Approach

*Links are not properly coded to use an anchor and href.

Can follow: 

  • <a href="">
  • <a href="/relative/path/file">

Can't follow: 

  • <a routerLink="some/path">
  • <span href="">
  • <a onclick="goto('')">

*No industry-standard for developers on how to make links
*Solution? Provide documentation. Here's Google's.

Possible Culprit: It's a Single Page App (SPA)

JS SEO culprit - it's a single page app (SPA)

Video Transcript: 

It could also be a Single Page App, or an SPA. Is everybody familiar with what an SPA is? Yes, okay. Um, so, basically, with Single Page AppsReact, Angular, Vuethey all make SPAs at their base level. And, of course, that can be really cool, because you just kind of skip through content, there's no page load events that need to fire. But that does also mean that crawlers aren't seeing the "changing content." So that can be an issue.

Now, just a side note, if you ever have an appwhere you actually don't need it to be crawled, but you do want to see it in Google Analytics, you can actually circumvent that problem by feeding "history change events." And so that's not gonna help your SEO, but just a little tracking information, since Google Analytics and data is my other love.

So as far as when you have an SPA, your options for fixing that: there's some rendering options. And then there's also router plugins or extensions for each of the frameworks. And so we're going to talk a little bit about all of those. Any questions so far?

Slide Text: 

* Many JS frameworks end up creating a SPA. This makes for super quick experiences for users by skipping the page load step. It just replaces the page with the requested content.
* This means that users don’t actually change URLs, meaning the crawlers can’t see changing content — they only ever see one page.
* Solutions? 

  • Rendering options
  • Router plugins

"If you’re having issues with seeing pageviews in Google Analytics, you can circumvent this problem by feeding History Change events with the new content request. This will NOT help with SEO however."

Rendering Options By JS FrameworkReact, Angular & Vue

JS SEO Issue: rendering options for SPAs

Video Transcript: 

Next, alright, so for the rendering options, so I put together this chart; these are just my recommendedor what I found that works really well, or consistently come across. So the idea with this is thatdepending on the framework, and depending on what style of rendering you'd like to utilizethis would be the type of tool that you could recommend to the development team. So pre-renderingwe're all familiar with that. We have; there's also a plugin for React called React-snap, we're going to talk quite a bit about Angular Universal. And then there's also some pre-rendering web packs and CLI for Vue. So all of thoseexcept for the Prerender.ioare actually plugins or essentially other libraries that would get added to theto the app that's already there.

And just, you know, anytime using React, Angular or Vue, even if it's a website, it's actually always called an "app" on there. There's straight up an "app tag" that houses everything.

Then you have server side. So of course, that's where all of the calculations are being doneon the server, and not in the client browser. So React does this by using Node, or a plugin library called NextJS.

Angular Universal. So to talk about that a little bit, Angular is actually the framework that Google uses, so they spend a lot of resources and development on making improvements to Angular. There is another kind of sub-library of Angular called Angular Universal, and this puts together both pre rendering options, server side, and really handles a lot of thewhat's considered "best practices for SEO." It also has quite a bit of other uses in other kinds of functionsmore than just SEO. So it's pretty common that if you have Angular, it's probably going to also include Angular Universal.

However, I will say Angular Universal is more useful in Angular Version 2 versus Version one. We can talk a little bitbasically, if you see someone saying AngularJS, that's Version 1, if they're just saying Angular, that's Version 2. Why it's that way, I have no idea! Butjust you know, when you're talking about it.

And then Vue has a library called nuxt.js that can be used for the server-side. Now, with server side, they almost all require some special server setup. Like for the React, you actually have to have Node running on the serverit can sound really scary, but actually, pretty much every major hosting service that can do apps like this, can also support Node. The difference is if you're ever using Azure, or a Microsoft-based server, they have their own unique things going onit can still be done, but I would just recommend that you probably need to at least get a consultant to help set up that server correctly.

And at that point, that's probably out of SEOs purview, and it's on engineering. Or if you say it's on Windows, maybe you just run, run far away, if you're an agency! Because IIS is the bane of my existence.

Next, we have a Dynamic. So of course, that's one of the ones that we studied fromthat's referenced in Google's documentation. So there are a couple tools that do that. And remember that dynamic is where basicallywhen the query is made, like to pull the page data,the server looks at who is asking for the data, and will  either give the response of the live JavaScript client-enabled version, or they will serve kind of the static version. And that will get served to crawlers and bots.

So that's what Dynamic is. There are a couple different toolsso, again, Rendertron is also a very popular tool use for it, I personally have not used it, I've used But those are kind of the two biggest ones that are "accepted."

Next, you have Isomorphic. So Isomorphic is probably one of the things that I absolutely love. Um, so Isomorphic is a little bit different than Dynamic in the fact that it will always serve the static one FIRST, and then if it sees that the clientor who is accessing this informationwhose browser is capable of doing JavaScript on the client side, it will then serve the JavaScript enabled and interactive. There is no difference to the user, they don't see the change at all. But I really like it because the response time's a little bit faster, because there isn't that amount of logic that needs to happen when the when the request is made, like there is in Dynamic. Remember, in Dynamic, the request is made, the server then says "Oh, who is this?," and then sendsyou know, determines what to send. In Isomorphic, the same thing is always sent, and THEN it does the query, and then it'll change content, if it needs to.

Isomorphic is something that's becoming very popular among JavaScript frameworks. React already has it with this plugin called "Isomorphic Render". Angular Universal for Version 2 already does it. Vue, however, does not support any isomorphic rendering options that I've heard of so far. And in order to do it, you have to use server-side rendering, and then at that point, you're actually introducing new technologies to make it happen.

Lastly, we have static site generators. So this is whereif you're familiar with how WordPress works, you basically have your template, the PHP goes to the server, and pulls the applicable content that should be rendered within that template. So essentially, what a static site generator does isit does the same exact thing, but it's going to go ahead and take all that HTML, create the raw HTML files for you, and then actually, at the end of the day, you're serving these HTML files.

Gatsby is one of those popular ones for React. But there's also Hugo and Jekyll which are making big waves. For Angular Scully is pretty much the only one that can be found, and it's not very popular. So staticso using static site generation is not very popular for Angular users. And then for Vue, you've got Vuepress and Gridsome. So those are some of the biggest ones. But definitely, you're going towhen it comes to static site generators, you're going to see React a lot more than anything else. There's a lot of informationquestions?

Speaker 2: 
Yes. Youcould you say a little bit more about the Dynamic rendering in terms ofit used to be really recommended by Google. And now I sort of hear that it's kind of not recommended anymore, or it's considered like, "Well, we used to recommend that, but now, I don't know." I hear names like hydrationand all kinds of stuff I don't understandare somehow better than the dynamic rendering? Could youdo you have any opinion you could offer there? Or like, what's the development going inin what direction is this going?

Sam Torres:
Sure. So everything that's within Google's documentation, because I was doing making sure I had my, my all my ducks in a row, I'll make this presentation. Um, everything in Google's documentation is still supporting Dynamic. However, the development community is definitely supporting more Isomorphic, which uses that Hydration layer. And so that's where you're going to hear a lot about it is usually having to do with Isomorphic.

Note: As of August 2022, Google officially no longer recommends Dynamic Rendering as a permanent (3-5+ year) solution; it should only be used as a temporary workaround.

There's a couple other rendering versions that use Hydration, but they are much less popular than Isomorphic, because it is becoming something that's soalmost natural, to React and Angular. Like it's becoming almost part of like, the default set that anybody would use. So the other reason for that is just, you know, to me, and this is a personal opinionthe reason I like Isomorphic is because it looks at the user, at the timeas they're engagingbut the response has already been made. So they're already seeing something, whether it's a user, like an actual person, or a crawler.

Whereas Dynamic, I personally really worry about, you know, that request, and then the calculation of what to serve. Like, we already know that Google has crawlers and other search engines that don't actually identify themselves as Googlebot, right. So "what are they getting served" is kind of hard to tell. The Isomorphic is identifying whether a user has the capability of client-side rendering versus just who is making this request. So to me Isomophic's a little bit more reliable. Dynamic as wellwith edge computingso basically, right before the requestsI'm sorrythe response leaves the server. Edge computing is becoming bigger, but that's also becoming a little bit of a security risk, meaning somebody couldcould potentially screw with that response. Um, so it's just a bit of a security gap that has to be taken into consideration when using Dynamic. Now Prerender and Rendertron, they already have those security measures in place, so you don't really have to worry about that. It's just if you were doing it kind of "all by hand" or custom on your own servers, those are considerations that you'd have tohave to think about. Does that answer your question?

Speaker 2:
Um, yeah, thanks. Um, and really shortif a team is using Vue, and they're already familiar with Nuxt, can you think would there be any reason to change to Dynamic? Or should they stay with Nuxt?

Sam Torres:
So with server side, the biggest thing is the configurationso if it's already running, I would keep it that way. Because also on server-side, everybody's getting the same kind of content.

Speaker 2:
Yeah, I like that, too.

Sam Torres:
Yeah. So yeah, it's just the setup is where it getsfor... it's probably the most difficult to set up. But if you have it, there's no reason to change it. In my opinion.

Thanks. Any other questions about all the rendering options? Okay, cool beans.

Um, so the other option you have for rendering is also Router, and it's notI should saythis isn't really an either/orboth should be used. So routers are essentially how a Single Page Apps kind of guide what content should be loaded where.

So there are some router plugins that then provide actual URIs or URLs on so that there are unique locations, uniquelike I saidURIs where that content can be accessed. So React uses React Router v4. Pretty much any React project that you haveand if they don't have that, what are they doing? I don't know.

And it also can be used with Redux, which is a state managementwe're not really going to get into that, but just know Redux is a pretty popular thing that you may run into. And you can tell if it's there by using Wappalyzer.

Angular, as I said, Angular Universalso this actually provides that same kind of routing, and "creating URL" functionality. And then in Vue, if it's a newer version of Vue, then you can use History mode instead of Hash mode. And the way to know whether it's using hash or history mode is: first you look at the view version, and if it's greater than two, then it has this configuration option. But basically, when you're changing the content that you're looking at, if you're seeing that there is a parameter changing, or basically you just have the pound sign with the content, that's what changes, then it's in hash mode. If you from that point, it just needs to be put in history mode, and then URLs will automatically be generated.

If it's an older version, so any of the onesone dotsyou can use a plug in called Vue Router. So one of the really nice things about Wappalyzer is it will tell you which version of Vue or Angular is being used.

Slide #1 Text: 

  • Pre-rendering, React:, react-snap
  • Pre-rendering, Angular: prerender,io, Angular Universal
  • Pre-rendering, Vue:, prerender webpack, Vue CLI
  • Server-side, React: Node, next,js
  • Server-side, Angular: Angular Universal
  • Server-side, Vue: nuxt.js
  • Dynamic, React:, rendertron
  • Dynamic, Angular:, rendertron
  • Dynamic, Vue:, rendertron
  • Isomorphic, React: react-isomorphic-render
  • Isomorphic, Angular: Angular Universal (2)
  • Isomorphic, Vue: Uses SSR
  • Static Site Generator, React: Gatsby, Hugo, Jekyll
  • Static Site Generator, Angular: Scully
  • Static Site Generator, Vue: VuePress, Gridsome

Slide #2 Text: 

Routers are plugins for JS libraries that help with the URI/URL creation and overall user pathing

React: React Router v4 plugin, Redux

Angular: Angular Universal

Vue: Use “History” mode instead of “Hash” mode when configuring the app, Vue Router

Possible Culprit: No XML Sitemap

JS SEO Issue: No XML Sitemap

Video Transcript: 
Another reason why sections of your site may not be getting crawled is because there's no XML sitemap. So thankfully, for all of these, whether it's React, Angular, Vue, or Gatsby, there are plugins to produce XML sitemaps. Now, sometimes there may be a lot of customization that needs to be doneat that point, you're just going to have to document and work with your developers.

So documentation! Documentation all the time! Um, and then these are the sitemap plugins that I recommend and have used, so I can vouch for their functionality. And also, we're going to talk a little bit later about some of the problems. But basically, whenever a query is run to pull the proper content, you do want the query to filter the content, and not the module that's been rendering how it looks.

And we're gonna talk a lot more about that. So if it doesn't make sense yetit's okay. So those are the three things that could be happening when it comes to sections of your site aren't being crawled and indexed. Remember, that was (1) you're not linking properly, (2) you have rendering or router issues, or (3) there's no XML sitemap.

Slide Text: 

Possible Culprit: No XML Sitemap

Thankfully, plugins exist for each of the major frameworks to automatically create an XML sitemap.
Customizations regarding sitemap exclusions, generating multiple for larger sitemaps, etc. will require some customization from the developers.

  • React & Gatsby: react-router-sitemap
  • Angular: sitemapper-for-js
  • Vue: vue-cli-plugin-sitemap, vue-router-sitemap

JS SEO Issue #3: My Content's being crawled, and images show in GSC Inspect, but why aren't my images indexed?

Let's see if we can do this in less than 1,000 words.

Possible Culprit: Images are in CSS

JS SEO Solution: Images are in CSS, so they can't be indexed

Video Transcript (22:33): 

Okay, so content is being crawled, your images show up on the page when you're looking at it, but your images aren't being indexed. Alright. So the first thing could be and this would be true for any site, not just JavaScript sites. But if your images are being served in the CSS, instead of HTML, they're not going to get indexed. So also note that can be a great thing to have in your tool belt on the other side, because maybe you just have these backgrounds, or these button gradients that you don't want to be indexed:  put them in the CSS, you don't have to worry about that!

Um, there's also documentation. So again, I pulled this from Google's documentation, there's a link to it, um, so that you can see how all of that works. Um, yeah, that one's pretty easy.

Slide Text: 

Possible Culprit: Images are in CSS
It's likely that images are being served in CSS, rather than in HTML

  • Good: <img src="puppy.jpg" alt="a golden retriever puppy" />
  • Bad: <div style="background-image:url(puppy.jpg)">A golden retriever puppy</div>

Solution? Provide documentation. Here's Google's.

JS SEO Issue #4: But My Images Aren't Showing At All!

Don't worry fam, I got you.

Video Transcript (23:26): 

Um, so the next one, all right: but your images aren't showing it all! So remember, the last one was "if you're seeing your images show up when you're looking in GSC Inspect", and this is your images AREN'T showing in the rendering at all. So first off, you need to make sure that you are not blocking crawlers to your asset folders. This is something that's pretty common with JavaScript frameworksis that there will inherently be some measures taken to reduce the number of requests on assets so that you don't get pinged by nonsensical traffic, or people trying to overload your server. So you just have to make sure that your folder where the assets are stored has the permissions to allow crawlers. The way you can do this is test it in GSC. It will probably tell you whether it can grab it or notyou're gonna have to check your robots. txt and your redirect rules.

Possible Culprit: Blocking Crawlers

JS SEO Solution: Stop blocking crawlers

Video Transcript: 

So are you redirecting that request to the assets folder? That is pretty common. You couldand that would be something where you're redirecting really just other agents than your own is essentially: if your code is making a request, then it's allowed because it's coming from internal. Otherif it's coming from external, then it won't let it render. So that's pretty common. You also have to look at your security protocols and headers, and that one gets pretty advanced and even some of it is out of my own purview. I Google a lot with that. So don't be afraid to Google. Questions on that?

Speaker 3  25:04  
I do have a question. Although it's not really related to necessarily only JavaScript-rich websites, but I have been seeing an issue in Search Console, when you check a website. Actually, we have this problem. So on each first hit, it tells me that it cannot "access any resource". So anything on our CDN, for example, so it cannot access. Not everything is on our CDN, but it cannot access CSS files, JavaScript files, you know. And then when I check it again, everything's fair with Search Console. So and then when I check again, it doesn't show again, so you know, so on each, first and third and fifth hit, I get this problem. Whereas it doesn't seem that Google has any problem with our sites at all. I don't have that issue in crawling at all. Because I was at first suspecting we have a problem with caching, we use CloudFlare. But thatit doesn't seem to be a problem. So I was wondering if you had seen this in the past? Happening anywhere, because it's really annoying, because that way, I never know, can I? How much can I rely on what Search Console says about my pages? And why is that happening?

Sam Torres  26:24  
Yeah. Um, so I've not seen that. I wouldmy first thought definitely went to caching as well. Um, I also would wonder about security headers.

Speaker 3  26:37  
Yeah, I checked them, but they look okay. So it's really weird.

Sam Torres  26:49  
I wonderit's in the server configuration and whitelisting. That might be something to check out as well.

Speaker 3  26:58  
Okay, yeah.

Sam Torres  27:03  
Because I've definitely seen security measures where it's like, it doesn't take the first time it recognizes an IP address, but it'll take it the second timeto try to help avoid DDoS attacks.

Speaker 3  27:17  
Yes, we do have measures like that in place, although this problem existed even before we had those measures.

Sam Torres  27:23  
Well, that isCloudFlare has some of that too?

Speaker 3  27:26  
Yes, exactly, exactly. And before we started using thatwe already had that issue. So it did not increase as an issue after we started using protection against DDoS attacks. And the weird thing isso at first, I thought it's a caching problem, because when the first hit, you don't get thisthe resources and you get them on the second hit. But then, on the third hit, you don't get the resources again. So that's just utterly weird.

Sam Torres  27:53  
Okay, um,

Speaker 3  27:57  
But then it should have been cached. So I collect this.

Sam Torres  28:02  
Yeah, that. So it definitely sounds like a server response issue. So, um, let me ask my husband about that. He used to be a server infrastructure engineer. So let me see if he has any ideas where that can happen.

Speaker 3  28:21  
Okay, thank you.

Sam Torres  28:22  
Yeah. Having him as a husband is awesome, like cheatingat life!

Speaker 3  28:28  
I imagine!

Sam Torres  28:31  
Yeah, I know, he's a full stack developer. So just all of the things, he answers all of my questions. Um, okay. But great question. If you do find an answer, let us know. And then like I said, I'll update after I talk to Arthur. And we can try to continue diagnosing from there because that's, that's very interesting.

Speaker 3  28:47  
I will. I will I have been trying to because we have had this issue for a year, maybe. And I've been trying to get the developers on it. But it was always likeprioritized away.

Sam Torres  28:59  
Because we broke it to them.

Speaker 3  29:02  
Soexactly. Because they say it seems that this is a Search Console issue. And someone claimed that it's also something an issue that someone else outside of our company is seen as well, but I have never heard of anyone having a problem.

Sam Torres  29:17  
Yeah, that's a new one for me. Oh, yeah.

Speaker 3  29:22  
I feel suspicious. I still think it deserves looking into.

Sam Torres  29:25  
I think so because it also means butyou know, how muchso not getting a response the first time, it could mean that you're not getting that content isn't getting crawled as often as it warrants being crawled?

Speaker 3  29:38  
Yeah. Exactly.

Sam Torres  29:38  
Um, so, for sure, it could be effects. I would think it's definitely making an effect on the budget and efficiency of that budget. So yeah.

Speaker 3  29:51  
Thank you. Awesome.

Slide Text: 

Possible Culprit: Blocking Crawlers

  • Check that the folder where your images are stored are not actively blocking crawlers
  • Solution? Test asset URLs in the GSC Inspect Tool. Check your robots.txt, redirect rules, and security protocols.

JS SEO Issue #5: My Metadata Is Missing?

Well, that won't do at all.

Video Transcript (29:55): 

Sam Torres  29:55  
Oh, let's see. Okay. Um, so metadata for pages are missing! So page titles, meta descriptions, robots, directives canonicals. All of that, which really is really about 70% of the issues I run into with JavaScript frameworks. It just means somebody put in the plugin in, and it's not configured properly.

So all of the JavaScript frameworks have these plugins for supporting SEO. Unfortunately, this is also one of those cases where really, you just have to go to your developer, there's nothing that really YOU can do as an SEO, because obviously, something is wrong with the code.

Possible Culprit: No SEO/Metadata Vehicle

JS SEO Issue: No SEO/Metadata Vehicle

Video Transcript: 

So the first thing to do is confirm that the SEO plugin is there, and I have a list of the recommended ones in a second. And then creating documentation for how each tag should be rendered. What type offor each type of content that exists on your site. So think of all the different post types, whether it's a page or a blog post, or a resource, or like a teamperson, whatever, all of that you're going to have to create all of that. And then the most important part is also mapping to wherever that content is housedor, so your CMSwhat field in the CMS should match to that? It's really painful to write the first time. I know, I've done it. But I will also say, once you write it the first time, you never have to write it again, you just have to make changes as you work on different frameworks or different types of websites, different companies to match obviously, their types of content, but you'll never have to write again, like this is what a title tag should look like. This is where it should go, it should be appended with the brandyou know, all of that good stuff, you never have to do it again.

And then that is also something that I sayregardless of where you are, always take it with you, that is your IP. Yeah, just keep a copy in your own personal Dropbox or Google Drive, or whatever you havetake it with you. Unless, of course, you have contracts that are supposed to say you can't then don't, because I don't want anybody to get legally in trouble. But it's all in your brain. So according to IP law, if you could write it again, you can take it with you.

Um, so if there is no plugin, the plugins that are recommended for each of theseHelmet for React. I'm going to be perfectly honest with the functionality that Helmet brings to React apps: if your developer does not have Helmet installed, and I were the engineering manager, I would fire that developer. Helmet is too useful, it should ALWAYS be used. That might be very close-minded, and maybe there are things I don't understand. But from everything I know, everybody uses it, you're kind of missing the boat if you don't.

Angular, again, it's an Angular Universal. So you're pretty much always going to have that in every Angular app as well. And then in Vue, there are a few different ones out there, the most used and most recommended one, and the one I've used is Vue-meta. Now, when talking about these, this is also a great time to start talking to your developers about how to implement structured data that would actually scale with the post types on.

So I haven't done that with Angular and Vue, but I've done that quite a few times with React, and also with Gatsbyas far as being able to just kind of "tie down" that functionality within Helmet. It's really easy, there are a ton of articles out there on how to do it that you can send to your developer, and it just makes life that much easier. it renders the JSON in the page, so that you can get that structured data yumminess just already baked in.

Slide #1 Text:

Possible Culprit: No SEO/Metadata Vehicle

  • For popular JS frameworks, the component for creating meta data with pages is usually done through a plugin.
  • Solution? Ask your developers or confirm that the SEO plugin appropriate for the framework is in place. Add documentation for how each tag should be rendered on each type of content, plus what field(s) in the CMS maps to that information.
  • I know documentation is painful to write, but it will save you so many hours of rework and frustration. Plus, it’ll score some big points with your dev team as it will remove guesswork for them. Bonus: write it once and take it with you from job to job.

Slide #2 Additional Text: 

  • React & Gatsby: Helmet
  • Angular: Angular Universal
  • Vue: Vue-meta
  • This is also a great time to talk to your developers about implementing structured data at scale!

JS SEO Issue #6: My React Site Is Using The Default 404 Page!

She doesn't even go here.

Video Transcript (33:47): 

Alright, now we're gonna go into some of the more framework-specific. And then just: a complete disclaimerwhen it comes to coding my own projects. I am a React developer. I can muddle my way through Angular and Vue, but React is definitely my chosen stack. So I have a lot more experience in those. So as we go into the specifics, you'll see it's basically just React and Gatsby. That's because that's what I use. It's what I recommend when clients are wanting to build things. So that's, that's what I like. So the React site is using a Default 404 page. So you're seeing that horribly ugly page. We've all seen it, where it's the red text, and a gray box at the top.

Possible Culprit: Missing Config Files

JS SEO Issue: Missing Config Files

Video Transcript: 

There's a missing config file in your React app. If you're using the React-Router-4, which of course we recommended earlierto use that for creating the URIs and URLs that you want, so that there are specific, or very depicted locations, for content. You just need to check with your developers that they've created a RouteJS and ServerJS file. Make sure that there is code in there, and for the design of a 404 pagethat's where it needs to go. It's really considered not best practice to go ahead and try to use like a page template, you should actually have like a separate file for the 404 page.

Also, I found that this works extremely well, whenever developers are not getting me an answer on this one, I then asked for read only access to the Git repo, so I can just look at it myself, and then all of a sudden, I "magically" have an answer. So just know, developers tend to not want anybody looking at stuff. WhyI'm not really sure, but there you go.

So like I said, those are the 2 files that you need to make sure on those exist, and then also that the design for the 404 page lives there.  I should say that can apply to both React and Gatsbyso it's not just react, it would also happen in a Gatsby site.

Learn how to fix 404 page issues on SPAs for SEO.

Slide Text: 

Possible Culprit: Missing Config Files

  • If your React site is using react-router-4 (and it should), then there are a couple files that need to be included to render a nice-looking 404 page.
  • Solution? Check with your developers that they’ve created a route.js and server.js file. This is where any design should be added.

JS SEO Issue #7: Why Aren't My Canonical Tags Properly Working on my Gatsby Site?

If working with Gatsby, expect this to crash the party.

Video Transcript (35:55): 

Um, so with Gatsby, if you look at if you do Wappalyzer and find that you're working with a Gatsby site, pretty much count onthere's going to be an issue with canonical tags, probably every Gatsby site that I've come intoafter the fact, they were never working, right.

Possible Culprit: Plugin Dependency

JS SEO Issue: Pluginin Dependency

Video Transcript: 

So chances are, it's because the developers are like, Oh, we need to have canonical tags, and they use this canonical plugin called "Gatsby Plugin Canonical URLs." Everything sounds great, right? Except not, becausethat plugin actually builds a canonical on every content piece and it's always self-referencing. So if you actually need canonical tags for the uses of itof preventing duplicate content, then it actually needs to be hard coded.

This is another great extension for adding to Helmet. There's an article written by another developer who wrote up how to do this far more eloquently than I ever could. So that's linked here. So it's super easy to implement, it is something that should be done custom when it comes to React, because that plugin is just not reliable. And then just make sure that whatever CMS you're using with it, that you actually have a place where you can declare that canonical.

Also, I'd recommendunless you like doing really mundane, monotonous thingsplace a fallback for the developers that it would just use the default self referencing, if nothing is there. So if the value is null, or empty in the CMS, it would just reference to itself. So it's just just an idea.

Slide Text: 

Possible Culprit: Plugin Dependency

Many developers just install gatsby-plugin-canonical-urls for handling canonicals. Unfortunately this ALWAYS builds with each URL self-referencing.
Solution? The developer will need to hardcode the canonical tag into the template header. There’s even the code that they can use to do that. Make sure they properly connect it to whatever field you have in the CMS for setting the canonical.

JS SEO Issue #8: I've Got Orphaned Pages That Shouldn't Exist On Gatsby!

It's all scientific, I read it in a book.

Possible Culprit: The Build Folder

JS SEO Issue: For Gatsby, the Build Folder

Video Transcript (37:42): 

Um, so another Gatsby thing, I've got orphaned pages, pages that shouldn't be live, what's happening? So there's a few different thingsfirst off Gatsby, so if you remember static site generators, what they do is they actually go through and render the site as if someone were going through it making all those requests. So while it's doing that, while it's going through the build process, it creates a "build folder." Now there is a build folder for every time it's done. So what you actually see is there's a build folder, and then there's all these sub folders with like 20 character strings, which note when whichwhich build it was, once a build is finished, then that content is taken over to the public HTML file, which is essentially your website, that's accessible by normal users.

So if the build gets interrupted, there will stillthat porting doesn't happen. So there are pages in this build file that never went live, except that folder is still accessible. So you may end up with pages that are like maybedrafts, or, you know, copies of pages that are actually live on your site. But they're orphaned, because there's going to be no links directly to that build version of it. Those would just stay there, and still be crawlable. Less than ideal! Because if it got interrupted, you're going to have to run the build again.

And then you also need to go ahead and have the build folders kind of cleaned up every now and thenlike a routine task. I actually set all of mine up to do a chron job on the server, to clean those up every day. That's something that should be relatively easy for your developers to implement. There could also bemaybe the site gets built, and so you have all the files in the build folderthey get placed over to the public HTML, maybe you're saying that draft content or content that shouldn't be posted yet should be publishedis gettingis live!

So an example of this would be likemaybe you have a blog post that's in Draft. And so when you look at the blog rollor the blog indexthat post doesn't show up there. But you can still actually access that blog detail page. Well, probably what's happening here, and I referenced this earlier, is that upon the build, everything's getting built, and only some of the content is moving over to the public HTML.

So your developer may have built some rules between the build folder and the public HTML portthat some of the content shouldn't be moved over to public HTML. So that's why you could have these "in draft" posts that are renderingknow you, the build process actually made them, but they don't actually get posted as "live". So what's happening there is your developer shouldcould add the Gatsby-plugin-exclude. And essentially what that does is that moves it toinstead of building it, and then not moving it over to the portGatsby is just never going to build it. So that's much more important. The Gatsby-plugin-exclude, you can set up all kinds of rules. So is it based on status? Is it based on URL? Yeah, just lots of different qualifications that you can have of why content shouldn't be built.

So that plugin makes it really easy, and prevents kind of all those random pages just showing up thatyou will pull your hair out until you figure out what's wrong. And I know that one from personal experience with my own website.

Slide Text: 

Possible Culprit: The Build Folder

When given the command to “build” the site, Gatsby creates them all within a /build folder within the app. These are then ported over to the public_html folder upon build completion.

If a build gets interrupted, or there are limitations on what goes into the public_html folder, then files can end up left in the build folder.

Solution? If a build got interrupted, it just needs to be run again. If it’s the latter, ask your developers to add the gatsby-plugin-exclude so that those files are never even built.

Possible Culprit: The Src/Pages Folder

JS SEO Issue: On Gatscy, the Srcpages folder

Video Transcript: 

I thinkOh, no, we got one more. Okay, so the SRC/pages folder. So in every Gatsby project, there is a SRC/pages folder. That is just natural to the folder structure when a Gatsby app is created. So if the project hasn't gone through cleanup, or the developers haven't refactored the code to make sure it's as elegant as possible, that folder could still end up existingwhich means pages that are in it, are still rendering. So you just want to make sure that that's been cleaned up. Again, if they're not really giving you a response, just ask if you can have Read access to the repo, so you can go diagnose yourself, um, and then all of a sudden, you'll beyou'll get really helpful answers.

So anything that's in there, you probably just want it to be deleted. So that's some Gatsby specific fun. If anybody ever wants to talk about Gatsby, I love it. I think it's awesome. I think they're an awesome company, highly recommend.

Slide Text: 

Possible Culprit: The Src/Pages Folder

In every Gatsby project, there exists a src/pages folder. If the project hasn’t gone through re-factoring or clean up, there could still be files in that folder that are causing them to be rendered even though they shouldn’t be.

Solution? Talk with your developer about what’s in those folders. If you have read access to the repo, you should be able to locate those yourself. Anything that’s in the folder that shouldn’t be, just ask for it to be deleted.

Possible Culprit: Draft Mode and GraphQL

JS SEO Issue: On Gatsby, Draft Mode & GraphQL

Video Transcript: 

Alright, the last thing could beit's happening on the query. So whenso Gatsby uses a query language called GraphQL. You've heard of query languages before, the most popular one is SQL, or SQL. So GraphQL is a new one, and basically, this is how the data is pulled from the CMS and populated into the static HTML files. Often times developers like to build their query to pull everything. But then when it comes to the module that's actually rendering the content, we'll put the filters there. The solution is that you should actually be putting the filter on the query itself, and not on the Rendering module. Not when it's mounted. So, um, that is a big one. And there's also a lot of resources.

So if you're ever in a situation; you're getting a lot of pushback from your developersI have a library of resources available, saying that doing it at the query level is best practice. Mostly because you reduce the server response, and so anybody who's Head of Engineering that hears "less stress on your server," is pretty much always gonna say yes, because that's always a win.

Slide Text: 

Possible Culprit: Draft Mode and GraphQL

Gatsby uses a query language called GraphQL to interact with your CMS/database and populate the dynamic data into static HTML files.

Developers often pull ALL of the content entries, and then use the rendering components to filter what should be live and what shouldn’t. Unfortunately, this means that Gatsby will build the page for a dedicated resource.

Solution? Ask your developer to adjust the query to filter then, and not at build/render time.

Example: a blog post URL is being created and rendered, but the blog post is NOT showing on the blog index page.

The JavaScript SEO Toolset

The JS SEO Toolset List

Video Transcript: 

So those are the major questions and problems that I found. This has my tool set what I use, so of course, Wappalyzer, that we talked about quite a bit. There's also a plugin calledextension for Chromecalled HTTP Headers, which actually shows you all of the requests, and responses, and their codes.

And then if you noticed consistently, thethe solutions for this for these problems is that you have to create documentation, and work with your developers. So I linked thisthat is the Google SEO Developer Guidelines. It's their own documentationuse it as much as you want, there's no need to rework the work that they've already done.

Slide Text: 

Example JavaScript Sites by Platform

Sample JavaScript sites for React, Gatsby, Vue, and Angular

Video Transcript: 

And then here, I have some sample sites for each of the frameworks, just in case you ever want to see it.

Slide Text: 


So let's for the last two minutes, I'll show you guys. Let's see, just like using Wappalyzereverybody good with that? Cool.


So I'm going to look in here for myokay, so like, everybody's favorite topic right now. So if I pull this on Wappalyzerthis is what it looks like. You can see it's Gatsby. It's using React for the JavaScript library. It's got another JavaScript framework called Emotion. So you can kind of justalready see everything that's in there. Um, let's see, what's another fun one. Airbnb uses React.

Speaker 3  46:10  
Interesting. It looks like it looks different from when I use Wappalyzer. But you're on a Mac, right?

Sam Torres  46:17  
I am.

Speaker 3  46:18  
Okay, because what I see is quite different. Like they have a specific area for HTchecking for HTML issues as wellHTML5 issues as well, and accessibility and quite interesting.

Sam Torres  46:31  
Dude, that sounds awesome.

Speaker 3  46:33  
It is awesome. It is even better, I would say.

Sam Torres  46:37  
I feel...  gypped. I feel gypped right now. Yes, you can see there's React. They think there might be Ruby on Rails on the backend and can confirm. I'mwhich Ruby on Railsjust everybody knowsis a backend language. You can use some front end, but you wouldn'twouldn't normally. But I imagine that all of this "holding the inventory" of available at Airbnbthat's all using Ruby.

So do you guys remember when I said that Google uses Angular and actually, like, helped create Angular. So really funny to me, that their Google Careers {site} actually uses Vue. So with it being likewhich React was something that Facebook developed. Angular was developed by Google and their parties, so it really cracks me up whenever I find Google properties that are using React or Vue instead of Angularso I'm likewho pissed this person off, right?

Now, I also imagine it usually comes from acquisitions for them. So maybe they acquired the technology that they use for their Careers and just haven't changed it yet. But I stillI get a nice little chuckle out of that. It's likeyou're not using your own product, why should I?

Alright, so we are at time, but any other questions from that presentation? Also feedbackif you thought it was horrible, and a waste of your life? I will make it accessible to everybody in the Women in Tech SEO {group} as well as this recording. So, got any questions or comments?

Thanks again for joining us for AHA! JavaScript SEO moments. If you need help, The Gray Dot Company can help bridge gaps with JS SEO by providing flexible solutions that adapt to the ever-changing needs of your team. Reach out today!

My AHA Moments with JS SEO

Work With Us
We’ll help craft, teach, and carry out SEO roadmaps that check all the boxes.