admin管理员组

文章数量:1304225

Background

I am now setting up a new Nuxt 3 project and integrating Nuxt-i18n into it. My project would finally be deployed to Github Page after development.

prefix_and_default is used as the routing strategy now, where these URLs should be available after nuxi generate:

  • /
  • /
  • /
  • /

As a site having multi-language, I would certainly want them to be having different site titles or descriptions in corresponding languages. So that in my translation files, I wrote down the corresponding words:

// en.json
{
  "app": {
    "title": "foo",
    "description": "bar"
  }
}
// zh.json
{
  "app": {
    "title": "標題",
    "description": "內容"
  }
}
// ja.json
{
  "app": {
    "title": "タイトル",
    "description": "内容"
  }
}

I have also set ssr: false in nuxt config.


Problem

The title and meta tag are not there inside <head> after nuxi generate, where I believe that they need to be statically written inside <head> so to make them work? (e.g. Sharing via Discord / Twitter etc.)


What I tried

Method 1 (Inside nuxt.config.ts)

// nuxt.config.ts
{
  app: {
    head: {
      htmlAttrs: {
        lang: 'en',
      },
      title: 'foo',
      link: [
        { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' },
        { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
        { rel: 'shortcut, icon', href: '/favicon.ico' },
        { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
        { rel: 'manifest', href: '/site.webmanifest' },
      ],
      meta: [
        { name: 'description', content: 'bar' },
        { property: 'og:title', content: 'foo' },
        { property: 'og:description', content: 'bar' },
      ],
    },
  }
}

This works. They are written into <head> in the output of nuxi generate. However I think I cannot use the i18n t here?

Method 2 (Using useHead() and useSeoMeta)

// app.vue
useHead({
  htmlAttrs: {
    lang: 'zh',
  },
  link: [
    { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' },
    { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
    { rel: 'shortcut, icon', href: '/favicon.ico' },
    { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
    { rel: 'manifest', href: '/site.webmanifest' },
  ],
})

useSeoMeta({
  title: t('app.title'),
  ogTitle: t('app.title'),
  description: t('app.description'),
  ogDescription: t('app.description'),
})

This works only when browsing the website. They are NOT written into <head> in the output of nuxi generate


In conclusion:

  1. Actually, are title and og meta tags need to be statically written inside <head> so to make them work?
  2. If so, how could I achieve this in nuxt 3 with nuxi generate?

Background

I am now setting up a new Nuxt 3 project and integrating Nuxt-i18n into it. My project would finally be deployed to Github Page after development.

prefix_and_default is used as the routing strategy now, where these URLs should be available after nuxi generate:

  • https://example/
  • https://example/zh/
  • https://example/en/
  • https://example/ja/

As a site having multi-language, I would certainly want them to be having different site titles or descriptions in corresponding languages. So that in my translation files, I wrote down the corresponding words:

// en.json
{
  "app": {
    "title": "foo",
    "description": "bar"
  }
}
// zh.json
{
  "app": {
    "title": "標題",
    "description": "內容"
  }
}
// ja.json
{
  "app": {
    "title": "タイトル",
    "description": "内容"
  }
}

I have also set ssr: false in nuxt config.


Problem

The title and meta tag are not there inside <head> after nuxi generate, where I believe that they need to be statically written inside <head> so to make them work? (e.g. Sharing via Discord / Twitter etc.)


What I tried

Method 1 (Inside nuxt.config.ts)

// nuxt.config.ts
{
  app: {
    head: {
      htmlAttrs: {
        lang: 'en',
      },
      title: 'foo',
      link: [
        { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' },
        { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
        { rel: 'shortcut, icon', href: '/favicon.ico' },
        { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
        { rel: 'manifest', href: '/site.webmanifest' },
      ],
      meta: [
        { name: 'description', content: 'bar' },
        { property: 'og:title', content: 'foo' },
        { property: 'og:description', content: 'bar' },
      ],
    },
  }
}

This works. They are written into <head> in the output of nuxi generate. However I think I cannot use the i18n t here?

Method 2 (Using useHead() and useSeoMeta)

// app.vue
useHead({
  htmlAttrs: {
    lang: 'zh',
  },
  link: [
    { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' },
    { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
    { rel: 'shortcut, icon', href: '/favicon.ico' },
    { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' },
    { rel: 'manifest', href: '/site.webmanifest' },
  ],
})

useSeoMeta({
  title: t('app.title'),
  ogTitle: t('app.title'),
  description: t('app.description'),
  ogDescription: t('app.description'),
})

This works only when browsing the website. They are NOT written into <head> in the output of nuxi generate


In conclusion:

  1. Actually, are title and og meta tags need to be statically written inside <head> so to make them work?
  2. If so, how could I achieve this in nuxt 3 with nuxi generate?
Share Improve this question edited Feb 5 at 3:38 Oliver asked Feb 4 at 8:33 OliverOliver 475 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

A very common structure in app.vue to work with static generated pages would look like the one below (I also use it):

  <Html :lang="t('locale')" :class="darkMode ? 'dark' : ''">
  <Head>
    <Title>{{ t("slogan") }} </Title>
    <Meta charset="UTF-8" />
    <Meta name="title" :content="t('slogan')" />
    <Meta name="description" :content="t('herosection:description')" />
    <!-- Open Graph Meta Tags -->
    <Meta property="og:title" :content="t('slogan')" />
    <Meta property="og:description" :content="t('herosection:description')" />
    <Meta property="og:image" content="https://r2.laundrybag.ch/img/home/imagem-04.jpg" />
    <Meta property="og:url" content="https://laundrybag.ch" />
    <Meta property="og:type" content="website" />
  </Head>

  <Body>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
  </Body>


  <ClientOnly>

  </ClientOnly>

  <Toast />
  </Html>

This would work for all pages of your app. If you want a more specific description, you can use the code below inside your pages (e.g., pages/something.vue):

<script lang="ts" setup>
const { t } = useI18n()
useHead({
  meta: [
    {
      name: 'XAXAXA',
      content: t('some_content')
    },
    {
      name: 'title',
      content: t('privacy_policy')
    },
    {
      property: 'og_title',
      content: t('slogan_privacy_policy')
    }
  ]
})
</script>

It will replace the values you set up in app.vue.

You can also use useHead() inside app.vue. It should work.

本文标签: nuxtjsHow to properly set multilanguage title and open graph meta tags in Nuxt 3Stack Overflow