Slide 1

Slide 1 text

My Aha Moments with JS SEO May 2021

Slide 2

Slide 2 text

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 2

Slide 3

Slide 3 text

Frameworks We’re Discussing... ⊹ Foundational JS ⊹ React × Gatsby ⊹ Angular ⊹ Vue Please know there are dozens more JS frameworks - these are just the ones I’ve most run into (and/or coded myself). 3

Slide 4

Slide 4 text

My Process 4 1 Identify the stack I use a Chrom e extension called W appalyzer 2 Site craw l Using Scream ing Frog or ahrefs w ith the JS rendering, I’ll look for any errors 3 Investigate in GSC Know ing w hether your content is being craw led at all is essential to diagnosing issues

Slide 5

Slide 5 text

Are you seeing that only a portion of your page/content is getting crawled/indexed? We’ve All Been There. 1

Slide 6

Slide 6 text

Possible Culprit: JavaScript Errors 6 If you’re seeing some content in GSC Inspect but not all, you could have a JS error that’s causing it to be unparseable (unreadable). Find these errors by checking the Console in Chrome Dev Tools while on the page in question. Foundational JS React Angular Vue Gatsby

Slide 7

Slide 7 text

Possible Culprit: JavaScript Errors 7 JS is unforgiving, and its error handling leaves much to be desired. Solution? Raise it to the developer. 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. 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. Foundational JS React Angular Vue Gatsby

Slide 8

Slide 8 text

Entire URLs, pages, and even sections of my site aren’t being crawled. Not the Gumdrop Buttons! 2

Slide 9

Slide 9 text

Possible Culprit: Bad Linking Approach 9 ⊹ Links are not properly coded to use an anchor and href ⊹ No industry-standard for developers on how to make links ⊹ Solution? Provide documentation. Here’s Google’s. Foundational JS React Angular Vue Gatsby

Slide 10

Slide 10 text

Possible Culprit: It’s a single page app (SPA) 10 ⊹ 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 Foundational JS React Angular Vue Gatsby 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.

Slide 11

Slide 11 text

Possible Culprit: It’s a single page app (SPA) 11 Foundational JS React Angular Vue Gatsby React Angular Vue Pre-rendering prerender.io react-snap prerender.io Angular Universal prerender.io prerender webpack Vue CLI Server-side Node next.js Angular Universal nuxt.js Dynamic prerender.io rendertron prerender.io rendertron prerender.io rendertron Isomorphic react-isomorphic-render Angular Universal (2) Uses SSR Static Site Generator Gatsby Hugo Jekyll Scully VuePress Gridsome

Slide 12

Slide 12 text

Possible Culprit: It’s a single page app (SPA) 12 ⊹ Routers are plugins for JS libraries that help with the URI/URL creation and overall user pathing. Foundational JS React Angular Vue Gatsby React React Router v4 plugin Redux Angular Angular Universal Vue Use “History” mode instead of “Hash” mode when configuring the app Vue Router

Slide 13

Slide 13 text

Possible Culprit: No XML sitemap 13 ⊹ 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. Foundational JS React Angular Vue Gatsby React & Gatsby react-router-sitemap Angular sitemapper-for-js Vue vue-cli-plugin-sitemap vue-router-sitemap If customization is needed, work with the developer to update the query for creating the sitemap to filter the content then, and not try to remove after the fact.

Slide 14

Slide 14 text

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 a 1,000 words. 3

Slide 15

Slide 15 text

Possible Culprit: Images are in CSS 15 ⊹ It’s likely that images are being served in CSS, rather than in HTML. ⊹ Solution? Provide documentation. Here’s Google’s. Foundational JS React Angular Vue Gatsby

Slide 16

Slide 16 text

But my images aren’t showing at all! Don’t worry fam, I got you. 4

Slide 17

Slide 17 text

Possible Culprit: Blocking Crawlers 17 ⊹ 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. Foundational JS React Angular Vue Gatsby

Slide 18

Slide 18 text

Metadata for my pages are missing. Well that won’t do at all. 5

Slide 19

Slide 19 text

Possible Culprit: No SEO/Metadata Vehicle 19 ⊹ 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. React Angular Vue Gatsby Foundational JS 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 20

Slide 20 text

Possible Culprit: No SEO/Metadata Vehicle 20 React Angular Vue Gatsby Foundational JS 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!

Slide 21

Slide 21 text

My React site is using the default 404 page. She doesn’t even go here. 6

Slide 22

Slide 22 text

Possible Culprit: Missing Config Files 22 ⊹ 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. React Angular Vue Gatsby Foundational JS

Slide 23

Slide 23 text

Why aren’t my canonical tags properly working on my Gatsby site? If working with Gatsby, expect this to crash the party. 7

Slide 24

Slide 24 text

Possible Culprit: Plugin Dependency 24 ⊹ 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. Here’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. React Angular Vue Gatsby Foundational JS

Slide 25

Slide 25 text

I’ve got orphaned pages, pages that shouldn’t even be live - what the heck Gatsby? It’s all scientific, I read it in a book. 8

Slide 26

Slide 26 text

Possible Culprit: The Build Folder 26 ⊹ 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. React Angular Vue Gatsby Foundational JS

Slide 27

Slide 27 text

Possible Culprit: The Src/Pages Folder 27 ⊹ 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. React Angular Vue Gatsby Foundational JS

Slide 28

Slide 28 text

Possible Culprit: Draft Mode and GraphQL 28 ⊹ 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. React Angular Vue Gatsby Foundational JS Example: a blog post URL is being created and rendered, but the blog post is NOT showing on the blog index page.

Slide 29

Slide 29 text

29 My Toolset ⊹ Chrome extension: Wappalyzer ⊹ Google Search Console URL Inspection Tool ⊹ Screaming Frog with JS rendering ⊹ Chrome extension: HTTP Headers ⊹ Google SEO Developer Guidelines

Slide 30

Slide 30 text

Sample Sites 30 React Zagat Discord AirBnB Vue Google Careers LOUIS VUITTON® Nintendo UK Bitcoin Figma National Geographic UK Gatsby JSON Schema Grasshopper US Travel Bureau Angular

Slide 31

Slide 31 text

Thanks! Any questions? You can find me at: ⊹ @samtorresatl 31