ブックマークレットでOGPタグを確認する【javascript】

JavaScript

OGPタグはページに表示されない裏側のタグです。
そのためチェックがめんどくさいし、確認漏れも起こりやすいので『OGPタグ確認』ブックマークレットを作りました。

登録すればボタン一つでタグが確認できるので便利です!

ブックマークレットの登録方法

このブックマークレットの動作確認はChrome、Firefox、Edgeで行っています。
他のブラウザでは動作しないかもしれません。ご了承ください。
以下のボタンをブックマークバーにドラッグすれば登録できます。

該当のページ上で、登録した『OGPタグ確認』をクリックすれば次のようなポップアップが表示されると思います。
※yahoo天気のページで実行した例です

https://weather.yahoo.co.jp/weather/jp/13/4410.html

OGPに設定した値が一覧で取得できます。
個人的に必須だと思うタグを取得して表にしました。それ以外は「上記以外のOGPタグ」としてまとめました。主にmetaタグで、属性に「twitter」や「og」の記述があるものをピックアップしてます。

そもそもOGPタグとは?

OGPタグとは、TwitterやFacebookなどのSNSで使用されるタグで、ページの概要を伝える為に記載します。HTMLのメタディスクリプションのSNS版といったところでしょうか。
OGPタグには、主にページのイメージや説明文、URLなどのページの情報を記載します。

SNSでURLを共有した時、OGPの内容が読み込まれ、Twitterではこんなカンジで画像やページの説明文が挿入されます。

OGPタグが設置されているページを共有すると画像や説明文が挿入される

OGPタグがなくても、SNS側である程度はページを解析してくれますが、確実に情報を伝えたいときは設置したほうが良いタグです。

完成したコードを確認する

こちらが完成したコードになります。外部cssを読み込ませるのは避けたかったので大変長くなりました。

(function(){
    //すでに実行中か確認
if(document.getElementById('ogpCheck') != null) {
  document.body.removeChild(document.getElementById('ogpCheck'));
}
const allMetaTag = document.querySelectorAll('meta');
const metaOgp = [];
const metaTDK = [];
const noValue = 'noValue';
const appearBoolean = 'noValue';
let htmlElm = document.createElement('div');
let coverElm = document.createElement('div');
let closeBtn = document.createElement('p');
let addtag = "";

//htmlタグ作成
htmlElm.id = "ogpCheck";
htmlElm.style.cssText = "max-width: 960px;"
                      + "background: #fff;"
                      + "position: fixed;"
                      + "z-index: 99999;"
                      + "margin: 30px auto;"
                      + "padding: 20px;"
                      + "top: 0;"
                      + "right: 0;"
                      + "bottom: 0;"
                      + "left: 0;"
                      + "overflow: scroll;"
                      + "filter: drop-shadow(0 0 0.75rem #000);";

coverElm.style.cssText = "background:rgba(0,0,0,0.3);"
                      + "width: 100%;"
                      + "height: 100%;"
                      + "position: fixed;"
                      + "z-index: 99999;"                             
                      + "top: 0;"
                      + "right: 0;"
                      + "bottom: 0;"
                      + "left: 0;";

closeBtn.innerText = "close";
closeBtn.style.cssText = "background:rgba(0,0,0,0.6);"
                      + "font-size:18px;"
                      + "color:#fff;"
                      + "font-weight:bold;"
                      + "display:inline-block;"
                      + "position:absolute;"
                      + "top:0;"
                      + "right:0;"
                      + "padding:.56em 1em;"
                      + "background:#000;"
                      + "cursor:pointer;";

//クローズボタンイベント設定
closeBtn.addEventListener('click',function() {
    document.querySelector('body').removeChild(coverElm);
    document.querySelector('body').removeChild(htmlElm);

})

//metaタグ取得
for(let tag of allMetaTag) {
    const tagProp = SearchTag(tag);
    const metaProp = tagProp.getAttr('property') || noValue;
    const metaCont = tagProp.getAttr('content') || noValue;
    const metaName = tagProp.getAttr('name') || noValue;

     //meta description取得
    if(metaName.match(/description/)) {
        metaTDK.push({property:metaProp, content : metaCont, name:metaName});
    }
     //meta keywords取得
    if(metaName.match(/keywords/)) {
        metaTDK.push({property:metaProp, content : metaCont, name:metaName});
    }
     //meta og取得
    if(metaProp.match(/og:/)) {
        metaOgp.push({property:metaProp, content : metaCont, name:metaName});
    }
     //meta twitter取得
    if(metaName.match(/twitter:/)) {
        metaOgp.push({property:metaProp, content : metaCont, name:metaName});
    }
    
}

//タグの属性を取得
function SearchTag(tag) {
    return {
        getAttr : function(attr) {
            return tag.getAttribute(attr);
        }
    }
}

//タグの存在チェック
function judgmentItem(itemObj,prop,value) {
    let existTag = false;
    for(let item of itemObj) {
        if(item[prop] == value) {
            existTag = true;
            return judgmentNoValue(item.content);
        }
    }
    if(!existTag) return '<span style="color:red;font-weight:bold">タグがありません</span>';
}
//タグの存在チェック(イメージ)
function judgmentItemImage(itemObj,prop,value) {
    let existTag = false;
    for(let item of itemObj) {
        if(item[prop] == value) {
            existTag = true;

            if(item.content == noValue || item.content == "") {
                return '<span style="color:red;font-weight:bold">タグはありますが、値が設定されていません</span>';
            } else {
                return `<img src="${item.content}" style="max-width:100%"><p style="font-size:13px;margin-top:10px">${item.content}</p>`;
            }
        }
    }
    if(!existTag) return '<span style="color:red;font-weight:bold">イメージが設定されていません</span>';
}

//タグの値があるかチェック
function judgmentNoValue(value) {
    if(value == noValue || value == "") {
        return '<span style="color:red;font-weight:bold">タグはありますが、値が設定されていません</span>';
    } else {
        return value;
    }
}
//基本のOGP以外のタグ
function otherOgp() {
    let existTag = false;
    for(let tag of metaOgp) {
        const defualtProp = ["og:title","og:type","og:description","og:url","og:site_name","og:image",];
        const defualtName = ["twitter:card","twitter:site"];
        const metaProp = tag.property;
        const metaCont = tag.content;
        const metaName = tag.name;
        
        if(defualtProp.indexOf(metaProp) == -1 && metaProp !== noValue ) {
            existTag = true;
            addtag += `<p style="padding:0 0 10px;margin:0;ext-align:left">【${metaProp}】${judgmentNoValue(metaCont)}</p>`;
        }
        if(defualtName.indexOf(metaName) == -1 && metaName !== noValue ) {
            existTag = true;
            addtag += `<p style="padding:0 0 10px;margin:0;text-align:left">【${metaName}】${judgmentNoValue(metaCont)}</p>`;
        }

    }
    if(!existTag) addtag += '<p style="padding:0 0 20px;margin:0;text-align:left;color:red;font-weight:bold;">該当するタグはありませんでした</p>';
}

//title取得
const getTitle = document.title || '<span style="color:red;font-weight:bold">タグがありません</span>';
addtag += `<p style="padding:10px 0;margin:0 0 10px;text-align:left;font-size:1.1em;color:#129012;font-weight:bold;background:#d6ffd6;padding:10px">タイトル</p>`;
addtag += `<p style="padding:10px;margin:0 0 20px;text-align:left">${getTitle}</p>`;

//ディスクリプション、キーワード取得
addtag += `<p style="padding:10px 0;margin:0 0 10px;text-align:left;font-size:1.1em;color:#129012;font-weight:bold;background:#d6ffd6;padding:10px">ディスクリプション</h2>`;
addtag += `<p style="padding:10px;margin:0 0 20px;text-align:left">${judgmentItem(metaTDK,'name','description')}</p>`;
addtag += `<p style="padding:10px 0;margin:0 0 10px;text-align:left;font-size:1.1em;color:#129012;font-weight:bold;background:#d6ffd6;padding:10px">キーワード</p>`;
addtag += `<p style="padding:10px;margin:0 0 20px;text-align:left">${judgmentItem(metaTDK,'name','keywords')}</p>`;

//OGPタグ取得
addtag += `<p style="padding:10px 0;margin:0 0 10px;text-align:left;font-size:1.1em;color:#129012;font-weight:bold;background:#d6ffd6;padding:10px">OGPタグ</p>`;
addtag += `<table style="width:100%;border:1px solid #ccc;border-top:none;border-spacing: 0;">`;
addtag += `<tr>`;   
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:image</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItemImage(metaOgp,'property','og:image')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:title</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'property','og:title')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;   
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:type</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'property','og:type')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;   
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:description</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'property','og:description')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;   
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:url</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;word-break: break-word;">${judgmentItem(metaOgp,'property','og:url')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;   
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#e4e4e4;">og:site_name</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'property','og:site_name')}</td>`;
addtag += `</tr>`;

