- Nuxt
Nuxt SEO設定|useSeoMeta・sitemap・OG画像を実出力で解説
NuxtのSEO設定は、「ページごとのメタ情報は useSeoMeta」「サイト全体の共通設定は nuxt.config.ts」「sitemap.xml・robots.txt・OG画像・構造化データは @nuxtjs/seo」の3層で考えると整理できます。 NuxtはSSR(サーバーで描画)が既定なので、useSeoMeta で書いた内容はそのままHTMLの <head> に入り、検索エンジンやSNSのクローラーが読めます。
この記事では、Nuxt 4.5.2 と @nuxtjs/seo 5.3.16 で、<head> を設定するAPIの使い分けを表にまとめ、title・canonical・OGP・robots・JSON-LD・hreflang をコピペ用コードで載せます。さらに、ビルドしたサーバーから curl で取得した <head>・sitemap.xml・robots.txt の実出力と、OG画像で日本語が表示されなかった現象の解決手順を載せます。
Nuxt SEO設定の早見表
| やりたいこと | 書き方 | 書く場所 |
|---|---|---|
全ページ共通の lang・favicon |
app: { head: { htmlAttrs: { lang: 'ja' }, link: [...] } } |
nuxt.config.ts |
| タイトルに「|サイト名」を付ける | useHead({ titleTemplate: ... }) |
app/app.vue |
| ページのtitle・description | useSeoMeta({ title, description }) |
各ページ |
| OGP・Twitterカード | useSeoMeta({ ogTitle, ogType, twitterCard }) |
各ページ |
| canonical | useHead({ link: [{ rel: 'canonical', href }] })(@nuxtjs/seo なら自動) |
各ページ |
| 多言語の hreflang | useHead({ link: [{ rel: 'alternate', hreflang, href }] }) |
各ページ |
| 検索に載せない | routeRules: { '/admin/**': { robots: false } } |
nuxt.config.ts |
| 構造化データ(JSON-LD) | useSchemaOrg([defineArticle({...})]) または useHead({ script: [...] }) |
各ページ |
| sitemap.xml | @nuxtjs/sitemap(動的URLは sitemap.sources) |
nuxt.config.ts + server/api |
| robots.txt | @nuxtjs/robots(robots.disallow) |
nuxt.config.ts |
| OG画像を自動生成 | defineOgImage('Card.takumi', { title }) |
各ページ + app/components/OgImage/ |
- ページごとの設定は
useSeoMeta、それ以外の<head>要素はuseHeadが基本です。 @nuxtjs/seoを入れると、canonical・og:url・og:site_name・robots メタ・WebSite の構造化データが自動で出力されました(後述の実出力)。- OG画像に日本語を入れるときは日本語フォントの設定が必須です。既定のフォント(Inter)のままだと文字が表示されませんでした。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Nuxt SEO設定|useSeoMeta・sitemap・OG画像を実出力で解説」
検証環境
| パッケージ | バージョン | 役割 |
|---|---|---|
| nuxt | 4.5.2(Vue 3.5.43、Nitro 2.13.4) | 本体 |
| @nuxtjs/seo | 5.3.16 | 下のモジュールをまとめて導入 |
| 同梱モジュール | sitemap 8.5.1 / robots 6.2.3 / og-image 6.9.1 / schema-org 6.4.0 / seo-utils 8.5.2 / site-config 4.2.3 | sitemap.xml・robots.txt・OG画像・JSON-LD・canonical補完・サイト共通設定 |
| @takumi-rs/core | 2.14.0 | OG画像のレンダラー |
| @nuxt/fonts | 0.14.0 | OG画像のフォント |
Node.js 22.22.2 で nuxt build し、node .output/server/index.mjs で起動したサーバーに curl を送りました。
head を設定する方法の使い分け
| 方法 | 書く場所 | 向いている用途 | 注意点 |
|---|---|---|---|
app.head |
nuxt.config.ts |
全ページ共通の固定値(lang、favicon、viewport) | リアクティブな値は使えない |
useHead |
app.vue・レイアウト・ページ |
titleTemplate、link(canonical・hreflang)、script(JSON-LD) | 何でも書けるが、メタタグは useSeoMeta の方が型が効く |
useSeoMeta |
ページ | title、description、OGP、Twitterカード | キー名の打ち間違いを型でチェックできる。関数を渡すとリアクティブ |
useServerSeoMeta |
ページ | サーバーでだけ出せばよいメタ | クライアントのJSに含まれない。Nuxt 5では自動インポート対象外になる予定 |
definePageMeta({ title }) |
ページ | @nuxtjs/seo 利用時のタイトル指定 | モジュール(seo-utils)が <title> に反映する |
useSeoMeta は ogTitle → og:title、twitterCard → twitter:card のように、name と property の使い分けを自動でしてくれるのが利点です。
手順1:インストールとサイト全体の設定
npm install nuxt@4.5.2 @nuxtjs/seo @nuxt/fonts @takumi-rs/core
# 公式の案内では npx nuxt module add seo でも導入できます
@takumi-rs/core は OG画像のレンダラーです。nuxt-og-image v6 からは同梱されず、Takumi(推奨)か Satori(satori + @resvg/resvg-js)を自分で入れます。
// nuxt.config.ts(Nuxt 4.5.2 + @nuxtjs/seo 5.3.16)
export default defineNuxtConfig({
compatibilityDate: '2026-09-01',
devtools: { enabled: false },
modules: ['@nuxt/fonts', '@nuxtjs/seo'],
// OG画像用の日本語フォント(public/fonts/ に置いたファイルを使う)
fonts: {
// 外部のフォントサービスに問い合わせない(社内ネットワークやCIで便利)
providers: { google: false, googleicons: false, bunny: false, fontshare: false, fontsource: false },
families: [
{ name: 'Noto Sans JP', provider: 'local', weights: [400, 700], global: true },
],
},
// サイト全体の情報(sitemap・robots・OG画像・schema.org が共通で参照)
site: {
url: 'https://example.com',
name: 'サンプル技術ブログ',
description: 'Nuxtの設定を実例で解説するサンプルサイトです。',
defaultLocale: 'ja',
},
// 全ページ共通の <head>
app: {
head: {
htmlAttrs: { lang: 'ja' },
link: [{ rel: 'icon', type: 'image/png', href: '/favicon.png' }],
},
},
// 動的ページのURLを sitemap に追加
sitemap: {
sources: ['/api/__sitemap__/urls'],
},
// robots.txt に追加する指示
robots: {
disallow: ['/admin'],
},
// 構造化データ(組織情報)
schemaOrg: {
identity: { type: 'Organization', name: 'サンプル技術ブログ' },
},
routeRules: {
'/admin/**': { robots: false },
},
})
いちばん大事なのは site.url です。 canonical・og:url・og:image・sitemap.xml の絶対URLはこの値から作られます(環境変数 NUXT_SITE_URL で上書き可)。
手順2:titleTemplate でサイト名を付ける
<!-- app/app.vue -->
<script setup lang="ts">
useHead({
titleTemplate: (title) => (title ? `${title}|サンプル技術ブログ` : 'サンプル技術ブログ'),
})
</script>
<template>
<NuxtPage />
</template>
ページで title: 'トップ' と書くと <title>トップ|サンプル技術ブログ</title> になりました。関数なら未設定時にサイト名だけを出せます。
手順3:ページごとの title・description・OGP・Twitterカード
APIから取得したデータでメタ情報を作る、記事ページの完成形です。
// server/api/articles/[slug].get.ts(説明用の固定データ)
const articles: Record<string, { title: string; summary: string; published: string; updated: string }> = {
'nuxt-seo': { title: 'NuxtのSEO設定', summary: 'useSeoMetaとsitemapの設定例です。', published: '2026-09-01', updated: '2026-09-20' },
// 'nuxt-route-rules': { ... } も同じ形で登録
}
export default defineEventHandler((event) => {
const slug = getRouterParam(event, 'slug')!
const article = articles[slug]
if (!article) throw createError({ status: 404, statusText: 'Article Not Found' })
return { slug, ...article }
})
<!-- app/pages/articles/[slug].vue -->
<script setup lang="ts">
const route = useRoute()
const slug = route.params.slug as string
const { data: article } = await useFetch(`/api/articles/${slug}`)
if (!article.value) {
throw createError({ status: 404, statusText: 'Page Not Found', fatal: true })
}
// title / description / OGP / Twitterカード
useSeoMeta({
title: () => article.value?.title,
description: () => article.value?.summary,
ogTitle: () => article.value?.title,
ogDescription: () => article.value?.summary,
ogType: 'article',
articlePublishedTime: () => article.value?.published,
articleModifiedTime: () => article.value?.updated,
twitterCard: 'summary_large_image',
})
// canonical と hreflang(多言語版がある前提の例)
const url = `https://example.com/articles/${slug}`
useHead({
link: [
{ rel: 'canonical', href: url },
{ rel: 'alternate', hreflang: 'ja', href: url },
{ rel: 'alternate', hreflang: 'en', href: `https://example.com/en/articles/${slug}` },
{ rel: 'alternate', hreflang: 'x-default', href: url },
],
})
// 構造化データ(nuxt-schema-org)
useSchemaOrg([
defineArticle({
headline: article.value.title,
datePublished: article.value.published,
dateModified: article.value.updated,
}),
])
// OG画像(後述のコンポーネントで生成)
defineOgImage('Card.takumi', { title: article.value.title, subtitle: article.value.summary })
</script>
<template>
<article>
<h1>{{ article?.title }}</h1>
<p>{{ article?.summary }}</p>
</article>
</template>
ポイントは3つです。
title: () => article.value?.titleのように関数で渡すと、データが変わったときにも追従します(リアクティブ)。- 記事がないときは
createError({ status: 404, fatal: true })で404を返します。実測でも/articles/unknownは HTTP 404 になり、ソフト404(200で「見つかりません」を表示)を避けられました。 hreflangは 多言語版が実在するときだけ書きます。本格的な多言語サイトでは@nuxtjs/i18nのuseLocaleHead()で自動生成する方法もあります(本記事では未検証)。
実出力:SSRで返る
curl -s localhost:7451/articles/nuxt-seo で取得したHTMLの <head> です(JS・CSSの <link> と <script> は省略、改行を追加)。
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NuxtのSEO設定|サンプル技術ブログ</title>
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://example.com/_og/d/c_Card.takumi,title_~TnV4dOOBrlNFT-ioreWumg,subtitle_~dXNl...,s_7YNadCxtp8GXzt8I.png">
<meta property="og:image" content="(twitter:image と同じURL)">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta name="twitter:image:width" content="1200">
<meta property="og:image:height" content="600">
<meta name="twitter:image:height" content="600">
<link rel="icon" type="image/png" href="/favicon.png">
<meta property="og:type" content="article">
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1">
<meta name="description" content="useSeoMetaとsitemapの設定例です。">
<meta property="og:title" content="NuxtのSEO設定">
<meta property="og:description" content="useSeoMetaとsitemapの設定例です。">
<meta property="article:published_time" content="2026-09-01">
<meta property="article:modified_time" content="2026-09-20">
<link rel="canonical" href="https://example.com/articles/nuxt-seo">
<link rel="alternate" hreflang="ja" href="https://example.com/articles/nuxt-seo">
<link rel="alternate" hreflang="en" href="https://example.com/en/articles/nuxt-seo">
<link rel="alternate" hreflang="x-default" href="https://example.com/articles/nuxt-seo">
<meta property="og:url" content="https://example.com/articles/nuxt-seo">
<meta property="og:site_name" content="サンプル技術ブログ">
自分で書いていないのに出力されたものは次のとおりです。
| 出力 | 出したもの |
|---|---|
og:image・twitter:image・サイズ(1200×600) |
nuxt-og-image(defineOgImage) |
robots(index, follow, max-image-preview:large…) |
@nuxtjs/robots |
og:url・og:site_name |
nuxt-seo-utils(site.url・site.name から) |
| JSON-LD(WebSite・WebPage・Organization・Article・ImageObject) | nuxt-schema-org |
トップページでは og:title を書かなかったため、title から推測した値が data-infer 属性つきで自動で入りました。
canonical は自動で付き、クエリも外れる
canonical を書いていないトップページとFAQページでも、canonical が出力されました。クエリ文字列付きでアクセスしても、canonical からは外れています。
$ curl -s "localhost:7451/?utm_source=x" | grep -o '<link rel="canonical"[^>]*>'
<link rel="canonical" href="https://example.com/">
@nuxtjs/seo を使うなら、canonical の手書きは「別のURLを正規にしたい」ときだけで済みます(手書きと同じ値なら1つにまとまりました)。モジュールなしなら useHead で書きます。
構造化データ(JSON-LD)を出す2つの方法
方法A:nuxt-schema-org(@nuxtjs/seo に同梱)
上の記事ページの useSchemaOrg([defineArticle({...})]) から出力された JSON-LD です。サイト情報(WebSite)、ページ情報(WebPage)、組織(Organization)とのつながり(@id)まで自動で組み立てられています。
{
"@context": "https://schema.org",
"@graph": [
{ "@id": "https://example.com/#website", "@type": "WebSite", "name": "サンプル技術ブログ", ... },
{ "@id": "https://example.com/articles/nuxt-seo#webpage", "@type": "WebPage", "name": "NuxtのSEO設定", ... },
{ "@id": "https://example.com/#identity", "@type": "Organization", "name": "サンプル技術ブログ", "url": "https://example.com" },
{
"@id": "https://example.com/articles/nuxt-seo#article",
"@type": "Article",
"headline": "NuxtのSEO設定",
"datePublished": "2026-09-01",
"dateModified": "2026-09-20",
"inLanguage": "ja",
"author": { "@id": "https://example.com/#identity" },
"mainEntityOfPage": { "@id": "https://example.com/articles/nuxt-seo#webpage" }
}
]
}
(実出力から一部の項目と ImageObject を省略しています)
なお、このJSON-LDの <script> は </head> の後(body側)に出力されていました。GoogleはJSON-LDをbody内に置いても読み取れるため、そのままで問題ありません。
方法B:useHead で直接書く(モジュールなし)
<!-- app/pages/faq.vue -->
<script setup lang="ts">
definePageMeta({ title: 'よくある質問' })
// サーバーでだけ出力すればよい値(クライアントのJSに含まれない)
useServerSeoMeta({
description: 'Nuxtの設定に関するよくある質問です。',
})
// モジュールを使わずに JSON-LD を出す方法
useHead({
script: [
{
type: 'application/ld+json',
innerHTML: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: [
{
'@type': 'Question',
name: 'sitemap.xml はどこに出ますか?',
acceptedAnswer: { '@type': 'Answer', text: '/sitemap.xml に出力されます。' },
},
],
}),
},
],
})
</script>
<template><main><h1>よくある質問</h1></main></template>
$ curl -s localhost:7451/faq | grep -oE '<title>[^<]*</title>|<script type="application/ld\+json">[^<]{0,40}'
<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPa
<title>よくある質問|サンプル技術ブログ</title>
definePageMeta({ title }) だけで <title>よくある質問|サンプル技術ブログ</title> になりました(@nuxtjs/seo の機能)。定番の型(記事・パンくず・組織)は nuxt-schema-org、FAQなど1ページだけの型は useHead で直接書く、と使い分けると手間が少なくなります。
robots:検索に載せないページの指定
routeRules の '/admin/**': { robots: false } を設定した管理画面には、meta と HTTPヘッダーの両方で noindex が付きました。
$ curl -sI localhost:7451/admin | grep -i robots
X-Robots-Tag: noindex, nofollow
$ curl -s localhost:7451/admin | grep -o '<meta name="robots"[^>]*>'
<meta name="robots" content="noindex, nofollow">
さらに、このページは sitemap.xml からも自動で除外されていました(下の出力に /admin がありません)。
| 指定方法 | 書き方 | 効果 |
|---|---|---|
| ルール単位 | routeRules: { '/admin/**': { robots: false } } |
meta・X-Robots-Tag・sitemap除外 |
| robots.txt | robots: { disallow: ['/admin'] } |
クローラーの巡回を止める |
| ページ単位(モジュールなし) | useSeoMeta({ robots: 'noindex, nofollow' }) |
meta のみ |
robots.txt の Disallow は「巡回しない」指示で、「検索結果に出さない」指示ではありません。 検索結果から外したいページは noindex(meta または X-Robots-Tag)で指定します。
robots.txt と sitemap.xml の実出力
$ curl -i localhost:7451/robots.txt
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Cache-Control: max-age=14400, must-revalidate
# START nuxt-robots (indexable)
User-agent: *
Disallow: /admin
Sitemap: https://example.com/sitemap.xml
# END nuxt-robots
Sitemap: 行は site.url から自動で追加されます。
動的な記事URLは、sitemap.sources に指定したAPIから返します。
// server/api/__sitemap__/urls.ts
export default defineSitemapEventHandler(() => {
return ['nuxt-seo', 'nuxt-route-rules'].map((slug) => ({
loc: `/articles/${slug}`,
lastmod: '2026-09-25',
}))
})
$ curl -i localhost:7451/sitemap.xml
HTTP/1.1 200 OK
Content-Type: text/xml; charset=UTF-8
Cache-Control: public, max-age=600, s-maxage=600, stale-while-revalidate=3600
X-Sitemap-Cache-Duration: 600s
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/__sitemap__/style.xsl"?>
<urlset ... xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/</loc>
</url>
<url>
<loc>https://example.com/articles/nuxt-route-rules</loc>
<lastmod>2026-09-25</lastmod>
</url>
<url>
<loc>https://example.com/articles/nuxt-seo</loc>
<lastmod>2026-09-25</lastmod>
</url>
</urlset>
<!-- XML Sitemap generated by @nuxtjs/sitemap v8.5.1 at 2026-09-29T10:36:51.126Z -->
app/pages/の静的なページ(/・/faq)は自動で入り、動的ルート([slug])はsourcesから追加されます。- sitemap は 600秒キャッシュされていました。記事の追加が反映されるまで最大10分かかります。
OG画像を自動生成する(nuxt-og-image v6)
テンプレートを作る
v6ではファイル名の末尾にレンダラー名(.takumi.vue)を付けます。
<!-- app/components/OgImage/Card.takumi.vue -->
<script setup lang="ts">
const { title = 'Title', subtitle = '' } = defineProps<{ title?: string; subtitle?: string }>()
</script>
<template>
<div class="w-full h-full flex flex-col justify-center px-20 bg-slate-900 text-white" style="font-family: 'Noto Sans JP'">
<h1 class="text-[72px] font-bold">{{ title }}</h1>
<p class="text-[36px] text-slate-300">{{ subtitle }}</p>
</div>
</template>
ページでは defineOgImage('Card.takumi', { title, subtitle }) と呼びます(v5 の defineOgImageComponent は v6 で非推奨)。
生成された画像を取得する
$ curl -s -D - "localhost:7451/_og/d/c_Card.takumi,title_Nuxt+SEO+Sample,...png" -o og_home.png
HTTP/1.1 200 OK
cache-control: public, max-age=259200, s-maxage=259200, immutable
Content-Type: image/png
X-OG-Cache: MISS
Server-Timing: ... render-total;dur=101.155, total;dur=121.827
$ file og_home.png
og_home.png: PNG image data, 1200 x 600, 8-bit/color RGB, non-interlaced
1200×600 のPNGが約0.1秒で生成され、3日間(259200秒)キャッシュされる設定で返りました。URLに title などが入るので、内容が変わればURLも変わります。
日本語が表示されない → 日本語フォントを追加して解決
最初、fonts の設定なしで生成したところ、英語のタイトルは正しく描画されましたが、日本語の部分が「NO GLYPH」と書かれた四角に置き換わりました。既定のフォント(Inter)に日本語の文字が含まれていないためです。
解決の手順は次のとおりです。
- 日本語フォントのファイルを
public/fonts/に置く(今回はNotoSansJP-Bold.ttfとNotoSansJP-Regular.ttf。Google Fonts からダウンロードするか、npm の@expo-google-fonts/noto-sans-jpに含まれるTTFを使えます) @nuxt/fontsをモジュールに追加し、familiesにprovider: 'local'・global: trueで登録する(上の nuxt.config.ts のとおり)- テンプレートの
font-familyに'Noto Sans JP'を指定する
設定後に再ビルドすると、「NuxtのSEO設定」「useSeoMetaとsitemapの設定例です。」が正しく描画されました。global: true がないとOG画像からフォントが見えないことは、モジュールの警告メッセージにも書かれています。
また @nuxt/fonts は既定で外部のフォントサービスに問い合わせるため、外部に接続できない環境では Could not fetch from https://fonts.google.com/... の警告が出ました。providers で外部サービスを false にすると警告は0行になり、画像も同じものが生成されました。
nuxt generate(静的化)するときの注意
npx nuxt generate では、robots.txt・sitemap.xml・OG画像も静的ファイルになります。
[nitro] ├─ /robots.txt (151ms)
[nitro] ├─ /articles/nuxt-seo (147ms)
[nitro] ├─ /_og/s/...png (376ms)
[nitro] ├─ /sitemap.xml (26ms)
[nitro] i Prerendered 15 routes in 10.814 seconds
.output/public/robots.txt
.output/public/sitemap.xml
.output/public/_og/s/(ファイル名省略).png
.output/public/articles/nuxt-seo/index.html
(index.html・faq/index.html などは省略)
ここで、sitemap.xml には /articles/nuxt-route-rules が載っているのに、そのHTMLは生成されていませんでした。prerenderはリンクをたどるため、どこからもリンクされていない記事は対象外になります。sitemap に載せた動的URLは nitro.prerender.routes にも列挙すると、404を防げます。
// nuxt.config.ts(追記)
nitro: {
prerender: { routes: ['/articles/nuxt-seo', '/articles/nuxt-route-rules'] },
},
SEOチェックリスト
| # | 確認項目 | 確認方法 |
|---|---|---|
| 1 | site.url が本番のURLになっている |
canonical・og:url を curl で確認 |
| 2 | 全ページで <title> と description が固有 |
curl -s URL | grep '<title>' |
| 3 | canonical が1つだけ、クエリなし | grep -c 'rel="canonical"' が1 |
| 4 | og:title・og:description・og:image・og:url | SNSのシェアデバッガー |
| 5 | OG画像の日本語が表示される | 画像URLをブラウザで開く |
| 6 | 存在しないURLが404を返す | curl -o /dev/null -w '%{http_code}' |
| 7 | 管理画面などに noindex | curl -I で X-Robots-Tag |
| 8 | robots.txt に Sitemap 行 | curl /robots.txt |
| 9 | sitemap.xml に全公開ページ、noindexページなし | curl /sitemap.xml |
| 10 | JSON-LD がエラーなし | Googleのリッチリザルトテスト |
| 11 | 本文がSSR(または prerender)でHTMLに入っている | curl の結果に本文がある |
よくあるつまずきと対処
| 症状 | 原因 | 対処 |
|---|---|---|
| OG画像の日本語が「NO GLYPH」の四角になる | 既定フォントに日本語がない | @nuxt/fonts でNoto Sans JPなどを global: true で登録 |
| canonical・og:url のドメインが本番と違う | site.url が開発用のまま |
site.url か環境変数 NUXT_SITE_URL で本番URLを設定 |
| sitemap にあるページが404(静的化時) | リンクがなく prerender されていない | nitro.prerender.routes に列挙 |
よくある質問
Q. useHead と useSeoMeta はどちらを使えばよいですか?
A. メタタグ(title・description・OGP・Twitter)は useSeoMeta、link(canonical・hreflang)と script(JSON-LD)は useHead が目安です。useSeoMeta はキーの打ち間違いを型で見つけられます。
Q. @nuxtjs/seo は必須ですか?
A. 必須ではありません。useSeoMeta と useHead だけでも基本は設定できます。sitemap・robots.txt・OG画像・構造化データまで揃えるなら @nuxtjs/seo が手早いです。@nuxtjs/sitemap だけを個別に入れることもできます。
Q. Next.jsの metadata API との違いは?
A. Next.jsは metadata や generateMetadata をエクスポートし、Nuxtは useSeoMeta をページ内で呼ぶ形です。
まとめ
- メタタグは
useSeoMeta、link・script はuseHead、全体共通はnuxt.config.tsのapp.head site.urlを設定すると canonical・og:url・sitemap・robots.txt の絶対URLがまとめて決まる- @nuxtjs/seo 5.3 で canonical・og:url・robotsメタ・JSON-LD が自動出力され、canonical からクエリも外れた
robots: falseのルールで noindex(meta とヘッダー)と sitemap 除外が同時にできる- OG画像の日本語は既定フォントでは表示されない。
@nuxt/fontsで日本語フォントをglobal: true登録して解決 - 静的化では sitemap の動的URLを
nitro.prerender.routesにも列挙する - 最後は curl で
<head>と sitemap.xml を実際に見て確認する
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Nuxt SEO設定|useSeoMeta・sitemap・OG画像を実出力で解説」
株式会社RJCでは、検索エンジンに正しく届くWebサイトづくりを、実際の出力を確かめながらプロジェクトの中で仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。