{"_path":"/blog/nuxt3-nuxtcontent2-meta-tags","_draft":false,"_partial":false,"_empty":false,"title":"Adding Meta tags in Nuxt 3 and Nuxt Content 2","description":"While Nuxt v3 is still not released (RC) and docs are missing some pages, it doesn't stop enthusiasts from using it.","excerpt":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"adding-meta-tags-in-nuxt-3-and-nuxt-content-2"},"children":[{"type":"text","value":"Adding Meta tags in Nuxt 3 and Nuxt Content 2"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a developer, I love to build websites. I enjoy the process itself and the results I see.\nAs a product owner, I want to make the website noticeable in search engines and social media. To make that happen, you need to work on your website Meta tags. Adding Meta, Open Graph, and Twitter Meta tags are the same in Nuxt."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for now, Nuxt 3 is still not released, so that things may change in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are several ways to set the Meta tags in Nuxt 3. Not all of them are dynamic:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"nuxt.config.ts (dynamic ❌)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useHead composable (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Meta components (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useMeta (deprecated)"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's see how you can use them in your code."}]},{"type":"element","tag":"h3","props":{"id":"nuxtconfigts"},"children":[{"type":"text","value":"Nuxt.config.ts"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can set the META tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":". I believe this is a good place for the tags\nthat rarely / never change."}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtConfig({\n // Global page headers: https://go.nuxtjs.dev/config-head\n app: {\n head: {\n htmlAttrs: {\n lang: 'en'\n },\n meta: [\n {name: 'viewport', content: 'width=device-width, initial-scale=1'},\n {property: 'og:site_name', content: 'XDEVS.PRO'},\n {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'},\n {property: 'og:url', content: 'https://xdevs.pro/'},\n {property: \"og:type\", content: \"website\"},\n ],\n link: [\n {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}\n ]\n },\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export default defineNuxtConfig({\n // Global page headers: https://go.nuxtjs.dev/config-head\n app: {\n head: {\n htmlAttrs: {\n lang: 'en'\n },\n meta: [\n {name: 'viewport', content: 'width=device-width, initial-scale=1'},\n {property: 'og:site_name', content: 'XDEVS.PRO'},\n {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'},\n {property: 'og:url', content: 'https://xdevs.pro/'},\n {property: \"og:type\", content: \"website\"},\n ],\n link: [\n {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}\n ]\n },\n },\n})\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-composable"},"children":[{"type":"text","value":"useHead composable"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It can be used to set constant Meta tags, or you can use it in combination with "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useRoute"}]},{"type":"text","value":", which adds a bit of flexibility. "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" can be used both globally and on per page basis."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In your "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]},{"type":"text","value":", you can set global Meta tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable:"}]},{"type":"element","tag":"code","props":{"code":"\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Any other page component, e.g., "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"blog/index.vue"}]}]},{"type":"element","tag":"code","props":{"code":"// You can override the global title \n// that was set in app.vue like this\nuseHead({ \n title: 'XDEVS Team Blog – our latest articles 📚', \n}) \n\n// it won't have direct access to your meta tags\ndefinePageMeta({ \n layout: 'blog', \n ogType: 'OgType',\n otherArgs: youWantToPass \n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"// You can override the global title \n// that was set in app.vue like this\nuseHead({ \n title: 'XDEVS Team Blog – our latest articles 📚', \n}) \n\n// it won't have direct access to your meta tags\ndefinePageMeta({ \n layout: 'blog', \n ogType: 'OgType',\n otherArgs: youWantToPass \n})\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-title-templates"},"children":[{"type":"text","value":"useHead Title Templates"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, something we can use to set the page title dynamically. Unfortunately, it works only with the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" tag."}]},{"type":"element","tag":"code","props":{"code":"// in your app.vue, add the following.\nconst route = useRoute()\n\nuseHead({\n // route.meta.title is is defined in definePageMeta({}) in another page component\n titleTemplate: (titleChunk) => {\n return titleChunk || route.meta.title || 'Site Default Title'\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"// in your app.vue, add the following.\nconst route = useRoute()\n\nuseHead({\n // route.meta.title is is defined in definePageMeta({}) in another page component\n titleTemplate: (titleChunk) => {\n return titleChunk || route.meta.title || 'Site Default Title'\n },\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now you can set the title using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" on any other page of your website."}]},{"type":"element","tag":"code","props":{"code":"useHead({\n title: 'Some other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"useHead({\n title: 'Some other page title.',\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"or"}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n title: 'Any other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"definePageMeta({\n title: 'Any other page title.',\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In case no title is set, the default title will be used."}]},{"type":"element","tag":"h3","props":{"id":"definepagemeta"},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" is extracted at build time via a macro, so it can't be set dynamically.\nIt extends "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"route.meta"}]},{"type":"text","value":" with any non-dynamic information you pass. It's important to notice that you can't set Meta tags using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" without using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"page1.vue"}]}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n someInformation: 'You may need elsewhere available at a build time.'\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"definePageMeta({\n someInformation: 'You may need elsewhere available at a build time.'\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]}]},{"type":"element","tag":"code","props":{"code":"const route = useRoute()\n\nconsole.log(route.meta.someInformation)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const route = useRoute()\n\nconsole.log(route.meta.someInformation)\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"meta-components"},"children":[{"type":"text","value":"Meta components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may find the Meta component a more flexible and valuable solution to set Meta tags."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt provides "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"