Alternate page with proper canonical tag and duplicate URL part errors in Google search console report - vue.js

I have a static blog site created with Nuxt and hosted on Netlify. For content, I am using markdown files and the new Content module in Nuxt. I used Nuxt and static content, along with vue-meta for SEO purposes, but after a couple months, my coverage report shows multiple errors, and I can't get any pages returned in Google, even when searching on the site name or a specific string of text used on the site.
Here's my setup:
My markdown content is stored in /content/posts
In my blog/index.vue file, this is what I have for my meta tags and data fetching:
<script>
export default {
name: 'Posts',
head() {
return {
title: 'Blog Posts',
meta: [
{
hid: 'description',
name: 'description',
content: 'Example Site blog index'
},
{
hid: 'link',
name: 'link',
content: 'https://example.com/blog'
}
]
}
},
async asyncData({ $content, params }) {
const posts = await $content('posts', params.slug)
.only(['title', 'description', 'publishDate', 'slug'])
.sortBy('publishDate', 'desc')
.fetch()
return {
posts
}
},
};
</script>
In my /blog/_slug/index.vue page, I'm doing almost the same thing.
export default {
name: 'Post',
computed: {
pageConfig() {
return {
identifier: this.post.slug
}
}
},
head() {
return {
title: this.post.title,
meta: [
{
hid: 'description',
name: 'description',
content: this.post.description
},
{
property: "og:site_name",
hid: "og:site_name",
vmid: "og:site_name",
content: "My Site Name"
},
{
property: "og:title",
hid: "og-title",
vmid: "og-title",
content: this.post.title
},
{
property: "og:description",
hid: "og-description",
vmid: "og-description",
content: this.post.description
},
{
property: "og:type",
hid: "og-type",
vmid: "og-type",
content: "article"
},
{
property: "og:url",
hid: "og-url",
vmid: "og-url",
content: 'https://example.com/blog/' + this.post.slug
},
{
hid: "link",
name: "link",
content: 'https://example.com/blog/' + this.post.slug
},
],
link: [
{
rel: 'canonical',
href: 'https://example.com/blog/' + this.post.slug
}
]
}
},
async asyncData({ $content, params }) {
const post = await $content('posts', params.slug).fetch()
return {
post
}
},
}
I'm using this to generate my sitemap in nuxt.config.js
sitemap: {
path: '/sitemap.xml',
hostname: process.env.BASE_URL,
gzip: true,
routes: async () => {
let routes = []
const { $content } = require('#nuxt/content')
let posts = await $content('posts').fetch()
for (const post of posts) {
routes.push(`blog/${post.slug}`)
}
return routes
},
}
and this generates a sitemap at /sitemap.xml with the following structure
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>https://example.com/blog/blog-post-1</loc>
</url>
<url>
<loc>https://example.com/blog/blog-post-2</loc>
</url>
<url>
<loc>https://example.com/blog/blog-post-3</loc>
</url>
</urlset>
I submitted my sitemap to Google.
When I look at my Coverage report in Google Search Console, I have two main problems:
A large number of posts listed under Not Found (404) with a URL of https://example.com/blog/blog/my-blog-post (two /blogs in the URL). I've noticed this happens sometimes when I click on a post right after deploying to Netlify. I've looked around the code, and I can't find where I might be adding an extra /blog in the URL.
An equally large number under Alternate page with proper canonical tag. Before I put the canonical tag in my /_slug/index/vue header, I got errors about missing a canonical tag, and now that I put that in, I get this error instead.
What do I need to do to fix these errors and get my content correctly indexed?

Related

replace the page meta and link with global meta on nuxt

