How to Change Page Titles When Using Vue-Router ?
When using Vue Router in a Vue.js application, you may want to dynamically change the page title based on the currently active route. This is commonly done for better user experience and SEO. Vue Router provides a way to accomplish this by updating the document title in the browser dynamically.
Below methods that can be used to achieve this task:
Table of Content
- Using Watcher
- Using beforeEach
Approach 1: Using Watcher
A Watcher in Vue.js is a special feature that allows one to watch a component and perform specified actions when the value of the component changes. It is a more generic way to observe and react to data changes in the Vue instance. Watchers are the most useful when used to perform asynchronous operations.
Syntax:
watch: {
$route(to, from) {
document.title = to.meta.title || "Default Title";
},
}
Example
In this example, The pageTitle data property is used to store the current page title. A watcher is set up to watch for changes in the $route and update pageTitle accordingly.
HTML
<!-- index.html --> <!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" /> < meta name = "viewport" content=" width = device -width, initial-scale = 1 .0" /> < title > How to change page titles when using vue-router? </ title > </ head > < body > < div id = "app" ></ div > < script src = "https://cdn.jsdelivr.net/npm/vue@2" > </ script > < script src = "https://cdn.jsdelivr.net/npm/vue-router@3" > </ script > < script > // Define components for each route const Home = { template: ` < div > This is Home Page. </ div >` }; const About = { template: ` < div > This is About Page. </ div >` }; const Contact = { template: ` < div > This is Contact Page. </ div >` }; // Create a router instance const router = new VueRouter({ routes: [ { path: "/", component: Home, meta: { title: "Home Page" } }, { path: "/about", component: About, meta: { title: "About Us" } }, { path: "/contact", component: Contact, meta: { title: "Contact Us" } }, ], }); // Create a Vue instance with the router new Vue({ router, el: "#app", data: { pageTitle: "Default Title", }, watch: { $route(to, from) { document.title = to.meta.title || "Default Title"; }, }, template: ` < div > < h1 style = "color: green;" > w3wiki </ h1 > < p > Change Page Title to the currently< br /> viewing page by clicking the nav links. </ p > < h3 >< router-link to = "/" > Home </ router-link ></ h3 > < h3 >< router-link to = "/about" > About </ router-link ></ h3 > < h3 >< router-link to = "/contact" > Contact </ router-link ></ h3 > < router-view ></ router-view > </ div > `, }).$mount("#app"); </ script > </ body > </ html > |
Output:
Approach 2: Using beforeEach
The navigation guards provided by Vue router are primarily used to guard navigations either by redirecting it or canceling it. We can use router.beforeEach to listen for routing events globally across the application.
Syntax:
router.beforeEach((to, from, next) => {
document.title = to.meta.title || "Default Title";
next();
});
Example: In this example, the beforeEach navigation guard is responsible for setting the document title before each route change. This approach ensures that the title is updated as soon as the route changes.
HTML
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" /> < meta name = "viewport" content=" width = device -width, initial-scale = 1 .0" /> < title >Vue Router Example</ title > < script src = "https://cdn.jsdelivr.net/npm/vue@2" > </ script > < script src = "https://cdn.jsdelivr.net/npm/vue-router@3" > </ script > </ head > < body > < div id = "app" > < h2 style = "color: green;" > w3wiki </ h2 > < p > Change Page Title to the currently< br /> viewing page by clicking the nav links. </ p > < h3 > < router-link to = "/" > Home </ router-link > </ h3 > < h3 > < router-link to = "/about" > About </ router-link > </ h3 > < h3 > < router-link to = "/contact" > Contact </ router-link > </ h3 > < router-view ></ router-view > </ div > < script > const Home = { template: ` < div > I am Home </ div >` }; const About = { template: ` < div > I am About </ div >` }; const Contact = { template: ` < div > I am Contact </ div >` }; const routes = [ { path: "/", component: Home, meta: { title: "Home Page" } }, { path: "/about", component: About, meta: { title: "About Us" } }, { path: "/contact", component: Contact, meta: { title: "Contact Us" } }, ]; const router = new VueRouter({ routes, }); // Global navigation guard to // set the title based on the route router.beforeEach((to, from, next) => { document.title = to.meta.title || "Default Title"; next(); }); new Vue({ el: "#app", router, }); </ script > </ body > </ html > |
Output:
Conclusion
Both examples demonstrate different approaches to dynamically changing page titles based on the active route when using Vue Router in a Vue.js application. Choose the approach that best fits your application structure and preferences