2026年5月20日

2026年5月20日

WordPressのOGPタグを設定する方法

はじめに

OGP(Open Graph Protocol)タグはFacebook・X(Twitter)・LINEなどのSNSでページがシェアされたときの表示内容を制御します。適切なOGPタグを設定することでクリック率が向上し、SNS経由のトラフィックを増やせます。

症状・原因

  • SNSでシェアしても画像が表示されない
  • タイトルや説明文が意図しない内容になっている
  • X(Twitter)でカード形式にならない
  • LINEでシェアしたときのサムネイルが崩れる

解決手順

ステップ1:OGPの基本タグを理解する

<!-- 最低限必要なOGPタグ -->
<meta property="og:title" content="記事タイトル">
<meta property="og:description" content="記事の説明文(120字以内推奨)">
<meta property="og:url" content="https://example.com/post-slug/">
<meta property="og:image" content="https://example.com/ogp-image.jpg">
<meta property="og:type" content="article">  <!-- トップページはwebsite -->
<meta property="og:site_name" content="サイト名">
<meta property="og:locale" content="ja_JP">

<!-- Twitter Card(X) -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@your_account">
<meta name="twitter:creator" content="@author_account">

ステップ2:WordPressにOGPタグを実装する

// functions.php

function mytheme_ogp_tags(): void {
    // OGP画像のデフォルト(アイキャッチがない場合に使用)
    $default_ogp_image = get_template_directory_uri() . '/assets/images/ogp-default.jpg';
    $site_name         = get_bloginfo('name');

    if (is_singular()) {
        // 記事・固定ページ
        $title       = get_the_title();
        $description = get_the_excerpt();
        $url         = get_permalink();
        $type        = is_singular('post') ? 'article' : 'website';

        // 説明文の整形
        if (empty($description)) {
            $post        = get_post();
            $description = wp_trim_words(
                wp_strip_all_tags($post->post_content ?? ''),
                40,
                '…'
            );
        }

        // OGP画像: アイキャッチ → デフォルト画像の順で優先
        $image = $default_ogp_image;
        if (has_post_thumbnail()) {
            $thumbnail = wp_get_attachment_image_src(
                get_post_thumbnail_id(),
                'large'
            );
            if ($thumbnail) {
                $image = $thumbnail[0];
            }
        }

        // 投稿日時(og:article:published_time)
        $published_time = get_the_date('c'); // ISO8601
        $modified_time  = get_the_modified_date('c');

    } else {
        // アーカイブ・トップページ
        $title       = get_bloginfo('name');
        $description = get_bloginfo('description');
        $url         = home_url('/');
        $type        = 'website';
        $image       = $default_ogp_image;
    }

    $description = mb_substr(wp_strip_all_tags($description), 0, 120);

    // OGPタグを出力
    echo '<meta property="og:title" content="' . esc_attr($title) . '">' . "\n";
    echo '<meta property="og:description" content="' . esc_attr($description) . '">' . "\n";
    echo '<meta property="og:url" content="' . esc_url($url) . '">' . "\n";
    echo '<meta property="og:image" content="' . esc_url($image) . '">' . "\n";
    echo '<meta property="og:type" content="' . esc_attr($type) . '">' . "\n";
    echo '<meta property="og:site_name" content="' . esc_attr($site_name) . '">' . "\n";
    echo '<meta property="og:locale" content="ja_JP">' . "\n";

    // article タイプの場合は日時も出力
    if ($type === 'article' && isset($published_time)) {
        echo '<meta property="article:published_time" content="' . esc_attr($published_time) . '">' . "\n";
        echo '<meta property="article:modified_time" content="' . esc_attr($modified_time) . '">' . "\n";
    }
}
add_action('wp_head', 'mytheme_ogp_tags', 5);

ステップ3:Twitter Card(X)を設定する

// functions.php

function mytheme_twitter_card_tags(): void {
    $twitter_account = '@your_twitter_account'; // サイトのXアカウント

    // summary_large_image: 大きい画像付きカード
    // summary: 小さい画像付きカード
    $card_type = has_post_thumbnail() && is_singular() ? 'summary_large_image' : 'summary';

    echo '<meta name="twitter:card" content="' . esc_attr($card_type) . '">' . "\n";
    echo '<meta name="twitter:site" content="' . esc_attr($twitter_account) . '">' . "\n";

    // 著者のTwitterアカウント(ACFなどで管理する場合)
    if (is_singular('post')) {
        $author_id      = get_the_author_meta('ID');
        $author_twitter = get_user_meta($author_id, 'twitter_account', true);
        if ($author_twitter) {
            echo '<meta name="twitter:creator" content="' . esc_attr($author_twitter) . '">' . "\n";
        }
    }
}
add_action('wp_head', 'mytheme_twitter_card_tags', 5);

ステップ4:OGP画像を自動生成する

// functions.php: アイキャッチがない場合にOGP画像を動的生成

function mytheme_get_ogp_image_url(int $post_id): string {
    // アイキャッチがある場合はそれを使用
    if (has_post_thumbnail($post_id)) {
        $thumbnail = wp_get_attachment_image_src(
            get_post_thumbnail_id($post_id),
            [1200, 630]
        );
        if ($thumbnail) {
            return $thumbnail[0];
        }
    }

    // アイキャッチがない場合は記事内の最初の画像を探す
    $post    = get_post($post_id);
    $content = $post->post_content ?? '';

    if (preg_match('/<img[^>]+src=["\']([^"\']+)["\']/', $content, $matches)) {
        return $matches[1];
    }

    // それもない場合はデフォルト画像
    return get_template_directory_uri() . '/assets/images/ogp-default.jpg';
}

ステップ5:OGPデバッグツールで確認する

OGPの動作確認ツール:

1. Facebook シェアデバッガー
   https://developers.facebook.com/tools/debug/
   URLを入力して「デバッグ」→ キャッシュは「再度スクレイプ」でリセット

2. X(Twitter)カードバリデーター
   https://cards-dev.twitter.com/validator
   ※ 現在はXのアカウントが必要

3. OGP確認ツール(日本語)
   https://ogp.me/
   curl でヘッダーとメタタグを確認:
# curlでOGPタグを確認
curl -s https://example.com/post/ | grep -E 'og:|twitter:'

注意事項

  • OGP画像は 1200×630px(アスペクト比 1.91:1)を推奨します。Facebookは600×315px以上、Xは300×157px以上が必要です
  • SNSはOGP情報をキャッシュします。記事更新後に正しく反映されない場合は各SNSのデバッガーツールで「キャッシュをリセット」してください
  • og:image のURLは絶対URLが必要です。相対URLは使えません

まとめ

wp_head フックで is_singular() を判定し、アイキャッチ画像→デフォルト画像の優先順位でOGP画像を設定します。Twitterカードは has_post_thumbnail() の結果で summary_large_imagesummary を切り替えます。設定後はFacebook シェアデバッガーとXカードバリデーターで動作を確認します。

お気軽にご相談ください

お見積りへ お問い合わせへ