Why doesn't the local configuration for meta title and description override the global configuration
The problem is that when I change the meta tags and links on the page, it removes the meta tags that are global and replaces the new meta tags. I want these meta and links to be added to the global meta and links.
In the meta tag and global links that I have, I have a part that makes the logo part of the site correct when adding a bookmark in Safari, but when I add the meta tag to my page, the photo is no longer loaded, and I think the problem is from It is that Next replaces the meta tags that are created on each page instead of the global meta tags
Code
**this is my nuxt config code**
head: {
title: 'Flyver',
htmlAttrs: {
lang: 'en',
},
meta: [
.........
{ charset: 'utf-8' },
{
name: 'viewport',
hid: 'viewport',
content:
'width=device-width,initial-scale=1,shrink-to-fit=no,maximum-scale=5,viewport-fit=cover',
},
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
{
hid: 'apple-mobile-web-app-status-bar-style',
name: 'apple-mobile-web-app-status-bar-style',
content: 'black-translucent',
},
.........
],
link: [
.........
{
hid: 'apple-touch-icon',
rel: 'apple-touch-icon',
href: '/android-chrome-180x180.png?v=sf54fgh123',
type: 'image/png',
sizes: '180x180',
},
{
hid: 'apple-touch-icon1',
rel: 'apple-touch-icon',
href: '/apple-touch-icon.png?v=sf54fgh123',
type: 'image/png',
sizes: '120x120',
},
.........
},
this is my index page**
async fetch() {
........
this.headValue = {
title: this.pageData?.value?.title,
link: [
{
rel: 'canonical',
href: `https://flyver.ir`,
},
],
meta: [
{
name: 'description',
content: this.pageData?.value?.description,
},
...this.pageData?.metaTags,
],
};
..........
},
head() {
return this.headValue;
},
What is Expected?
I expect the meta tags that are created per page to be added to the global meta tags
What is actually happening?
Replaces new meta tags with global meta tags

Adding dynamic meta tags fetched from API to nuxtjs static site

I have a static site with Nuxt and content coming in from Strapi. I want to dynamically set the meta tags that are fetched asynchronously.
My site has an index page which passes the fetched data to index-web or index-mobile through props.
let pageMeta: any
const apiBase: string = 'https://strapi.xyz.com'
export default Vue.extend({
components: { Greeting, Showcase, Features, Footer },
props: {
data: Map,
pageMeta,
},
data() {
return {
loading: true,
}
},
metaInfo(): any {
return {
meta: [
{
hid: 'description',
name: 'description',
content: pageMeta.description,
},
{
hid: 'author',
name: 'author',
content: pageMeta.author,
},
],
}
},
})
The prop being passed in a JSON parsed object.
Having done this, the generated site does not have the meta tags added in.
As mentioned, you need to access the property with .this.

How to override global meta tags in a specific template in Nuxt?

I am not sure if this is possible but here it comes.
I have a nuxt.config.js such as (I have changed some information such as content and href attributes for privacy):
head: {
htmlAttrs: {
lang: 'de-DE'
},
title: 'My Title',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'My Content.' },
],
link: [
{ rel: 'icon', type: 'image/png', href: '/images/icons/favicon.png' },
{ rel: 'preload', as: 'style', onload: "this.onload=null;this.rel='stylesheet'", href: 'mycss' },
{ rel: 'preload', as: 'style', onload: "this.onload=null;this.rel='stylesheet'", href: 'mycss' },
{ rel: 'dns-prefetch', href: 'https://www.google-analytics.com' }
]
}
As you can see I have two preload link tags which includes onload. I am doing some AMP pages for SEO and AMP gives an error for onload.
The attribute 'onload' may not appear in tag 'link rel=preload
So I want to override those link tags only in my AMP pages. What I have tried is head() function for my AMP pages to override global settings however it didn't override and actually added new links.
export default {
head () {
return {
link: [
// my links
]
}
}
}
I have checked the documentation and looked a few questions here but couldn't find a solution. Is there any way that I can achieve this ?
PS: I want to keep those 2 links in my global because there are lots of pages that uses it.
From nuxt documentation:
To avoid any duplication when used in child components, please give a unique identifier with the hid key to the meta description. This way vue-meta will know that it has to overwrite the default tag.
So try to add an hid attribute to your meta tags to identify them and be able to override them with sub components.
// nuxt.config.js
head: {
link: [
{ hid: 'my-stylesheet', rel: 'preload', as: 'style', href: 'mycss' },
]
}
// page/amp.vue
head: {
link: [
{ hid: 'my-stylesheet', rel: 'preload', as: 'style', href: 'overridedHref' },
]
}
I had as well some issue, with head().
In dev mode I was not seeing any meta data rendered, but when I run nuxtgenereate static (which was my goal anyway) the links were there.
I am not sure, if you wanna go static, but I would try it, to see if it is there or check, what happens if you actually build the app.

