Create Dynamic Titles and Favicons with Nuxt

Javier Martínez

Javier Martínez

Jun 18, 2020
3 min read
Share on Twitter or LinkedIn

According to a study by the University of Myself, 98.87% of developers don't pay attention to the title or the favicon of their webapps. That browser tab is where your app is going to live since the user opens it, goes to Twitter on another tab, spends 30 minutes liking dog memes and then comes back to you.

There are a lot of states that happen in your application in the background: Incoming messages, Notifications, Deploys, you name it... Sometimes the best place to put an indicator to that state is just the browser tab.

In our case, with remate.io, we have Projects the team can work on. A project has a unique color that identifies it. You can hop from one project to another, go to github, open issues, review that extra semicolon and then get back to the app (or not). When we are tracking our network tab looks like

Counter

This seems rocket science, but in fact is quite easy with Nuxt and its head method.

Nuxt.js uses vue-meta under the hood to update the headers and html attributes of your application. So we can do something like

export default {
  head () {
    return {
      title: 'Vue Dose is awesome!',
    }
  }
}

The fun fact is that head function acts like a computed, so it's reevaluated each time a dependency inside of it changes!

With that in mind, let's create a simple example: A dynamic page that gets a slug by route param with some categories in it

// _slug.vue
export default {
  data() {
    return {
      slug: this.$route.params.slug,
      categories: [
        { slug: 'geography', name: 'Geography', color: 'rgb(66, 153, 225)' },
        { slug: 'history', name: 'History', color: 'rgb(236, 201, 75)' },
        { slug: 'sports', name: 'Sports', color: 'rgb(237, 137, 54)' },
      ]
    }
  }
}

Now, lets update the title of the page using the name of the category

export default {
  data() {
    return {
      slug: this.$route.params.slug,
      categories: [
        { slug: 'geography', name: 'Geography', color: 'rgb(66, 153, 225)' },
        { slug: 'history', name: 'History', color: 'rgb(236, 201, 75)' },
        { slug: 'sports', name: 'Sports', color: 'rgb(237, 137, 54)' },
      ]
    }
  },
  
  computed: {
    category() {
      return this.categories.find(c => c.slug === this.slug) || {}
    }
  },
  
  head() {
    return {
      title: this.category.name,
    }
  }
}

Easy right? Let's go crazy and update the favicon too! As you might know, you can use SVGs as favicons. This feature allows you to be more dynamic. For this example let's just use an inline SVG with a circle.

export default {
  data() {
    return {
      slug: this.$route.params.slug,
      categories: [
        { slug: 'geography', name: 'Geography', color: 'rgb(66, 153, 225)' },
        { slug: 'history', name: 'History', color: 'rgb(236, 201, 75)' },
        { slug: 'sports', name: 'Sports', color: 'rgb(237, 137, 54)' },
      ]
    }
  },
    
  computed: {
    category() {
      return this.categories.find(c => c.slug === this.slug) || {}
    }
  },
  
  head() {
    return {
      title: this.category.name,
      link: [
        {
          rel: 'icon',
          type: 'image/svg+xml',
          href: `data:image/svg+xml,
                <svg
                  width="32"
                  height="32"
                  viewBox="0 0 32 32"
                  fill="none"
                  style="color: ${this.category.color};"
                  xmlns="http://www.w3.org/2000/svg"
                ><circle cx="16" cy="16" r="15.0049" fill="currentColor" /></svg>`,
        },
      ],
    }
  }
}

What we are doing here is simple. We are drawing an SVG and styling it with the color of the category. Inside, there is a circle that takes the currentColor and uses it in the fill property. The result for the Sport category will be an orange circle!

image

You can checkout this repo and fork it out if you want to see it in action.

Don't miss out anything about Vue, your favourite framework.

Subscribe to receive all the articles we publish in a concise format, perfect for busy devs.

Related Articles

How to use the new Fetch in Nuxt.js

The Nuxt team is on fire, releasing new stuff every week! In this tip Samuel shows you a feature that might've gone unnoticed... till now.

Samuel Snopko

Samuel Snopko

Sep 7, 2020

Advanced i18n in Nuxt using Interpolations

Internationalization it's necessary in a multi-language site. Learn how to do i18n the right way in Nuxt and Vue using the nuxt-i18n module.

Debbie O'Brien

Debbie O'Brien

Aug 17, 2020

Setting up a full static Nuxt site

Overwhelmed by too many options to create a blog? Chill and use Nuxt, Storyblok and TailwindCSS to make it simple, beautiful and incredibly performant

Alex Jover Morales

Alex Jover Morales

Jul 14, 2020

Sponsors

VueDose is proudly supported by its sponsors. If you enjoy it, consider supporting it to ensure the project maintainability.

Silver
Learning Partner