Improve SEO and share experience in a SPA
By: Fran Lendínez
Tags: SEO, Vue, React, Django Rest Framework, Rest

Nowadays some bots are able to render Single Page Applications (SPA) and manage Javascript-loaded resources but not all of them. It causes some problems on the share experience of users and Search Engine Optimisation (SEO).

Photo by Austin Distel on Unsplash

How a SPA works

A single-page application (SPA) is a web application or website that interacts with the web browser by dynamically rewriting the current web page with new data from the web server, instead of the default method of the browser loading entire new pages. The goal is faster transitions that make the website feel more like a native app. (Wikipedia)

At the moment an user goes to a single page application, it produces the following steps:

Browser makes a GET request over server The server response with HTML, CSS and JS content (the frontend application) This frontend application makes API calls to a server that respond via services This services can manage information of databases, caches, files… The frontend application renders the retrieved information and makes the UI changes needed

Main schema of a single page application

Definition of the problem

The previous schema doesn’t distinct a user or a bot, for that, if a bot doesn’t load the frontend application, it would be never able to recover the information of a specific page and never render meaningful content.

Crawlers that not execute JS follows this schema

This problem makes us get always the same preview when you share the url on whatsapp, facebook, linkedin…

This is an important problem, and that’s why people have created Server Side Rendering alternatives that works with the main frontend frameworks, such as Next.js (React) or Nuxt.js (Vue)

Easy patch for this problem

To manage this problem effectively we must serve different content according to its type.

According to the type of user-agent, we can manage the static preview serving a Fake-HTML

Once we differ users and bots:

We must create an endpoint in our service that uses the same route that the frontend application

This endpoint must serve HTML content

Let’s see an example

Our fake-HTML (using Django templates, but it is agnostic to the backend):

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width,initial-scale=1.0">

<title>{{obj.title}}</title>

<meta property="og:title" content="{{obj.title}}" id="og__title" />

<meta property="og:type" content="website" />

<meta property="og:url" content="https://example.com/app/{{obj.slug}}" id="og__url" />

<meta property="og:image" content="{{obj.image}}" id="og__image" />

<meta name="description" property="og:description" content="{{obj.description}}" id="og__desc" />

</head>

<body>



</body>

</html>

Our view:

def fake_obj_view(request, slug):

obj = get_object_or_404(Obj, slug=slug)

return render(request, 'fake_obj.html', {'obj': obj})

With that we will serve the previous HTML rendered with enough information to improve the share experience.

Our route:

urlpatterns = [

path('api/', include('users.urls')),

...

path('app/<str:slug>/', fake_obj_view, name='fake_obj'),

]

We must reply the front path routes that we want to improve.

Our server configuration (in this example I used Nginx but it could be done easily with Apache):

location ^~ /app/ {

if ($http_user_agent ~* "opengraphcheck|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest\/0\.|pinterestbot|slackbot|vkShare|W3C_Validator|whatsapp") {

proxy_pass http://0.0.0.0:8000;

}

try_files $uri $uri/ index.html =404;

}

This configuration checks the user-agent of the current request and, if it is a crawler, send the request to our service. Doing it, users will always follows the first schema obtaining all the power of a SPA and crawlers will obtain a fake html with enough information to render a preview.

Final note

Some social networks as Linkedin or Facebook have tools to prove it (tool). You can test sending yourself a URL vía Whatsapp, Slack among others.

If you find this article useful, don’t forget to clap it! :D