Vue Tip: Dynamically Change Page Title
Michael Hoffmann
@mokkapps
To set the document title, we define the <title>
tag in our index.html
file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue Tip: Dynamically Change Page Title</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
In many applications, we have different routes and want to show a dedicated title for each route.
Unfortunately, this does not work out of the box, and we need to write some code to enable this functionality.
Let's take a look at an exemplary route configuration (check the Vue Router docs for more details about Vue Router):
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: Home,
},
{
path: '/about',
component: () => import('@/views/About.vue'),
},
{
path: '/contact',
component: () => import('@/views/Contact.vue'),
},
],
})
export default router
We can use the beforeEach guard on the router instance to dynamically set the document title on each route. The beforeEach
guard adds a navigation guard that executes before any navigation:
router.beforeEach((to, from) => {
document.title = to.meta?.title ?? 'Default Title'
})
Inside the navigation guard callback, we use document.title
to set the document's title. We use the nullish coalescing operator (??
) in combination with optional chaining (?.
) to set Default Title
if the meta
object or the title
is undefined.
Finally, we need to define the metadata on our routes:
routes: [
{
path: '/',
component: Home,
meta: {
title: 'Home',
},
},
{
path: '/about',
component: () => import('@/views/About.vue'),
meta: {
title: 'About',
},
},
{
path: '/contact',
component: () => import('@/views/Contact.vue'),
meta: {
title: 'Contact',
},
},
],
At this point, we have updated our code to dynamically update the page title when the page changes. The following StackBlitz playground contains a running example:
We can improve the code by adding "more dynamic" page titles using route props:
<script setup>
const client = await useClient()
</script>
<template>
<router-link :to="{ name: 'ViewClient', params: { pageTitle: `${client.firstName} ${client.lastName}` } }">
View client details
</router-link>
</template>
We can access the route params via to.params
and set the document's title accordingly:
router.beforeEach((to, from, next) => {
const titleFromParams = to.params?.pageTitle
if (titleFromParams) {
document.title = `${titleFromParams} - ${document.title}`
} else {
document.title = to.meta?.title ?? 'Default Title'
}
})
If you liked this Vue tip, follow me on BlueSky to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter :