Alaa
Alaa
NNuxt
Created by Alaa on 4/29/2025 in #❓・help
Nuxt2 displays wrong meta tags when the page is deleted
To Summarize: I'm stuck on this Nuxt 2 issue: when a user visits a non-existent profile URL, I throw an error in the fetch() method. This correctly triggers my custom error component, but the meta tags in the <head> (like title, description, og tags) remain from the last successful page and do not update or clear. Here’s what I have: The page fetches profile data in async fetch() and sets up metadata in head(). If the fetch fails, I throw a formatted error which renders a custom <error-component />. This is all wrapped inside <client-only>, including the error component being wrapped inside it too. I'm suspicious that head() isn't being recalculated on error, or maybe client-only is preventing it somehow? Has anyone run into this before? What's the best way to force a proper head/meta reset when a page results in a 404 or fetch error? Thanks in advance 🙏
7 replies
NNuxt
Created by Alaa on 4/29/2025 in #❓・help
Nuxt2 displays wrong meta tags when the page is deleted
I have a feeling that the issue is with the <client-only> tag especially with my error component looking like this
<template>
<client-only>
<div class="layout-class error error-404 flex w-full p-8 mb-4">
<div class="bg-white lg:bg-gray-10 rounded-xl w-full flex flex-col lg:flex-row-reverse items-center p-12" :dir="$store.state.dir">
<div class="error-image min-w-[240px] w-1/2 py-4 lg:py-0">
<svg-asset class="w-full" asset="error-404-en"></svg-asset>
</div>

<div class="error-body flex flex-col w-full lg:w-1/2 items-center lg:items-start space-y-4 py-4" :dir="$store.state.dir">
<svg-asset v-if="$store.state.timeZone != 'Asia/Tehran'" asset="logo" class="error-body-logo w-24 min-w-24"></svg-asset>

<h3 class="error-body-title text-lg font-bold">
{{ $t('sorry, the page you are looking for does not exist!') }}
</h3>

<p v-if="$store.state.timeZone != 'Asia/Tehran'" class="error-body-description">
{{ $t('but we suggest you register in for better coordination.') }}
</p>

<div v-if="$store.state.timeZone != 'Asia/Tehran'" class="flex lg:self-start">
<a class="error-body-link z-btn bg-yellow hover:bg-orange-500 text-white" :href="siteUrl">
{{ $t('view home page') }}
</a>
</div>
</div>
</div>
</div>
</client-only>
</template>

<script>
import SvgAsset from '@/components/svg-asset';

export default {
name: 'Error404',
components: {
SvgAsset,
},
computed: {
siteUrl() {
return `stuff here`;
},
},
mounted() {
this.$store.dispatch('setProfile', null);
},
};
</script>

<style scoped lang="scss">
.error-404 {
height: 100%;
}

@media only screen and (max-width: 768px) {
.error-body {
text-align: center;
}
}
</style>
<template>
<client-only>
<div class="layout-class error error-404 flex w-full p-8 mb-4">
<div class="bg-white lg:bg-gray-10 rounded-xl w-full flex flex-col lg:flex-row-reverse items-center p-12" :dir="$store.state.dir">
<div class="error-image min-w-[240px] w-1/2 py-4 lg:py-0">
<svg-asset class="w-full" asset="error-404-en"></svg-asset>
</div>

<div class="error-body flex flex-col w-full lg:w-1/2 items-center lg:items-start space-y-4 py-4" :dir="$store.state.dir">
<svg-asset v-if="$store.state.timeZone != 'Asia/Tehran'" asset="logo" class="error-body-logo w-24 min-w-24"></svg-asset>

<h3 class="error-body-title text-lg font-bold">
{{ $t('sorry, the page you are looking for does not exist!') }}
</h3>

<p v-if="$store.state.timeZone != 'Asia/Tehran'" class="error-body-description">
{{ $t('but we suggest you register in for better coordination.') }}
</p>

<div v-if="$store.state.timeZone != 'Asia/Tehran'" class="flex lg:self-start">
<a class="error-body-link z-btn bg-yellow hover:bg-orange-500 text-white" :href="siteUrl">
{{ $t('view home page') }}
</a>
</div>
</div>
</div>
</div>
</client-only>
</template>

