• #ogp
  • #seo
  • #cloudflare-workers
  • #nuxt
  • #sns-share
未分類

OGPシェアURL改善計画

現状の問題

現在の構成

シェアURL(SNSに投稿されるURL):
https://og-image-worker.number55number55.workers.dev/share/japanese-quiz?category=...

↓ Worker側の処理
1. OGPメタタグを含むHTMLを返す
2. og:url には https://log.eurekapu.com/... を設定
3. meta refresh で log.eurekapu.com にリダイレクト

問題点:被リンク評価がWorkers.devに流れる

項目効果
ユーザートラフィック✅ 得られる(リダイレクトで来る)
OGPカード表示✅ 正常に動作
SEO(被リンク評価)❌ ほぼなし

なぜSEO効果がないのか

  1. 被リンクの直接的な評価先
    • SNSで拡散されるリンクは workers.dev を指している
    • Googleは実際のリンクURLを評価対象とする
    • og:urlの値はcanonical的なヒントに過ぎない
  2. リダイレクトでのリンクジュース転送
    • 301リダイレクトでも100%のリンクジュースは転送されない(一般的に85-99%程度)
    • さらに、外部サービスドメイン(workers.dev)からの転送は評価が低い
    • meta refreshリダイレクトは301より弱い
  3. SNSリンクの特性
    • 多くのSNS(Twitter/X、Facebook等)は外部リンクにrel="nofollow"を付与
    • ただし、拡散による間接的なSEO効果(他サイトからの引用、ブランド認知向上)は期待できる

改善策

推奨:メインサイトにシェアページを設置

シェアURLをメインドメイン(log.eurekapu.com)に変更する。

改善前: https://og-image-worker.number55number55.workers.dev/share/japanese-quiz?...
改善後: https://log.eurekapu.com/share/japanese-quiz?...

実装方法

方法1: Nuxt Server Route(推奨)

server/routes/share/japanese-quiz.tsを作成し、動的にOGPタグ付きHTMLを生成:

// server/routes/share/japanese-quiz.ts
export default defineEventHandler((event) => {
  const { category, correct, total } = getQuery(event)

  const categoryNames: Record<string, string> = {
    'modification-order': '修飾語の順序',
    'punctuation': '句読点の打ち方',
    'particles': '助詞の使い方',
    'all': '全問チャレンジ',
  }

  const categoryName = categoryNames[category as string] || 'クイズ'
  const ogImageUrl = `https://og-image-worker.number55number55.workers.dev/og/japanese-quiz?category=${category}&correct=${correct}&total=${total}`
  const redirectUrl = `https://log.eurekapu.com/japanese-writing-quiz/${category}`

  const html = `<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>${categoryName} - ${correct}/${total}問正解! | 日本語作文クイズ</title>
  <meta property="og:title" content="${categoryName}クイズ - ${correct}/${total}問正解!">
  <meta property="og:description" content="日本語作文クイズに挑戦しよう">
  <meta property="og:image" content="${ogImageUrl}">
  <meta property="og:url" content="${redirectUrl}">
  <meta property="og:type" content="website">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:title" content="${categoryName}クイズ - ${correct}/${total}問正解!">
  <meta name="twitter:description" content="日本語作文クイズに挑戦しよう">
  <meta name="twitter:image" content="${ogImageUrl}">
  <meta http-equiv="refresh" content="0;url=${redirectUrl}">
  <link rel="canonical" href="${redirectUrl}">
</head>
<body>
  <p>リダイレクト中... <a href="${redirectUrl}">こちらをクリック</a></p>
</body>
</html>`

  return new Response(html, {
    headers: { 'Content-Type': 'text/html; charset=utf-8' },
  })
})

方法2: 専用Vueページ + SSR

pages/share/japanese-quiz.vueを作成し、useSeoMetaで動的OGPを設定:

<script setup lang="ts">
const route = useRoute()
const { category, correct, total } = route.query

const categoryNames: Record<string, string> = {
  'modification-order': '修飾語の順序',
  'punctuation': '句読点の打ち方',
  'particles': '助詞の使い方',
  'all': '全問チャレンジ',
}

const categoryName = categoryNames[category as string] || 'クイズ'
const ogImageUrl = `https://og-image-worker.number55number55.workers.dev/og/japanese-quiz?category=${category}&correct=${correct}&total=${total}`
const redirectUrl = `/japanese-writing-quiz/${category}`

useSeoMeta({
  title: `${categoryName} - ${correct}/${total}問正解! | 日本語作文クイズ`,
  ogTitle: `${categoryName}クイズ - ${correct}/${total}問正解!`,
  ogDescription: '日本語作文クイズに挑戦しよう',
  ogImage: ogImageUrl,
  twitterCard: 'summary_large_image',
})

// クライアントサイドでリダイレクト
onMounted(() => {
  navigateTo(redirectUrl)
})
</script>

<template>
  <div>リダイレクト中...</div>
</template>

注意: 方法2ではSSRが必須。ssr: falseの設定だとクローラーがOGPを認識できない。

ResultSummary.vueの変更

シェアURLを変更:

// 変更前
const shareUrl = computed(() => {
  return `https://og-image-worker.number55number55.workers.dev/share/japanese-quiz?...`
})

// 変更後
const shareUrl = computed(() => {
  return `https://log.eurekapu.com/share/japanese-quiz?category=${props.category}&correct=${props.result.correctAnswers}&total=${props.result.totalQuestions}`
})

OGP画像URLはそのままでOK

OGP画像のURLがWorkers.devを指していることは問題ない:

<meta property="og:image" content="https://og-image-worker.number55number55.workers.dev/og/japanese-quiz?...">
  • OGP画像のホスティング場所はSEOに影響しない
  • 重要なのはシェアされるページのURLがどのドメインか
  • 画像は外部CDNでも、Workers.devでも問題なし

期待される効果

項目改善前改善後
シェアURLworkers.devlog.eurekapu.com
被リンク評価の帰属先workers.devlog.eurekapu.com
ドメインオーソリティへの寄与❌ なし✅ あり
ブランドURL認知❌ 低い✅ 高い
OGPカード表示✅ 同じ✅ 同じ

補足:SNSリンクのSEO効果について

直接的なSEO効果は限定的

  • Twitter/X、Facebook等は外部リンクにrel="nofollow"を付与
  • 直接的なリンクジュースはほぼ転送されない

間接的なSEO効果は大きい

  1. ブランドシグナル: ドメイン名の露出がブランド認知を高める
  2. トラフィックシグナル: サイトへの訪問者増加はポジティブシグナル
  3. 二次的な被リンク: SNSで見た人がブログ等で引用する可能性
  4. クローラーへの発見: SNSリンク経由でクローラーがページを発見

結論

拡散のトラフィック効果はあるが、SEO効果(被リンク評価)はほぼないのが現状の実装である。

メインドメイン(log.eurekapu.com)にシェアページを設置することで:

  • 被リンク評価がメインサイトに帰属する
  • ブランドURLとしての認知が向上する
  • OGP画像生成は引き続きWorkers.devで行える(影響なし)

実装優先度: 高(SEOを重視する場合)