Webjeda
How to add SEO to Svelte Apps?

How to add SEO to Svelte Apps?

Adding SEO in svelte is easier than other JS frameworks because of this nice and simple utility -

<svelte:head></svelte:head>

You can place any tag inside this svelte tag and it will be moved into the <head></head> tag.

This is fantastic if you have maybe 3 pages. But if you are dealing with hundreds of pages with dynamic content, then you have to figure out how to do it without repeating the same code in all routes.

A demo of this method can be found in Hagura Sveltekit Theme

Let’s see how to do this.

1. Create a root layout

If you do not already, then create a layout at the root level in your Svelte app. If you’re using sveltekit then it will be src/__layout.svelte.

If you are not sure how layout works then please go through this video.

Sveltekit Intro, Pages, Layouts & Components

2. Create an SEO component

You can create this anywhere. In sveltekit, the best place is inside src/lib/. Let’s call this Seo.svelte. Now import this in your layout that was created in the previous step and use it.

<script>
  import Seo from "$lib/Seo.svelte"
</script>

<Seo />
<slot />

Let’s see what content we can have inside our Seo component.

<svelte:head>

  <title>My website</title>
  <meta name="description" content="This is a description of my website">
</svelte:head>

This will not work because all the pages will have the same tags. But you can add this and check if you are getting these tags for all the routes.

3. Create an SEO state

This is the soul of our Svelte SEO component. We will create a store file and add the following. If you’re using sveltekit then you can do this inside $lib directory. Create a file called store.js.

If you don’t know what state in Svelte is then watch this video. Svelte has an inbuilt state management and it is amazingly simple.

import { writable } from "svelte/store";

export const seo = writable({
title: "My Website", // default title
description: "This is a description of my website" // default description
})

The object seo has writable default values. We will soon see how to change these based on page or route.

4. Update your layout

Let’s update the __layout.svelte file we created on step 1.

<script>
  import Seo from "$lib/Seo.svelte"
</script>

<Seo />
<slot />

5. Update Seo component

<script>
  import { seo } from "$lib/store.js"
</script>

<svelte:head>
  <title>{seo.title}</title>
  <meta name="description" content={seo.description}>
</svelte:head>

6. Update seo object in routes

Let’s say you are in the homepage then your SEO store object would look like this.

<script>
  import { seo } from "$lib/store.js"

$seo = {
  title: "Home",
  description: "This is homepage"
}
</script>

and if you are in the about page then your SEO object would be something like

<script>
  import { seo } from "$lib/store.js"

$seo = {
  title: "About",
  description: "This is about page"
}
</script>

This is it. This would take care of the SEO tags in your app. I have shown only title and description but you can have OGP, Twitter tags, JSON-LD etc.

Dynamic values

Sometimes you might have dynamic routes for websites like a blog. In such cases, you can use this on dynamic files. A common dynamic route file usually has the name [slug].svelte.

You can use dynamic values for your titles in such cases.

<script>
  import { seo } from "$lib/store.js"

  const post = {
    //post object with title and description
    // you usually fetch this through an API
    title: "A post title",
    description: "A post description"
  }
$seo = {
  title: post.title,
  description: page.description
}
</script>

Advantages

It is obvious that instead of going through all this, why can’t we just add our meta tags and JSON-LD script inside <svelte:head></svelte:head> in all pages and posts?

You can. But the only problem is that if you want to add one more tag or remove a tag, you will have to go through all the pages and posts of your website.

But with the method I have described above, you just have to edit one component and it will reflect in all the pages.

Comparing with React Helmet

I have used react-helmet and it works fine. But unless you set up server-side rendering, you will not see any info on your web pages upon sharing on social media.

Whereas svelteKit has SSR inbuilt and the tags are available for the bots to read.

Conclusion

There are plugins out there for solving this. But usually, they are repetitive. This method is simpler once you are familiar with how stores work on Svelte and how easy it is to update them. Let me know if you have a simpler solution.

Watch SvelteKit videos here:


Tweet this article

tweet this post

Also read