I have a simple Vue-based website created using Vue CLI, and I'm trying to figure out how to dynamically generate page titles for views w/ dynamic routes. The site is pulling JSON data from a headless CMS, and I have dynamic routes set up for detail views of a "project" content type. I have the dynamic route set up as follows:
// single project vue (dynamic)
{
path: "/projects/:project_name_slug",
name: "single-project",
component: () =>
import(
/* webpackChunkName: "single-project" */ "./views/SingleProject.vue"
),
meta: {
title: "project detail",
}
}
I have added the following, which works for adding static page titles:
// show page titles
const DEFAULT_TITLE = "my blog";
router.afterEach((to, from) => {
// document.title = to.meta.title || DEFAULT_TITLE;
document.title = "my blog - " + to.meta.title || DEFAULT_TITLE;
});
As it stands, upon visiting a project detail view, the title will read "my blog - project detail"; however, I'd like it to pull the actual project name from the JSON/field data for project_name
(just as the route path is using project_name_slug
), but nothing I've tried thus far has worked. For instance, using meta: { title: (route) => route.params.project_name }
just results in a raw function text showing after "my blog - ". Thus, in cases for those dynamic views, I would like to.meta.title
to resolve to the project name, creating "my blog - {project name}". Thank you for any assistance here, and please let me know if I need to provide any more details.
*Note: This question differs from that posed in this SO thread as my case involves dynamic routes using JSON data requested via Axios
Set the meta
in the router's beforeEach
navigation guard:
router.beforeEach((to, from, next) => {
to.meta.title = to.params.project_name_slug;
next();
});
-or-
You could use the beforeRouteEnter
and beforeRouteUpdate
in-component guards:
export default {
...
beforeRouteEnter(to, from, next) {
to.meta.title = to.params.project_name_slug;
next();
},
beforeRouteUpdate(to, from, next) {
to.meta.title = to.params.project_name_slug;
next();
}
}
You can use the afterEach
just like you would for a static meta since it will already be set:
const DEFAULT_TITLE = "my blog";
router.afterEach((to, from) => {
// document.title = to.meta.title || DEFAULT_TITLE;
document.title = "my blog - " + to.meta.title || DEFAULT_TITLE;
});
(Note: Using beforeEnter
in the route definition wouldn't be enough because it doesn't trigger when going from one dynamic param to another. Even <router-view :key="$route.fullPath"></router-view>
does not trigger beforeEnter
when changing params.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With