SvelteKitでSEOとOGPのメタタグを設定した話

SvelteKitでは <svelte:head> タグの中にメタタグを書くだけでSEOやOGPの設定ができます。


SEOとOGPの違い

SEO(Search Engine Optimization)は検索エンジンにページの内容を正しく伝えるための設定です。

OGP(Open Graph Protocol)はSNSにURLを貼ったときに表示されるカード情報を制御します。

URLをSNSに貼ったとき↓
┌─────────────────────────┐
│ [og:image の画像]        │
│ og:title のテキスト       │
│ og:description のテキスト │
└─────────────────────────┘

主なメタタグ

SEO用

タグ 役割
<title> タブとGoogle検索結果のタイトル
<meta name="description"> Google検索結果の説明文

OGP用

タグ 役割
og:title カードのタイトル
og:description カードの説明文
og:image カードの画像URL
og:url ページのURL
og:type ページの種類(website / article

Twitter Card用

タグ 役割
twitter:card カードの種類(summary / summary_large_image

OGP画像の推奨サイズは 1200 × 630pxsummary_large_imageの場合)です。


実装

+layout.svelte にデフォルトのメタタグを設定

サイト全体のデフォルトとして +layout.svelte に書きます。

<svelte:head>
  <title>My SvelteKit App</title>
  <meta name="description" content="SvelteKitで作ったアプリです" />

  <!-- OGP -->
  <meta property="og:type" content="website" />
  <meta property="og:title" content="My SvelteKit App" />
  <meta property="og:description" content="SvelteKitで作ったアプリです" />
  <meta property="og:image" content="https://myapp.example.com/ogp.png" />

  <!-- Twitter Card -->
  <meta name="twitter:card" content="summary_large_image" />
</svelte:head>

+page.svelte でページごとに上書き

+page.svelte<svelte:head> を書くと、レイアウトのものを上書きできます。

<svelte:head>
  <title>TODOリスト | My SvelteKit App</title>
  <meta name="description" content="TODOを管理するページです" />
  <meta property="og:title" content="TODOリスト | My SvelteKit App" />
</svelte:head>

load 関数のデータを使った動的なメタタグ

投稿ページなど、データに応じてタイトルや説明を変えたい場合はSvelteの式を使います。

<!-- src/routes/posts/[id]/+page.svelte -->
<script lang="ts">
  let { data } = $props();
</script>

<svelte:head>
  <title>{data.post.title} | My SvelteKit App</title>
  <meta name="description" content={data.post.body.slice(0, 100)} />
  <meta property="og:title" content={data.post.title} />
  <meta property="og:description" content={data.post.body.slice(0, 100)} />
</svelte:head>

<h1>{data.post.title}</h1>
<p>{data.post.body}</p>

D1クエリには型パラメータを指定して、titlebody が正しく認識されるようにします。

const post = await db?.prepare('SELECT * FROM posts WHERE id = ?')
  .bind(params.id)
  .first<{ id: number; title: string; body: string }>();

確認方法

確認したいもの 方法
タイトル・description ブラウザのタブ・ページのソースコード
OGP opengraph.xyz にURLを入力
Twitter Card Twitter Card Validator

まとめ

  • <svelte:head> の中にメタタグを書くだけで設定できる
  • +layout.svelte にデフォルトを書き、+page.svelte でページごとに上書きする
  • load 関数のデータをそのままメタタグに使える
  • D1クエリに型パラメータを指定すると data.post.title などが正しく型推論される
← トップページに戻る