install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/nuxt-seo-metadata" ~/.claude/skills/intense-visions-harness-engineering-nuxt-seo-metadata && rm -rf "$T"
manifest:
agents/skills/claude-code/nuxt-seo-metadata/SKILL.mdsource content
Nuxt SEO Metadata
Set page titles, Open Graph tags, canonical URLs, and structured data with useSeoMeta and useHead
When to Use
- You need to set unique
,<title>
, or OG tags per page<meta description> - You are implementing social sharing previews (og:image, twitter:card)
- You need to configure robots directives or canonical URLs
- You are adding JSON-LD structured data for search engine rich results
- You want to set global defaults and override them per page
Instructions
useSeoMeta — typed meta tags (preferred):
- Use
for all standard SEO and OG meta tags. It provides full TypeScript autocompletion and prevents common tag duplication mistakes:useSeoMeta
// pages/product/[id].vue useSeoMeta({ title: product.name, description: product.description, ogTitle: product.name, ogDescription: product.description, ogImage: product.imageUrl, ogType: 'product', twitterCard: 'summary_large_image', twitterTitle: product.name, twitterImage: product.imageUrl, });
- Use
in SSR-only contexts for better performance (skips client-side hydration):useServerSeoMeta
useServerSeoMeta({ robots: 'index, follow', ogSiteName: 'My Site', });
useHead — generic head management:
- Use
for tags not covered byuseHead
(canonical, structured data, custom link tags):useSeoMeta
useHead({ link: [{ rel: 'canonical', href: `https://mysite.com${route.path}` }], script: [ { type: 'application/ld+json', innerHTML: JSON.stringify({ '@context': 'https://schema.org', '@type': 'Product', name: product.name, offers: { '@type': 'Offer', price: product.price }, }), }, ], });
- Set global defaults in
or a layout, then override per page:app.vue
// app.vue useHead({ titleTemplate: (title) => (title ? `${title} — My Site` : 'My Site'), htmlAttrs: { lang: 'en' }, meta: [{ name: 'theme-color', content: '#ffffff' }], });
Reactive meta — computed values:
- Pass computed refs or reactive values to update meta when data changes:
const { data: post } = await useAsyncData('post', () => fetchPost(id)); useSeoMeta({ title: () => post.value?.title ?? 'Loading...', description: () => post.value?.excerpt, ogImage: () => post.value?.coverImage, });
Robots configuration:
- Configure robots globally in
:nuxt.config.ts
export default defineNuxtConfig({ app: { head: { meta: [{ name: 'robots', content: 'index, follow' }], }, }, });
- Block specific pages from indexing:
// pages/admin/settings.vue useSeoMeta({ robots: 'noindex, nofollow' });
nuxt-site-config module:
- For production-grade SEO including automatic canonical URLs, robots.txt, and sitemap integration, use the
module family:@nuxtjs/seo
// nuxt.config.ts export default defineNuxtConfig({ modules: ['nuxt-site-config'], site: { url: 'https://mysite.com', name: 'My Site', defaultLocale: 'en', }, });
Details
useSeoMeta vs. useHead:
useSeoMeta is a higher-level abstraction built on top of useHead. It knows which meta tags belong in name vs. property attributes, prevents duplicate tags, and offers typed keys. Prefer it for all standard SEO and social meta. Use useHead for raw head control (scripts, links, custom attributes).
Tag deduplication:
Nuxt uses
@unhead/vue under the hood. Tags are deduplicated by key — the most recently called composable wins. This means a page's useSeoMeta call overrides the layout's defaults without any explicit merge logic.
Open Graph image requirements:
- Minimum size: 1200x630px for optimal display
- Use absolute URLs (include the full
origin)https:// - For dynamic OG images, consider
which generates them at build time or on-demand@nuxtjs/og-image
// With @nuxtjs/og-image defineOgImage({ component: 'MyOgImageTemplate', title: post.title, description: post.excerpt, });
Structured data (JSON-LD) patterns:
Common schema types for Nuxt apps:
— blog posts, newsArticle
— e-commerceProduct
— navigation pathBreadcrumbList
— company info in layoutOrganization
— FAQ sectionsFAQPage
Place organization-level JSON-LD in the default layout; page-specific data in individual pages.
Performance note:
useServerSeoMeta renders meta tags only during SSR and skips the client-side hydration step, reducing JavaScript execution. Use it for any meta that does not need to change after initial render.
Source
https://nuxt.com/docs/getting-started/seo-meta
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.