Carlos Valdes Web
Carlos Valdes Web

Reputation: 65

Nuxt 3: Page Title Appears as <title>undefined</title> in Google

I'm working on a Nuxt 3 project, and I've encountered an issue where Google search results display my page title as undefined, even though the title appears correctly in the HTML tags. Below is the relevant code from my project:

Undefined title in google serp

Search console

Undefined title in search console

app.vue

<script lang="ts" setup>
const config = useRuntimeConfig();
const route = useRoute();

const i18nHead = useLocaleHead({
  addDirAttribute: true,
  identifierAttribute: "id",
  addSeoAttributes: true,
});

declare const window: any;

onMounted(() => {
  if (window.tidioChatApi) {
    window.tidioChatApi.on("ready", onTidioChatApiReady);
  } else {
    document.addEventListener("tidioChat-ready", onTidioChatApiReady);
  }
});

const onTidioChatApiReady = () => {
  window.tidioChatApi.open();
};

const { t, locale } = useI18n();

const title = computed(() =>
  (route.meta.title
    ? t(route.meta.title as string, { appName: config.public.appName })
    : undefined) as any,
);
const description = computed(() =>
  route.meta.description ? t(route.meta.description as string) : undefined,
);

useHead({
  title,
  link: () => [
    ...(i18nHead.value.link || []),
    { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
  ],
  meta: () => [
    ...(i18nHead.value.meta || []),
    { name: "description", content: description.value },
    { property: "og:title", content: title.value },
    { property: "og:description", content: description.value },
    { property: "og:site_name", content: config.public.appName as string },
    { property: "og:image", content: config.public.frontendUrl + "/images/meta_image.webp" },
    { property: "og:type", content: "website" },
    { name: "twitter:card", content: "summary_large_image" },
    { name: "twitter:title", content: title.value },
    { name: "twitter:description", content: description.value },
    { name: "twitter:image", content: config.public.frontendUrl + "/images/meta_image.webp" },
  ],
  htmlAttrs: {
    lang: () => i18nHead.value.htmlAttrs.lang,
    dir: () => i18nHead.value.htmlAttrs.dir,
  },
});
</script>

<template>
  <div>
    <NuxtLoadingIndicator color="repeating-linear-gradient(to right,#6e20e1 0%,#8045fd 50%,#6e20e1 100%)" :height="3" />
    <NuxtLayout>
      <NuxtPage />
    </NuxtLayout>
    <CookieControl v-if="locale === 'es'" locale="es" />
    <CookieControl v-else locale="en" />
    <UNotifications :ui="{ strategy: 'override' }" />
  </div>
</template>

layouts/guest-layout.vue

<script lang="ts" setup>
const sanctumClient = useSanctumClient();
const { data: products } = useAsyncData<Product[]>(
  "products",
  () =>
    sanctumClient("/products", {
      headers: {
        "Accept-Language": useNuxtApp().$i18n.localeProperties.value.code,
      },
    }),
  {
    lazy: true,
  },
);
</script>
<template>
  <div class="bg-white dark:bg-gray-900 min-h-screen">
    <TheMenu />
    <UMain>
      <slot />
    </UMain>
    <ProModal v-if="products" :products="products" />
    <TheFooter />
  </div>
</template>

pages/index.vue

<script lang="ts" setup>
definePageMeta({
  title: "landing.summarizer.title",
  description: "landing.summarizer.description",
  layout: "guest-layout",
});

const { t } = useI18n();
const localePath = useLocalePath();
const { isAuthenticated } = useSanctumAuth();

const faq = [
  {
    label: t("landing.summarizer.faq.1.label"),
    content: t("landing.summarizer.faq.1.content"),
  },
  {
    label: t("landing.summarizer.faq.2.label"),
    content: t("landing.summarizer.faq.2.content"),
  },
  // ...more FAQ items
];
</script>

<template>
  <div>
<ULandingHero
      :ui="{
        wrapper: 'py-4 sm:py-8 md:py-8',
        container: 'gap-4 sm:gap-y-4',
        description: 'mt-2 text-base',
      }"
      :title="$t('landing.summarizer.hero.title')"
      :description="$t('landing.summarizer.hero.description')"
    >
      <SummariesGuestSummarizer />
    </ULandingHero>

    <ULandingSection
      style="
        background: linear-gradient(
          180deg,
          #f8f4ff 0%,
          rgba(255, 255, 255, 0) 100%
        );
      "
      :ui="{
        wrapper: 'pt-16 sm:pt-20 pb-0 sm:pb-0',
      }"
    >
    <!-- More content... -->
  </div>
</template>

Despite setting the title in the definePageMeta and using useHead, Google search results display the title as undefined.

Steps I've Taken to Debug:

Additional Information:

Upvotes: 0

Views: 144

Answers (0)

Related Questions