SEO
Configure shared site metadata, page-level SEO tags, favicon links, robots.txt and sitemap generation for a Nuxt project.
Installation
npx alixan-ui-nuxt add seoThis command copies
app/config/site/site.ts, app/config/site/favicon.ts and app/composables/usePageMeta.ts. After copying, replace the example values in site.ts with your own domain, project name, default title, description and OG image.Sitemap
Install Nuxt Sitemap before adding sitemap options to nuxt.config.ts.
npx nuxt module add @nuxtjs/sitemapSitemap helps search robots find available routes and understand which pages should be crawled. After deployment, check that your sitemap is available from the URL used in robots.txt.
For more detailed information, visit the Nuxt Sitemap documentation.
Site Config
app/config/site/site.ts
export const siteConfig = {
// Replace with your production domain.
url: 'https://nuxt.ui.alixan.kz',
// Replace with your project name.
name: 'Alixan UI',
// Replace with your default page title.
title: 'Alixan UI - Nuxt UI Components',
// Replace with your default SEO description.
description:
'Modern, minimal and production-ready UI components for Nuxt 4, Vue 3 and TypeScript.',
// Replace with your default Open Graph image.
ogImage: 'https://nuxt.ui.alixan.kz/og-image.png',
}nuxt.config.ts
import { siteConfig } from './app/config/site/site'
export default defineNuxtConfig({
site: {
url: siteConfig.url,
name: siteConfig.name,
},
modules: ['@nuxtjs/sitemap'],
sitemap: {
autoLastmod: true,
},
})Initial Head
For favicon file generation, see the IconKitchen guide .
app/config/site/favicon.ts
export const favicon = [
{
rel: 'icon',
href: '/favicon.ico',
sizes: 'any',
},
{
rel: 'apple-touch-icon',
href: '/icons/apple-touch-icon.png',
},
{
rel: 'manifest',
href: '/site.webmanifest',
},
]app.vue
<script setup lang="ts">
import { favicon } from './config/site/favicon'
const { locale } = useI18n()
usePageMeta() // initialize default SEO meta
useHead({
htmlAttrs: { lang: locale.value }, // initialize lang attr for html
link: favicon, // initialize favicon
})
</script>Page Meta
app/composables/usePageMeta.ts
usePageMeta centralizes title, description, Open Graph and Twitter tags. Pages only pass values that differ from defaults. It uses useI18n().t internally, so page values can be translation keys while siteConfig defaults can stay plain strings when missingWarn is disabled.import { siteConfig } from '~/config/site/site'
interface PageMetaOptions {
title?: string
description?: string
img?: string
}
export const usePageMeta = (payload?: PageMetaOptions): void => {
const { t } = useI18n()
const route = useRoute()
const metaTitle = t(payload?.title || siteConfig.title)
const metaDescription = t(payload?.description || siteConfig.description)
const metaImage = payload?.img || siteConfig.ogImage
useSeoMeta({
title: metaTitle,
description: metaDescription,
ogType: 'website',
ogSiteName: siteConfig.name,
ogTitle: metaTitle,
ogDescription: metaDescription,
ogUrl: siteConfig.url + route.path,
ogImage: metaImage,
twitterCard: 'summary_large_image',
twitterTitle: metaTitle,
twitterDescription: metaDescription,
twitterImage: metaImage,
})
}pages/button.vue
Call
usePageMeta in each page. If a field is omitted, the default from siteConfig is used.<script setup lang="ts">
usePageMeta({
title: 'componentDocs.button.metaTitle',
description: 'componentDocs.button.description',
})
</script>Robots
Add public/robots.txt so crawlers can discover your sitemap. Replace the example domain with your production domain.
public/robots.txt
User-Agent: *
Disallow:
# Replace this domain with your own.
Sitemap: https://nuxt.ui.alixan.kz/sitemap_index.xml