Skip to content

Commit e7ac3df

Browse files
committed
Router callback to match page title
1 parent 454e7ac commit e7ac3df

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
<div class="flex justify-between items-center flex-col md:flex-row">
1919
<router-link to="/projects" class="text-lg font-medium text-gray-400 uppercase md:mx-6 mb-2 sm:py-2">Projects</router-link>
2020
<router-link to="/about" class="text-lg font-medium text-gray-400 uppercase md:mx-2 mb-2 sm:py-2">About Me</router-link>
21-
<div class="sm:-mt-3 sm:ml-10 bg-gray-50 hover:bg-gray-100 p-2 rounded-lg shadow-sm hover:shadow-md cursor-pointer">
22-
<a href="#"><i data-feather="moon" class="text-gray-500"></i></a>
21+
<div class="sm:-mt-3 sm:ml-10 bg-gray-50 p-2 rounded-lg shadow-sm cursor-pointer">
22+
<a href="#"><i data-feather="moon" class="text-gray-600 hover:text-gray-400"></i></a>
2323
</div>
2424
</div>
2525

src/components/Home.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ export default {
2323
</script>
2424

2525
<style scoped>
26-
26+
2727
</style>

src/router/index.js

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,32 @@ const routes = [
55
{
66
path: '/',
77
name: 'Home',
8-
component: Home
8+
component: Home,
9+
meta: {
10+
title: 'Home'
11+
}
912
},
1013
{
1114
path: '/about',
1215
name: 'About',
1316
// route level code-splitting
1417
// this generates a separate chunk (about.[hash].js) for this route
1518
// which is lazy-loaded when the route is visited.
16-
component: () => import(/* webpackChunkName: "about" */ '../components/About.vue')
19+
component: () => import(/* webpackChunkName: "about" */ '../components/About.vue'),
20+
meta: {
21+
title: 'About'
22+
}
23+
},
24+
{
25+
path: '/projects',
26+
name: 'Projects',
27+
// route level code-splitting
28+
// this generates a separate chunk (projects.[hash].js) for this route
29+
// which is lazy-loaded when the route is visited.
30+
component: () => import(/* webpackChunkName: "projects" */ '../components/Projects.vue'),
31+
meta: {
32+
title: 'Projects'
33+
}
1734
}
1835
]
1936

@@ -23,3 +40,52 @@ const router = createRouter({
2340
})
2441

2542
export default router
43+
44+
/**
45+
* Below code will display the component/active page title
46+
* Powered by: Nangialai Stoman
47+
*/
48+
49+
// This callback runs before every route change, including on page load.
50+
router.beforeEach((to, from, next) => {
51+
// This goes through the matched routes from last to first, finding the closest route with a title.
52+
// e.g., if we have `/some/deep/nested/route` and `/some`, `/deep`, and `/nested` have titles,
53+
// `/nested`'s will be chosen.
54+
const nearestWithTitle = to.matched.slice().reverse().find(r => r.meta && r.meta.title);
55+
56+
// Find the nearest route element with meta tags.
57+
const nearestWithMeta = to.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
58+
59+
const previousNearestWithMeta = from.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
60+
61+
// If a route with a title was found, set the document (page) title to that value.
62+
if(nearestWithTitle) {
63+
document.title = nearestWithTitle.meta.title;
64+
} else if(previousNearestWithMeta) {
65+
document.title = previousNearestWithMeta.meta.title;
66+
}
67+
68+
// Remove any stale meta tags from the document using the key attribute we set below.
69+
Array.from(document.querySelectorAll('[data-vue-router-controlled]')).map(el => el.parentNode.removeChild(el));
70+
71+
// Skip rendering meta tags if there are none.
72+
if(!nearestWithMeta) return next();
73+
74+
// Turn the meta tag definitions into actual elements in the head.
75+
nearestWithMeta.meta.metaTags.map(tagDef => {
76+
const tag = document.createElement('meta');
77+
78+
Object.keys(tagDef).forEach(key => {
79+
tag.setAttribute(key, tagDef[key]);
80+
});
81+
82+
// We use this to track which meta tags we create so we don't interfere with other ones.
83+
tag.setAttribute('data-vue-router-controlled', '');
84+
85+
return tag;
86+
})
87+
// Add the meta tags to the document head.
88+
.forEach(tag => document.head.appendChild(tag));
89+
90+
next();
91+
});

0 commit comments

Comments
 (0)