Nuxt.js after page refresh meta are filled from config instead of head method

I had problem with meta in nuxt.js app. I want to fill dynamic meta tags in one detail page
--pages
----event
-----_id.vue
When I navigate on web site via link all work great. But if I just refresh page, meta tags use value from nuxt.config.js. For instance I got 'SiteTitle Nuxt.config.js' instead of 'SiteTitle - Some event title'.
Nuxt version 2.15.3
nuxt.config.js
export default {
head: {
titleTemplate: '%s - SiteTitle',
title: 'SiteTitle Nuxt.config.js',
htmlAttrs: {
lang: 'en'
},
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{hid: 'description', name: 'description', content: ''}
],
link: [
{rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}
]
}
components: true,
buildModules: [
'#nuxt/typescript-build',
'#nuxtjs/vuetify',
],
modules: [`enter code here`
'#nuxtjs/axios'
],
vuetify: {
customVariables: ['~/assets/variables.scss'],
},
axios: {
baseURL: 'https://api.someurl.com',
}
}
And _id.vue file
<template>
<v-card class="mt-6 mb-5" outlined>
<v-card-title>{{ model.title }}</v-card-title>
</v-card>
</template>
<script lang="ts">
import {Component, Vue} from "nuxt-property-decorator"
import {EventModel} from "~/api/models/EventModel";
import EventApi from "~/api/EventApi";
#Component({
async asyncData({params, $axios}) {
const eventApi = new EventApi($axios)
const model = await eventApi.get(parseInt(params.id))
return { model: model };
},
head(this: EventPage): object {
return {
title: "SiteTitle - " + this.model.title,
meta: [
{
hid: 'description',
name: 'description',
content: this.model.shortDescription
}
]
}
},
})
export default class EventPage extends Vue {
model = {} as EventModel
async fetch() {
}
}
</script>
I tried to call api in fetch, in this case meta values always have valid value when I refresh page, but Facebook Sharing Debugger get meta from nuxt.config.js in this case, and this solution is not suitable
Thanks for your help
You can do one thing
Create one plugin in that you can use this on router.beforeEach like this:
app.router.beforeEach(async(to, _, next) => {
document.title = to.meta.pageTitle ? ('Specify title - ' + ${to.meta.pageTitle}) :'Default Title';
})
In your router file you can do something like this:
{
path: '/path',
name: 'Name',
component: Component,
meta: {
pageTitle: 'Change Password'
}
}

Nuxt.js head function not working in Article

I am trying to add some Open Graph tags to each Article of my blog that is hosted in Wordpress.
This code is working when I run "npm run dev", but when I run "npm run generate && firebase deploy" is not doing the same.
This is the code that I am using:
head() {
return {
title: 'This',
meta: [
{
hid: `og:description`,
name: 'og:description',
content: 'title'
},
{
hid: `og:title`,
name: 'og:title',
content: 'title'
}
]
}
In my nuxt.config.js I have configured the following in the head
head() {
return {
title: 'That',
meta: [
{
hid: `og:description`,
name: 'og:description',
content: '3'
},
{
hid: `og:title`,
name: 'og:title',
content: '4'
}
]
}
In the article, the title that is showing is "This" but, the meta is showing the content in nuxt.config.js ("3","4") instead of ("title", "title")
What I would like to obtain is the meta tag of the article one in the with the SSR.
My problem was using spa (single page application) mode instead of universal.
My working settings in nuxt.config.js:
export default {
mode: 'universal', // changed from mode: 'spa'
...
}
I would try using the nuxt-seo package. It adds full support for setting the most common social media tags, including auto generating canonical tags for each of your articles/pages.
You can checkout the docs site, which has a full nuxt blog example.
After installing the nuxt-seo package in your project, add it to your nuxt-config.js file:
{
modules: [
'nuxt-seo'
],
seo: {
// Module Options
}
}
Then on each article/page, you can set the page specific title, description, and pretty much any other meta tag:
<template>
<h1>Hello World</h1>
</template>
<script>
export default {
head({ $seo }) {
return $seo({
title: 'Home Page',
description: 'Hello World Page',
keywords: 'hello, world, home',
})
}
}
</script>
PS: I am the maintainer of the nuxt-seo package.