Single-page application (SPA) SEO is hard—not impossible. Read this resource-packed guide to optimize your React, Vue, or Angular app for Google.
Part 1
The best place to hide a body
Have you ever heard of That Awesome SPA Project?
The single-page application passed all unit, integration, and end-to-end tests. It was BEAUTIFUL; loved by designers and developers alike.
Ever heard of it? No?
Me neither.
Know why? Because it ranked on the second page of Google and never drew any business results. 😱
In other words, its developers didn’t know much about SPA SEO (Search Engine Optimization).
Lucky for YOUR awesome SPA project, I know enough about single-page application SEO to make sure your project ranks on Google.
See, in their purest form, SPAs aren’t great for SEO: their client-rendered content isn’t the easiest to crawl.
I don’t care if your edgy developer friend told you Googlebot executes JavaScript like a champ. I’ve read dozens of articles by researchers, developers, and industry insiders. They all have one thing in common:
You should at least use prerendering or server-side rendering to make SPA content easier to discover, understand, and index for search engines.
That’s the gist of it. There are other considerations, though, and this guide will cover most of them:
Fundamental SEO ranking factors (basics)
Issues with single-page application SEO
Best practices for SPA SEO in 2019
Actionable tips and tools for React, Vue, and Angular SEO
SEO is important. For many online businesses, Google isn’t just a search engine; it’s a growth engine.
But optimizing for Google can be hard—especially when lots of JS is involved.
Hard doesn’t mean impossible, though! At Snipcart, we have worked on dozens of tutorials for popular SPA frameworks. Handled the right way, they can all be SEO-friendly JavaScript frameworks.
So let’s jump in and make this whole thing a bit easier.
Disclaimer: this guide focuses on Google SEO, because it has over 92% of the market share. If you want to optimize for Bing, I invite you to google “bing seo.” I’m kidding—most of this advice applies to other search engines as well.
Part 2
Fundamental SEO ranking factors
So what matters in SEO? What makes a website rank?
I won’t be explaining the ins and outs of Google’s indexing algorithm here. I can’t do that—and frankly, nobody can. It’s closed source, highly complex, updated continuously, and interprets >200 ranking factors.
The good news? Some tried-and-tested simple practices will go a long way in boosting organic traffic.
Before dominating the SERP (Search Engine Results Page) with your SPA, you’ll need to master these SEO basics:
1. Discoverable, quality content 🏅
Before you create the sleekest of single-page applications, remember one thing: content quality is #1 in SEO.
Content quality requires expertise and research—if your client’s industry is alien to you, you can’t help here.
But you can definitely help with content discoverability, i.e. on-site and on-page optimization. Here’s how:
Meta tags
The following meta tags will help search engines better understand your content:
Meta content type—declares your character set for the page.
Viewport—enhances mobile user experience.
Title tag
Include 1 main keyword
Keep it < 70 characters
Differentiate it from competing titles on SERP
Always add your brand at the end ([...] - Your Brand)
Meta description
Include 1-2 main keywords
Keep it < 140 characters
Include a call-to-action to click on the page
Demonstrate you understand the searcher's intent (i.e. people who land on the SERP)
Social tags—increases social shareability of content.
Define at least Open Graph tags (Facebook) and Twitter Cards
Protips
Target keywords should appear in Title tag, URL, H1, and, with moderation, page content.
Image titles and ALT tags should be descriptively named.
Sitemap should always be defined—the XML sitemap helps search bots understand and index your site.
Further reading
2. Security (HTTPS) 🔒
You know that little lock before URLs? You’ll need it.
A valid SSL certificate—and thus a HTTPs connection—will show both users and Googlebot you care about fighting off evil hackers.
Election-meddling Russian cyber-terrorists aside, here’s another good reason to enable SSL on your site:
This screenshot, taken in Chrome, shows an explicit “Not Secure” label besides this non-SSL website. Now I don’t know about you, but it sure doesn’t feel SAFE to visit Florida.
Don’t be like Florida. Don’t scare off users. Be secure.
Plus, Let’s Encrypt and Cloudflare let you do it for free.
Further reading
3. Mobile optimization 📱
High at the top of “SEO things to keep in mind in 2019” is:
Google uses mobile-first indexing.
Old school desktop Googlebot won’t be the first knocking at your new SPA’s door. Smartphone Googlebot will!
If you have an existing SPA, you can go to Google Search Console settings to see when your indexing crawler switched to mobile.
It’ll evaluate both usability (font size, buttons spacing, responsivity) and performance.
Single-page applications are notorious for their “less downloaded content” advantage. However, be aware that your mileage may vary on mobile connections. A further section will address mobile performance for SPA.
Further reading
4. Performance & user engagement 🏎
Gone are the glory days of backlinks as the #1 SEO ranking factor.
Today’s Google Search algorithm is way more dynamic.
It weighs user-centric factors more than ever. Website speed and user engagement signals are the two big ones here.
Performance
Our collective attention span is shortening by the day. Online searchers are quick to abandon sites and carts.
Google wants to please its users, and slow-loading pages aren’t pleasing at all. They might even get your site penalized, or downranked.
Consider Googlebot’s impatience: the crawler typically won’t wait longer than 5 seconds for a script to execute. Miss that timeout, and you’ll risk content rendering and indexing issues.
Fear not though! Modern development practices for performant, SEO-friendly SPA abound—and they’re all described in a further section.
User engagement
Google now adapts to user-level signals. It often reorganizes SERP rankings by listening to:
Time on page, pages/session
Back-and-forth between results & SERP (frequency + speed)
Click-through rates on SERP
Social signals
Freshness + popularity factors
Tweets/RT, shares, comments, posts
Google has become incredibly adept at tracking user engagement to ensure its users are getting the results they’re looking for the first time around.
Further reading
5. Authority (backlinks & trust score) 🔗
In the ’90s, backlinks were measured in a “one link = one vote” fashion by Google. A very democratic—and gameable—ranking process.
That’s why, nowadays, you’ll find that artificial, spammy link building tactics lead to severe penalties. Sites disappear from Google Search, along with their organic traffic, when they rely on getting their authority from untrustworthy links.
Still though, building your site authority the right way remains a key strategy in SEO. You can do this by obtaining natural, relevant, topical backlinks from thematically-relevant and trusted websites. The most popular way to do that? Creating valuable content other sites will use as resources (and link to) on their pages.
Some authority factors that’ll influence your Google rankings:
Quality + number of linking domains/pages
Trust Flow (or Trust Score)
Simply put: what’s your link proximity to high-authority sites?
Media, governments, academia, official directories
Further reading
Part 3
Issues with single-page application SEO
What’s a SPA?
A Single-Page Application (SPA) is a web application relying on JavaScript to dynamically add content to pages users visit. A SPA typically downloads all of a site’s required code in one single page load—thus increasing perceived performance for end-users. UX-wise, it resembles an in-browser desktop application: no successive, lengthy page loads during navigation.
SPAs are increasingly present in web development. They’re fast, fun to build, and flexible. Plus, they’re easy to transform into Progressive Web Applications (PWA) too!
Why is SPA SEO difficult?
Single-page applications have a few drawbacks.
They are, after all, full of JavaScript, AKA the infamous double-edged sword of web development. And some developers are… bad at writing JS.
Some users even disable JS in browsers. Accessibility, too, can be tricky.
Here however, I’ll focus on the SEO drawbacks. I’ll assume you have pages that actually need to rank on Google. In other words, that some important parts of your SPA aren’t safely hidden behind a login.
Client-rendered content
Client-side rendering SEO is tricky.
See, by default, a SPA serves an empty container to the browser. Let’s take a basic example: this Emoji Search single-page app, from the official React documentation Examples.
→ https://ahfarmer.github.io/emoji-search/
If you View Page Source in Chrome, this is what you’ll get:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="manifest" href="/emoji-search/manifest.json">
<link rel="shortcut icon" href="/emoji-search/favicon.ico">
<title>Emoji Search</title>
<link href="/emoji-search/static/css/main.2e862781.css" rel="stylesheet">
</head>
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div><a class="github-fork-ribbon" href="https://github.com/ahfarmer/emoji-search"
title="Fork me on GitHub">Fork me on GitHub</a>
<script type="text/javascript" src="/emoji-search/static/js/main.d4350923.js"></script>
</body>
</html>
And that’s it. No actual content—just the container.
In a SPA, it’s JavaScript that adds content to this browser container.
More often than not, an AJAX call will request page content from the server:
If you use inspect element on that same React app, you’ll see the current state of the DOM:
See? The content is all there, thanks to our SPA.
But Googlebot, as you may have started to suspect, sees the first version of our two examples. Empty container, no content. A simplified heuristic here:
→ Synchronous content = crawled
→ Asynchronous content = not crawled
That crawler, while it requires the same URL you’re serving to users, is not a regular, browser-visiting user. You need to make sure it can access the content on pages you want to position on the SERP.
Wait, I thought Google started crawling JavaScript?
We’ve been hearing this since 2014.
Still, all the best-ranked articles on JavaScript SEO (see what I did there) recommend NOT relying on Googlebot for JS crawling.
It’s been proven that crawl budgets—Googlebot’s # of crawled/indexed pages for a given period—are not the same for HTML as they are for JS-rich sites. The latter, which are more resource-intensive and require executing strips, tend to have lower crawl budgets. This can lead to discoverability issues on the SERP.
So don’t assume that Googlebot will crawl your asynchronous content, or that it will do it well. Yes, even if they updated it to support Chrome 74. Optimize for bot crawlability anyway (this next section shows you how).
Consider this like buying insurance. For SEO.
Okay. End of analogy.
URL and routing
An intuitive, descriptive URL and content architecture helps with SEO.
Out-of-the-box, simple single-page apps do away with browser <> server navigation. Meaning the developer must carefully manage URLs. That’s you.
Thankfully, lots of libraries and tools linked to in upcoming sections will help you do that.
Mobile web performance
Lightweight single-page applications with minimal “downloaded content” still operate in the real world. And in the real world, most cellular connections are high latency.
Latency can be a pain in the butt, but the next section teaches you how to shield your SPA from it as much as possible. Spoiler alert: C - D - N.
Part 4
Best practices for SPA SEO
Now that you know about single-page applications’ potential drawbacks, you should be asking:
"What are the best practices for SPA SEO?"
As Alexis Sanders explains, you want to optimize your SPA for:
Crawlability
Can I find all of your URLs and navigate smoothly throughout your site’s architecture?
Googlebot
Obtainability
Can I access your content without executing slow JavaScript and user-specific interactions?
Googlebot
Perceived site latency
Can I display above-the-fold content to users rapidly enough?
Googlebot
The following sections will address these concerns:
1 - Server-side rendering
2 - Prerendering
3 - Performance/mobile optimization
4 - SEO-friendly URLs
5 - Testing SPA SEO
Your first goal is to get that content-rich DOM state you saw earlier, but directly on page load. That’s how you make sure Googlebot sees something as close to what the user’s seeing. Then, it becomes a question of when to serve the content.
The two most effective ways to render Google-friendly versions of SPA are server-side rendering and prerendering.
If you have never heard these terms, we break both of them down in this YouTube video:
1. Server-side rendering
Server-side rendering (SSR) is a way to offload rendering logic to a live backend. Your SPA executes a request to a Node.js web server; the latter returns a fully rendered HTML view to the client.
Psst! If you don’t know what Node.js is, no worries: read this.
By using SSR, you remove the need for Googlebot to run frontend JavaScript code. It makes for faster build times of your app. But SRR ain’t all sunshine and roses:
It’s relatively complex and requires more development time (than prerendering).
It puts more stress on your server—slower responses might ensue.
It forces your code into a universal (isomorphic) JavaScript app since it must work seamlessly with your JS framework AND Node.js.
The React, Vue, and Angular sections further down all feature tools and tutorials on handling SSR with JavaScript frameworks.
2. Prerendering
Prerendering is a way to handle rendering logic pre-deployment. It discriminates between real users and search crawlers. Your SPA runs with a headless browser and generates a “Googlebot-ready,” fully rendered HTML version of your app. That version is stored on your web server.
When a request hits it, the server checks if it’s coming from a real user (A) or Googlebot (B):
A - Serves your SPA straight up B - Serves the prerendered static files
Prerender.io is a popular tool to do just that with any JS framework. The same thing goes for the prerender-spa-plugin. Small differences to note: with the former, prerendering happens during run time, with the latter; during build time.
If you want to handle that prerendering logic yourself, you can! Look into Puppeteer and Prerender’s open-source version.
Keep in mind that highly dynamic apps with changing data might not play well with prerendering.
The React, Vue, and Angular sections further down all feature tools and tutorials on handling prerendering with JavaScript frameworks.
3. Performance/mobile optimization
As mentioned earlier, perceived performance is one of the biggest SPA advantages.
Perceived latency, however, isn’t. It happens when Googlebot hits render-blocking JS files and can harm your SPA SEO. Especially if it happens on mobile—remember, mobile-first indexing!
And a slow, incomplete mobile experience will harm your SEO, whether you’re building a single-page application or any other type of website.
For SPA though, a big ol’ JS file is often nested at the top of your HTML. This creates potential bottlenecks to page rendering.
Your goal? Make your code load as fast as possible through the critical rendering path:
Fear not, for there are lots of practical tips to get that above the fold content (and all the remaining content) displaying ASAP:
Use a Content Delivery Network (CDN)
A geographically distributed network of servers will allow for faster file delivery, wherever the request is coming from.
Bundle and minify your code
Smaller asset sizes are always good, whether they’re loaded async or not.
Allow persistent connections
Enable lazy loading for unneeded resources
Ask yourself: do ALL resources need to be loaded with the initial page load?
When bypassing same-origin policy, handle JSONP + CORS requests carefully
They will often initiate preflight checks that can increase latency.
Minimize reflows
Layout trashing often harms web perf—beware. Keep this in mind when designing frontend transitions, even if your page HTML is prerendered.
When dealing with real-time updates, implement WebSockets.
SSR and prerendering won’t address this issue.
These are all best practices. Granted, they’re on the advanced side of things when it comes to SPA. Nailing SSR or prerendering should be first on your priority list.
If you prefer taking a leaner approach to your SPA optimization, consider doing real user monitoring to identify actual perf bottlenecks. Maksym Churylov wrote a great post on the subject, which also expands technically on much of the advice above.
Helpful web perf resources
4. SEO-friendly URLs
At the dawn of SPA, navigation was done with hashbangs and escaped fragments. It was a mess for developers and search crawlers alike. The routing game has changed.
Today, the general, SEO-friendly method of dealing with SPA URLs is to leverage the History API and the pushState()
method in-browser. It lets you fetch async resources AND update “clean” URLs without fragment identifiers.
→ The MDN Web Docs has a solid entry on the subject.
Popular open-source routing libraries for React, Vue, and Angular all use the pushState()
method under the hood.
Clean URLs will also facilitate link building efforts and organic acquisition of backlinks.
Last but not least: a clean URL architecture will make for a MUCH better time analyzing data in Google Analytics. 👀
5. Testing your SPA SEO
Googlebot is on its way to rendering JavaScript flawlessly. But it’s not there yet. So, as Bitcoiners would advise: don’t trust, verify.
In other words? When in doubt, test that SPA!
Use Google URL inspection tool (f.k.a “Fetch as Google”)
The times they are a-changin’.
You can now find the Google URL inspection tool, formerly “Fetch and render as Google,” inside Google Search Console, formerly “Google Webmaster Tools.”
This nifty tool is a good starting point to test your SPA. Select “Live test” and punch in a URL from a verified property of yours. The report should tell you:
Is your URL indexable, crawlable?
Is your content mobile-friendly?
What HTML/content is Googlebot seeing?
What resources couldn’t be loaded?
You should also visit the Mobile Usability report in Google Search Console.
Check content quotes on SERP with site:
Traditional SEO advice suggests using your browser’s cache to see how Google indexed your content. By all means, do it, but don’t limit yourself to this technique.
A safer approach is to use the site:
command in Google search, coupled with an excerpt of content that should be indexed in a direct quote. Like so:
If your content is crawled and indexed correctly, it should show up in the search results.
Check the DOM!
Go beyond “view page source” and make sure your SPA content shows up in the DOM.
Track script performance
Make sure your scripts run < 5 seconds. On a regular basis—or better yet, an automated one—run performance audits:
Part 5
JavaScript frameworks SEO tips: React, Vue, Angular
Here’s a little summary of what you’ve learned thus far.
To increase crawlability, obtainability, and performance, your single-page app must be:
Using server-side rendering or prerendering to provide search crawlers with fully rendered HTML content.
Optimized as much as possible for performance, especially on mobile, to decrease perceived latency.
Organized with a clear, clean structure for SEO-friendly URLs.
Tested regularly with SEO and performance monitoring tools.
So how does the above translate to the big three JS frameworks: React, Vue, and Angular?
Here are some tools and guides that will let you optimize your [insert favourite framework] single-page applications for SEO.
React SEO
This React framework lets you streamline server-side rendering of your SPA.
This guide shows you how to handle SSR on React without using a framework like Next.js.
This guide shows you how to handle prerendering with Create React App and react-snapshot.
This documentation shows you how to use Webpack to bundle your React SPA. SEO-friendly React tools like Gatsby, Next.js and Create React App come with bundling out-of-the-box.
This collection of navigational components helps you manage routing and URLs.
→ For a more practical take on React SEO, check out this Next.js tutorial, which includes steps, an open-source repo, and a live demo.
You can also watch Google’s official video series on JS SEO. More specifically, check out the one with React:
Vue SEO
This Vue framework simplifies server-side rendering of your SPA.
This documentation explains how to handle SSR on Vue without using a framework like Nuxt.js.
This tutorial demonstrates how to handle prerendering with prerender-spa-plugin and Node/Laravel.
This documentation shows you how to use Webpack to bundle your Vue SPA. SEO-friendly Vue tools like Gridsome and Nuxt handle this out-of-the-box.
This is the official router for Vue.js.
→ For a more practical take on Vue SEO, check out this prerender-spa-plugin tutorial, which includes steps, an open-source repo, a live demo, and a video tutorial.
Google’s official Vue SEO video:
Angular SEO
This open-source project extends on the framework’s core APIs to enable easy SSR.
The official documentation to get started with Angular Universal.
This tutorial shows you how to handle prerendering with your SPA.
This tutorial expands on concepts of code-splitting in Angular. The official documentation on bundling is here.
This is the official router documentation for Angular.
→ For a more practical take on Angular SEO, check out this Angular Universal tutorial, which includes steps, an open-source repo, and a live demo.
Google’s official Angular SEO video:
Part 6
Closing thoughts
Do you feel ready to propel your SPA to the top of Google’s first page yet?
No? Don’t worry.
You don’t have to go crazy checklisting every single SEO tip mentioned in this guide.
Just start with SSR or prerendering.
After that, you can still put out a working app, bookmark this guide, and come back to it for iterative fine-tuning sessions!
SPAs are great. They’re fun to build and use.
But they often exist in a business reality where organic search traffic has lots of value. If that’s your case, please, improve SPA SEO. It’ll help keep the single-page app reputation pristine across all professions!
Here’s hoping I stumble upon your single-page apps on the SERP. 😊
A lot of work and love go into crafting these guides. If you liked this one, please, take a second to share it on Twitter. It’d mean a lot!