I hope this is a quick one.
I have this mapping that looks like this:
const routes = routeOptions.map((route) => {
return {
children: route?.children?.map((child) => {
return {
...{
path: child.path,
name: child.name,
meta: child.meta,
alias: child.alias,
},
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */
`../views/${child.name
.replace(" ", "-")
.toLowerCase()}/${child.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
}),
...{
path: route.path,
name: route.name,
meta: route.meta,
redirect: route.redirect,
},
component: () =>
import(
/* webpackChunkName: "[request]" */
`../views/${route.name
.replace(" ", "-")
.toLowerCase()}/${route.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
});
Then I can set my routeOptions like this:
const routeOptions: RouteOptions[] = [{
path: "/account",
name: "account",
meta: {
title: "Account",
},
redirect: {
name: "sign-in",
},
children: [{
path: "sign-in",
name: "sign-in",
meta: {
title: "Sign in",
},
},
{
path: "join",
name: "join",
meta: {
title: "Join",
},
},
{
path: "add-password",
name: "add-password",
meta: {
title: "Add password",
},
},
{
path: "forgot-password",
name: "forgot-password",
meta: {
title: "Forgot password",
},
},
{
path: "reset-password",
name: "reset-password",
meta: {
title: "Reset password",
},
},
],
},
{
path: "/crew",
name: "staff",
meta: {
title: "Crew",
},
redirect: {
name: "staff-account",
},
children: [{
path: "account",
name: "staff-account",
meta: {
title: "Account",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "demos",
name: "staff-demos",
meta: {
title: "Demos",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "leader-boards",
name: "staff-leader-boards",
meta: {
title: "Leader boards",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "search",
name: "staff-search",
meta: {
title: "Search",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "stories",
name: "staff-stories",
meta: {
title: "Stories",
authorize: ["Venue Staff", "Venue Manager"],
},
},
],
},
{
path: "/404",
name: "not-found",
meta: {
title: "Page not found",
},
},
{
path: "*",
name: "layout",
meta: {},
children: [{
path: "/business/live-better",
name: "blog",
meta: {
title: "Partner Blog",
},
children: [{
path: ":title",
name: "blog",
}, ],
},
{
path: "/business/live-better/:title",
name: "blog-post",
},
{
path: "/brands",
name: "brand-list",
meta: {
title: "Brands",
},
},
{
path: "/brands/:brandSlug",
name: "brand-details",
meta: {
title: "Details",
},
},
{
path: "/categories",
redirect: {
name: "categories"
},
},
{
path: "/categories/:categorySlug",
redirect: {
name: "product-list"
},
},
{
path: "/categories/:categorySlug/:productId/:productTitle",
redirect: {
name: "product-details"
},
},
{
path: "/products",
name: "categories",
meta: {
title: "Products",
},
},
{
path: "/products/:categorySlug",
name: "product-list",
meta: {
title: "Products",
},
},
{
path: "/products/:categorySlug/:productId/:productTitle",
name: "product-details",
meta: {
title: "Details",
},
},
{
path: "/favourites",
name: "favourites",
meta: {
title: "Your favourites",
},
},
{
path: "/feedback",
name: "consumer-feedback",
meta: {
title: "Your feedback",
authorize: [],
},
},
{
path: "/venues/:venueSlug/theatres",
name: "theatre-list",
meta: {
title: "Theatres",
},
},
{
path: "/venues/:venueSlug/theatres/:theatreSlug",
name: "theatre-details",
meta: {
title: "Theatre",
},
},
{
path: "/venues",
name: "venue-list",
meta: {
title: "Venues",
},
},
{
path: "/venues/:venueSlug",
name: "venue-details",
meta: {
title: "Details",
},
},
{
path: "/search",
name: "search",
meta: {
title: "Search results",
},
},
{
path: "*",
name: "home",
meta: {
title: "Home",
},
},
],
},
];
Most of these work, but if you take a look at this section here:
{
path: "/categories",
redirect: { name: "categories" },
},
{
path: "/categories/:categorySlug",
redirect: { name: "product-list" },
},
{
path: "/categories/:categorySlug/:productId/:productTitle",
redirect: { name: "product-details" },
},
I want these to redirect to other named views.
The way my mapping works at the moment, is that it takes the name and looks in the views folder for a matching template, but these routes don't have templates because they are just redirects.
Does anyone know what I can do to my code to get it to work with these?
I did it like this:
const createChildRoutes = (children) => {
return children?.map((child) => {
const childRoute = {
path: child.path,
name: child.name,
meta: child.meta,
alias: child.alias,
redirect: child.redirect,
};
if (child.name) {
return {
...childRoute,
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */ `../views/${child.name
.replace(" ", "-")
.toLowerCase()}/${child.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
} else {
return childRoute;
}
});
};
const routes = routeOptions.map((route) => {
const mainRoute = {
path: route.path,
name: route.name,
meta: route.meta,
alias: route.alias,
redirect: route.redirect,
};
if (route.name) {
return {
children: createChildRoutes(route?.children),
...mainRoute,
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */ `../views/${route.name
.replace(" ", "-")
.toLowerCase()}/${route.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
} else {
return {
children: createChildRoutes(route?.children),
...mainRoute,
};
}
});
I am using NuxtJS's head tag. The meta tags in my application are often repeated or only have a slight variation.
I would like to pass the title into the mixin and then reuse the code for all pages in the application. However, I am not sure how to do this in vuejs. any suggestions?
export const metatags = {
head () {
const organization = this.$store.state.loadedData
const title = 'Classes & Lessons - ' + organization.organization.name + ' ' +
organization.target_locations[0]
const description =
(organization.organization.name
? organization.organization.name
: '') +
' is ' +
(organization.services.length > 0
? organization.target_locations[0]
: '') +
"'s premier " +
(organization.services.length > 0
? organization.services[0].name
: '') +
' and ' +
(organization.services.length > 1
? organization.services[1].name
: '') +
' training centers'
const logo = process.env.AMAZONAWS_IMAGE_URL +
organization.organization.primary_logo_id + '_350.' + organization.organization.logo_extension
const favicon = logo
const domain = 'https://' + this.$store.state.domain
return {
title,
meta: [
{
name: 'description',
content: description
},
{
property: 'og:title',
content: title
},
{
property: 'og:site_name',
content: organization.organization.name
},
{
property: 'og:description',
content: description
},
{
property: 'og:image',
content: logo
},
{
property: 'og:url',
content: domain
},
{
name: 'twitter:title',
content: title
},
{
name: 'twitter:description',
content: description
},
{
name: 'twitter:image',
content: logo
}
],
link: [
{ rel: 'canonical', href: domain },
{ rel: 'icon', href: logo },
{ rel: 'shortcut icon', href: logo },
{ rel: 'apple-touch-icon', href: logo },
{ rel: 'icon', type: 'image/x-icon', href: favicon }
]
}
}
}
It's not possible to pass any argument into your head() method directly, but this is available there. It doesn't matter whether the head() is defined on the page directly or using a mixin. Just make sure to not override it on individual pages....
I have VUEJS app and I use CKEditor, I want to add color buttons on the toolbar, but it is not working.
import CKEditor from '#ckeditor/ckeditor5-vue';
Vue.use(CKEditor);
<ckeditor :editor="editor" :config="editorConfig"></ckeditor>
editor: ClassicEditor,
editorData: "<p>Content of the editor.</p>",
editorConfig: {
toolbarGroups: [
{ name: "document", groups: ["mode", "document", "doctools"] },
{ name: "clipboard", groups: ["clipboard", "undo"] },
{
name: "editing",
groups: ["find", "selection", "spellchecker", "editing"]
},
{ name: "forms", groups: ["forms"] },
"/",
{ name: "basicstyles", groups: ["basicstyles", "cleanup"] },
{
name: "paragraph",
groups: ["list", "indent", "blocks", "align", "bidi", "paragraph"]
},
{ name: "links", groups: ["links"] },
{ name: "insert", groups: ["insert"] },
"/",
{ name: "styles", groups: ["styles"] },
{ name: "colors", groups: ["colors"] },
{ name: "tools", groups: ["tools"] },
{ name: "others", groups: ["others"] },
{ name: "about", groups: ["about"] }
]
},
But in the final, I have got a toolbar that does not have the buttons that I put.
I am looking for ways to refactor this:
nuxt.config.js
const headConfig = require('./config/head')
const modulesConfig = require('./config/modules')
const config = {
head: headConfig,
(...)
}
module.exports = Object.assign({}, config, modulesConfig)
config/head.js
module.exports = {
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{name: 'fb:app_id', content: 'xxxx'},
{hid: 'og:url', name: 'og:url', content: 'xxxx'},
{hid: 'og:type', name: 'og:type', content: 'website'},
{hid: 'og:image', name: 'og:image', content: 'xxxx'},
{hid: 'og:site_name', name: 'og:site_name', content: 'xxxx'},
{hid: 'keywords', name: 'keywords', content: 'xxxx'}
]
}
An example of what I'd like to be able to do is to automatically set the 'og:url' to the url of the page. There is no need to repeat that every time.
At the moment I include this in each page of my Nuxt.js app:
{
hid: 'og:url',
property: 'og:url',
content: 'https://website.com' + this.$route.fullPath
},
I am sure there is a better way to automatically set that somewhere :/
Probably your best bet would be to create a global Mixin:
https://v2.vuejs.org/v2/guide/mixins.html#Global-Mixin
This should allow you to create a head mixin that will be auto-imported into every component, so you could define that og:url once and have it auto-injected everywhere.
Here's an example of how you'd register it as a plugin with Nuxt:
/plugins/headMixin.js
import Vue from 'vue'
export default ({ route }) => {
Vue.mixin({
head() {
return {
meta: [
{
hid: `og:url`,
property: 'og:url',
content: 'https://www.yoursite.com' + route.fullPath
}
]
}
}
})
}
in nuxt.config.js:
plugins: [
'~/plugins/headMixin.js'
]
this is my way
in nuxt.config.js:
head: {
title: 'default title',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{
hid: 'description',
name: 'description',
content: 'default description'
}
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
in default.vue
export default {
head() {
return {
title: `Company - ${this.$route.meta.title}`,
meta: [
{
hid: 'description',
name: 'description',
content: this.$route.meta.description
}
],
}
},
and if you use #nuxtjs/router in router.js
routes: [
{
path: '/page',
name: 'some',
meta: {
title: 'Best seo title',
description: 'Best seo description'
},
component: someComponent,
},
All the data you write in routes. Everything works perfectly.