How to modify alternate links during SSR using nuxt and Vue i18n - vue.js

I want to modify the href attribute(to remove query string) for specific pages
like screenshot below:
or maybe entirely remove the link element for specific pages
How can I archive that?

With nuxt, you just have to specify a head function that defines these links:
export default {
head() {
return {
link: [
{ rel: 'alternate', hreflang: 'zh', href: 'http://my-main-alternate-link' },
{ rel: 'alternate', hreflang: 'en', href: 'http://my-english-alternate-link' }
]
}
}
}
You'll have to manually specify all the links for all languages I'm afraid.

Related

Using Regex in vue router path

In Vue router, I have a path /[can be anything in here]/products/shoes/nike
The first part is languageCode that can be anything or it may not be exist at all. I want to cover all of the possibilities. I tried
{
path: ':lang/products/shoes/nike',
meta: { allowGuest: true },
redirect: { name: 'shoes' },
},
Tried with path: '/:catchAll(.*)/products/shoes/nike' too but didn't work either.
I am still not able to catch routes starting with a languageCode. Is there a way I can do it with regex?
In order to make :lang optional in your route's path, you need to use ? modifier.
So, update your route object as follows:
{
path: '/:lang?/products/shoes/nike',
meta: { allowGuest: true },
redirect: { name: 'shoes' },
}
Refer official vue-router docs for detailed info- https://router.vuejs.org/guide/essentials/route-matching-syntax.html#optional-parameters

How to exclude script on certain routes in Nuxt?

I have a nuxt2-webapp with a lot of routes and for all routes except 2, I need a script to be injected. Is there a way to disable the injecting?
Nuxt config:
meta: [
script: [
{
id: 'Cookiebot',
src: 'https://consent.cookiebot.com/uc.js',
'data-cbid': 'xxxxx',
type: 'text/javascript',
async: true,
},
],
]
No, there is no way to do so.
If you inject a script, it will be on the window object. Hence available everywhere in your DOM.
What's the issue with that? You could hide your thing with some CSS if it's annoying visually.
The best way to achieve this behaviour is via a plugin:
export default (context: Context) => {
if (!context.route.name?.includes('embed')) {
const scriptTag = document.createElement('script');
scriptTag.id = 'Cookiebot';
scriptTag.src = 'https://consent.cookiebot.com/uc.js';
scriptTag.setAttribute('data-cbid', 'xxxx');
scriptTag.type = 'text/javascript';
scriptTag.async = true;
document.head.appendChild(scriptTag);
}
};

Nuxt: Dynamic og:image when generating static files

I am working on my first Nuxt project. I am trying to dynamically set the og:image URL by taking images of a post. In principle I am able to achieve this with the following code in the script
export default {
head() {
return {
title: this.post.title,
meta: [
{
hid: "description",
name: "description",
content: this.post.description,
},
{ hid: "og:title", property: "og:title", content: this.post.title },
{
hid: "og:description",
property: "og:description",
content: this.deck.description,
},
{ hid: "og:type", property: "og:type", content: "article" },
{
hid: "og:image",
property: "og:image",
content:
"https:[website]" +
require(`#/content${this.slug.dir}/images/preview.png`),
},
{
hid: "og:url",
property: "og:url",
content:
"https:[website]" + this.$route.fullPath,
},
],
};
},
async asyncData({ $content, params }) {
...
},
};
</script>
I notice the following:
On the browser page, when I open view source, these tags are not shown. However, the inspector shows the meta tags in the head .
This is as expected because, the view source is the base HTML head that is served from the backend, while the meta tags, the Nuxt JS must be dynamically adding on load.
I think we type the URL in a social media post like Facebook, WhatsApp, Twitter, LinkedIn, the manner it works is that only the head portion of the page is retrieved and the og parameters are retrieved to display the image. But the JS script is not executed.
And that is why I get a missing image error or a blank thumbnail.
The nuxt.config.js is as below
// nuxt.config.js
export default {
...
target: 'static',
...
ssr: false, // removing this makes no difference
...
}
Question is: how can I get Nuxt to add the meta tags in the generated HTML? Thanks

Vue prop validation is not called

I create a component with input properties:
export default {
data() {
:
:
},
props: {
rowsContent: {
type: Object,
default: null,
validator: function(value) {
console.log("In validator");
}
},
rowsPerPage: {
type: Number,
default: 10,
},
}
I tried to pass different type of parameters, and got no error message.
Moreover, no "In validator" message is printed to console.
Any idea?
I don't know the reason, but it is working if I use component tag like <tag></tag>. If I use like <tag/>, it does not work. See example here. https://codesandbox.io/s/z6rlzl998p
EDIT: Vue does not support self-closing tags as components: https://github.com/vuejs/vue/issues/8664 (as mentioned in comment)

VueJS: one component for many routes

I'm a newbie to the world of VueJS.
My app uses vue-router to handle with routes changing. This's how it's configured:
new Router({
routes: [{
path: "/",
component: Articles
}, {
path: "/articles/:category",
component: Articles
}]
});
As you can see, I've got 2 routes handled by the same component. The idea is very simple. When we're on a home page, show articles from any category. When we're on a category page, show articles from that category.
The question is, how a component can detect whether the route's changed, e.g, from home page to category page?
I've come with this solution:
function loadArticles() {};
Vue.component("Articles", {
mounted: loadArticles,
watch: { "$route": loadArticles }
});
But I think, that's a bad solution.
Here's what I have done on a little project of mine, I'm using the template to display single article
This is my router
'/post/:id': {
name: 'post',
component: require('./components/article.vue')
},
In my .vue file, I get the $route.params to get the id of the article then displayed it in my ready function.
$.get('api/posts/' + this.$route.params.id, function(data){
myPost.current = data;
})
You'll need to get the category parameter then rendered the template according to it.
It should look something like this:
watch: {
'$route' (to, from) {
if (this.$route.params.category) {
this.loadArticles(category);
} else {
this.loadArticles();
}
}
}
'watch' is recommended here, in docs.