addtag += `</table>`;

addtag += `<table style="width:100%;margin-top:20px;border:1px solid #ccc;border-top:none;border-spacing: 0;">`;
addtag += `<tr>`;
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#b3edff;">twitter:card</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'name','twitter:card')}</td>`;
addtag += `</tr>`;
addtag += `<tr>`;
addtag += `<th style="width:25%;text-align:left;border-right:1px solid #ccc;border-top:1px solid #ccc;padding:10px;background:#b3edff;">twitter:site</th>`;
addtag += `<td style="width:75%;padding:10px;border-top:1px solid #ccc;">${judgmentItem(metaOgp,'name','twitter:site')}</td>`;
addtag += `</tr>`;
addtag += `</table>`;

addtag += `<p style="padding:10px 0;margin:20px 0 10px;text-align:left;font-size:1.1em;color:#129012;font-weight:bold;background:#d6ffd6;padding:10px">上記以外のOGPタグ</p>`;

//基本のOGP以外のタグ取得
otherOgp();

//HTML挿入
htmlElm.innerHTML = addtag;
document.querySelector('body').appendChild(coverElm);
document.querySelector('body').appendChild(htmlElm);
htmlElm.appendChild(closeBtn);
})()

必要に応じてコードを変更してください。以下のサイトでブックマークレットの形に変換できます。

Bookmarklet Maker【ブックマークレット変換サービス】 - Kujipedia
Bookmarklet(ブックマークレット)を作るためのスクリプトの変換サービスです。

参考サイト

タイトルや見出しの確認など、SEOに便利なブックマークレット (PIXEL LAB)
大阪北摂(吹田)のウェブデザイナーのピクセルイメージによるブログです。HTML,CSS,Javascriptやデザインの話題や、オリジナルのツールやCMSの紹介など。

まとめ

WordPressなどのCMSだと、デフォルトでOGPタグが設定されている場合が多いです。
それ以外の独自システムだと手作業でタグを追加する場合もあると思います。そんな時のチェック用として作りました。最終的には公式のツールで表示を確認することをお勧めします。

Twitterだと『Card validator』というTwitterカードを確認できるサイトがあります。

https://cards-dev.twitter.com/validator?

コードに不備があったら少しずつ修正していこうと思います!