<script>
import SvgAsset from '@/components/svg-asset';

export default {
name: 'Error404',
components: {
SvgAsset,
},
computed: {
siteUrl() {
return `stuff here`;
},
},
mounted() {
this.$store.dispatch('setProfile', null);
},
};
</script>

<style scoped lang="scss">
.error-404 {
height: 100%;
}

@media only screen and (max-width: 768px) {
.error-body {
text-align: center;
}
}
</style>
7 replies
NNuxt
Created by Alaa on 4/29/2025 in #❓・help
Nuxt2 displays wrong meta tags when the page is deleted
and I have the head component as this
head() {
// I do some operations here to push links properties

if (!this.$store.state.profile) {
return {
title: this.pageTitle,
link: links,
meta: [],
};
}

return {
title: this.pageTitle,
link: links,
meta: [
{ hid: 'description', name: 'description', content: this.welcomeMessage },

...(this.isNoindex ? [{ name: 'robots', content: 'noindex, nofollow, nosnippet, noarchive' }] : []),

// og tags
{ property: 'og:title', content: this.fullName, hid: 'og:title' },
{ property: 'og:url', content: this.userURL, hid: 'og:url' },
{ property: 'og:description', content: this.welcomeMessage, hid: 'og:description' },
{ property: 'og:author', content: this.fullName, hid: 'og:author' },
{ property: 'og:image', content: this.avatar, hid: 'og:image' },

// twitter tags
{ name: 'twitter:title', content: this.fullName, hid: 'twitter:title' },
{ name: 'twitter:description', content: this.welcomeMessage, hid: 'twitter:description' },
{ name: 'twitter:card', content: 'summary', hid: 'twitter:card' },
{ name: 'twitter:creator', content: `@${this.twitter}`, hid: 'twitter:creator' },
{ name: 'twitter:url', content: this.userURL, hid: 'twitter:url' },
{ name: 'twitter:image', content: this.avatar, hid: 'twitter:image' },
],
};
},
head() {
// I do some operations here to push links properties

if (!this.$store.state.profile) {
return {
title: this.pageTitle,
link: links,
meta: [],
};
}

return {
title: this.pageTitle,
link: links,
meta: [
{ hid: 'description', name: 'description', content: this.welcomeMessage },

...(this.isNoindex ? [{ name: 'robots', content: 'noindex, nofollow, nosnippet, noarchive' }] : []),

// og tags
{ property: 'og:title', content: this.fullName, hid: 'og:title' },
{ property: 'og:url', content: this.userURL, hid: 'og:url' },
{ property: 'og:description', content: this.welcomeMessage, hid: 'og:description' },
{ property: 'og:author', content: this.fullName, hid: 'og:author' },
{ property: 'og:image', content: this.avatar, hid: 'og:image' },

// twitter tags
{ name: 'twitter:title', content: this.fullName, hid: 'twitter:title' },
{ name: 'twitter:description', content: this.welcomeMessage, hid: 'twitter:description' },
{ name: 'twitter:card', content: 'summary', hid: 'twitter:card' },
{ name: 'twitter:creator', content: `@${this.twitter}`, hid: 'twitter:creator' },
{ name: 'twitter:url', content: this.userURL, hid: 'twitter:url' },
{ name: 'twitter:image', content: this.avatar, hid: 'twitter:image' },
],
};
},
And I also have this bit of code in my template
<client-only>
<template v-if="$fetchState.pending">
<div class="loading-spinner-box absolute top-0 left-0 right-0 bottom-0 backdrop-blur-sm z-10 flex justify-center">
<img alt="App logo" src="@/assets/svg/logo-mark-spinner.svg" width="48" height="auto" />
</div>
</template>
<template v-else-if="$fetchState.error">
<error-component :error="$fetchState.error" />
</template>
<client-only>
<template v-if="$fetchState.pending">
<div class="loading-spinner-box absolute top-0 left-0 right-0 bottom-0 backdrop-blur-sm z-10 flex justify-center">
<img alt="App logo" src="@/assets/svg/logo-mark-spinner.svg" width="48" height="auto" />
</div>
</template>
<template v-else-if="$fetchState.error">
<error-component :error="$fetchState.error" />
</template>
7 replies