Make Vue.js SPA with Laravel SEO friendly

Make Vue.js SPA with Laravel SEO Friendly

Make Vue.js SPA with Laravel SEO Friendly

I have been working on my new startup Triphie, it’s an interactive and collaborative trip planner that helps you and your friends plan your dream trips in a very smooth and convenient way. I used Laravel and Vuejs SPA for that, and one of the challenges I’ve faced is how to make my website SEO friendly.

If you have ever tried to build a website using Single page application using Vuejs and Larave, then you might already know that making it SEO-friendly is one of the challenges that you might encounter.

So how can you overcome this challenge and make your website SEO friendly?

First, let’s discuss how your website can be SEO friendly and then discuss the downfalls that Vuejs has regarding this,


How do Search engines rank your website?

Search engines crawl your website and try to understand its content, then they will index it so that if any user later searches for any keyword in the search engine they will match your website content to that keyword.

That means to get your website indexed, search engines should be able to crawl your website links and parse its content.

One more thing that helps your website to be ranked and viewed by search engines and social media are meta tags, they have title, description, and image, that are responsible for how your links will be viewed when it appears on search results or on the newsfeed of Facebook and Twitter.

This is an example of one of the links to our blog posts on Triphie

How links with meta tags appear on Facebook newsfeed
How links with meta tags appear on the Facebook newsfeed

What downfalls Vuejs has when it comes to SEO?

We all know that Vuejs is a JavaScript framework, and it is a client-side rendering framework, that means you when open any link of your website the page content will not be visible until the page is being loaded by the browser, so in most cases, search engines will not be able to fetch your page content, thus it will not be able to index it.

So how we overcome this?

Most search engines (like Google) now have some ways to run JavaScript and also it will index your page content. However this is not everything, social media platforms like Facebook and Twitter still can’t run JavaScript, hence your website links will not get parsed and viewed correctly, that because your website meta tags are not visible in your page content. 🙁

To solve this you can use libraries like vue-meta where you will be able to define your meta tags for each page separately, yet we still have the issue of the page isn’t being rendered on the server side.

Then shall you stop using Vuejs?

No not yet, there are some ways to solve this issue, one of them is server-side rendering, which will render your page content before it’s sent to the client.

I can hear you thinking then why we used vuejs in the first place if we want to render it on the server side?

Yes, you’re right, I don’t prefer this solution either, as it has some complications and you have to double your efforts sometimes.

How we solved this at Triphie?

Instead of using so many libraries, I came up with a very simple solution that solved most of my problems with a couple of lines of codes, I didn’t use vue-meta or server-side rendering, instead, I used the normal Larvel blade file, as you already know your SPA should have one entry blade file that has your app container, and this is the only page that will be loaded from server side and it will have it’s own meta tags.

And here comes the trick where I used this file to render meta tags for all of my pages,

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="your website url">
<meta property="og:title" content="title">
<meta property="og:description" content="description">
<meta property="og:image" content="image path">

These are the meta tags for Facebook, you should have more for Twitter and search engines like google.

As you can see the issue here is, that they are not dynamically changing for each page, so what I have done here is, replaced the previous one with this

<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="{{ $meta['url'] }}">
<meta property="og:title" content="{{ $meta['title'] }}">
<meta property="og:description" content="{{ $meta['description'] }}">
<meta property="og:image" content="{{ $meta['image'] }}">

Now we are getting meta tags dynamically from the server, but how the server will know which page is which?

Inside your SinglepageController index method, we check the route that is calling this method and then we return the meta tags accordingly.

public function index() {
$meta = [
   "title" => config('app.title'),
   "description" => config('app.description'),
   "url" => config('app.url'),
   "image" => asset('imgs/cover.jpg')
];

$path = request()->path();
if (str_contains($path, 'blog/post/')) {
   $post_id = str_replace('blog/post/', '', $path);
   $post = Post::find($post_id);
   if ($post) {
       $meta = [
       "title" => $post->title,
       "description" => $post->snippet,
       "url" => config('app.url') . $path,
       "image" => $post->cover
       ];
     }
}
return view('app', ['meta' => $meta]);
}

And Voila !!!

This simple method was very helpful for us in Triphie, I hope it will be helpful for you as well. If you have any better way of solving this please do share it in the comments down below

Don’t forget if you find this useful to clap it and share it with your friends who might be interested in this as well, and most importantly don’t forget to follow me for more 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *