そのWebサイト、外からキレイに見える？【metaタグ・OGP・Twitterカード】

この記事は、[本郷学園マイコン部 Advent Calender 2024](https://qiita.com/advent-calendar/2024/hongomcc) 17日目の投稿です。

みなさんこんにちは。つい最近職を免じられてしまった元高校部長です。

お気づきの方がいるかはわかりませんが、この度マイコン部ホームページを大リニューアル致しました。

https://www.hongomcc.net/

以前はWordPressだったのですが、

- 膨大な数のプラグインを管理する煩雑さ
- ページのデザイン上の制約の多さ

などの理由から、

> 「1から作った方が早いんじゃね?」

ということで、私がReact(Next.js)を使用して構築しました。
ソースコードは[こちら](https://github.com/HongoMCC/modern-website)です。

さて、本題に入りますと、
皆さんは自分のWebサイトを作るとき、そのサイト自体の見た目だけでなく、**外からの見た目**を気にしたことはありますでしょうか。

Webサイトを検索エンジンで検索した時やSNSで共有した時などに説明文やプレビューの画像が表示されることがありますが、正しく設定していなければとてもみすぼらしくなってしまい、サイトに訪れる前から印象を落としてしまう一因となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2097267/209c6166-3912-9144-10cd-ae1f928018a4.png)
↑みすぼらしい表示の例。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2097267/584b5d5f-d9d2-9edf-c237-5ffd30c30e52.png)
↑いい感じな表示の例。

というわけで、今回はマイコン部ホームページの際に気をつけた**Webサイトの外からの見た目**について書いていきたいと思います。

:::note warn
サンプルコードに使用している言語は**JSX**です。HTMLとは若干記法が異なります。
:::

# どこで設定するの？

https://developer.mozilla.org/ja/docs/Web/HTML/Element/head

`<head>`要素は、機械(検索エンジンやSNSなど)に読み取ることのできる、ページ自体に関する情報(= **メタデータ**)を記載するためのものです。

一般的に、HTML文書の初めにおきます。

`<title>`要素などを除いて、ほとんどの項目を`<meta>`タグで記述します。

```jsx
<html lang="ja">
  <head>
    <meta charSet="UTF-8" />
    <link rel="icon" type="image/png" href="/monitorman-m.webp" />
    <link rel="apple-touch-icon" href="/monitorman-m.webp" />
    <title>Top | 本郷学園マイコン部</title>
  </head>
 ...
</html>
```
↑よくある設定。文字コードとファビコン・タイトルのみが指定してある。

このままだと、このような極めて寂しい表示となってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2097267/209c6166-3912-9144-10cd-ae1f928018a4.png)
今回は上のコードに色々と付け足していきます。

# `<meta name="description">`: 説明文

```diff_jsx
<html lang="ja">
  <head>
    <meta charSet="UTF-8" />
    <link rel="icon" type="image/png" href="/monitorman-m.webp" />
    <link rel="apple-touch-icon" href="/monitorman-m.webp" />
    <title>Top | 本郷学園マイコン部</title>
+    <meta
+      name="description"
+      content="東京都巣鴨にある中高一貫制男子校、本郷中学校・高等学校のマイコン部HPです。活動内容などを掲載しています。"
+    />
  </head>
 ...
</html>
```

ページの説明文を記載します。検索エンジンなどに使用されることがあります。

# `<meta name="keywords">` : 検索ワード


```diff_jsx
<html lang="ja">
  <head>
    <meta charSet="UTF-8" />
    <link rel="icon" type="image/png" href="/monitorman-m.webp" />
    <link rel="apple-touch-icon" href="/monitorman-m.webp" />
    <title>Top | 本郷学園マイコン部</title>
    <meta
      name="description"
      content="東京都巣鴨にある中高一貫制男子校、本郷中学校・高等学校のマイコン部HPです。活動内容などを掲載しています。"
    />
+    <meta
+      name="keywords"
+      content="本郷学園, マイコン部, 本郷中学校, 本郷高等学校"
+    />
  </head>
 ...
</html>
```

検索エンジンに引っ掛けて欲しいキーワードを伝えます。
風の噂では最近はあまり気にされないということも聞きますが...書いておくに越したことはないでしょう。

# `<meta name="theme-color">` : テーマカラー

```diff_jsx
<html lang="ja">
  <head>
    <meta charSet="UTF-8" />
    <link rel="icon" type="image/png" href="/monitorman-m.webp" />
    <link rel="apple-touch-icon" href="/monitorman-m.webp" />
    <title>Top | 本郷学園マイコン部</title>
    <meta
      name="description"
      content="東京都巣鴨にある中高一貫制男子校、本郷中学校・高等学校のマイコン部HPです。活動内容などを掲載しています。"
    />
    <meta
      name="keywords"
      content="本郷学園, マイコン部, 本郷中学校, 本郷高等学校"
    />
+   <meta name="theme-color" content="#121212" />
  </head>
 ...
</html>
```

サイトのテーマカラーを16進カラーコードで指定します。 ~~Discordの左の色を変えられる...~~ と思っていましたが私の幻想のようです。試したところYouTubeかXでしか色が変わらないっぽいです。

# `<meta property="og:hogefuga">` : OGP設定

https://ogp.me

**OGP**:Open Graph Protocolは、meta社が策定したメタ要素記述方式です。(社名とは関係ありません)
多くのSNS等でリッチなリンクカードの表示に使用されています。

OGPを使用するためには、`<head>`タグに以下の通り追記する必要があります。

```diff_jsx
<html lang="ja">
-  <head>
+  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    <meta charSet="UTF-8" />
    <link rel="icon" type="image/png" href="/monitorman-m.webp" />
    <link rel="apple-touch-icon" href="/monitorman-m.webp" />
    <title>Top | 本郷学園マイコン部</title>
    <meta
      name="description"
      content="東京都巣鴨にある中高一貫制男子校、本郷中学校・高等学校のマイコン部HPです。活動内容などを掲載しています。"
    />
    <meta
      name="keywords"
      content="本郷学園, マイコン部, 本郷中学校, 本郷高等学校"
    />
   <meta name="theme-color" content="#121212" />
  </head>
 ...
</html>
```

:::note warn
OGPについても`<meta>`タグで設定しますが、設定内容を示す属性は`name`でなく`property`であることに注意が必要です。
```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
-   <meta name="og:type" content="website" />  
+   <meta property="og:type" content="website" />
  </head>
 ...
</html>
```
:::
## `<meta property="og:type">` : ページ種別

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
+   <meta property="og:type" content="website" />  
  </head>
 ...
</html>
```

ページの種別を指定します。

`website`以外には、
- 音楽
    - `music:song`
    - `music:album`
    - `music:playlist`
- 動画
    - `video:movie`
    - `video.episode`
- `article`
- `book`

などを指定できます。指定できる種別の一覧は[ドキュメント](https://ogp.me/#types)にあります。

##  `<meta property="og:url">` : サイトのURL

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
   <meta property="og:type" content="website" />  
+  <meta property="og:url" content="https://www.hongomcc.net/" />
  </head>
 ...
</html>
```

Webサイトの存在するURLを指定します。

## ` <meta property="og:site_name">` : サイトの名前

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
   <meta property="og:type" content="website" />  
   <meta property="og:url" content="https://www.hongomcc.net/" />
+  <meta property="og:site_name" content="Hongo M.C.C. Website" />
  </head>
 ...
</html>
```

Webサイト全体の名前を指定します。

## `<meta property="og:image>"` : サムネイル画像

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
   <meta property="og:type" content="website" />  
   <meta property="og:url" content="https://www.hongomcc.net/" />
   <meta property="og:site_name" content="Hongo M.C.C. Website" />
+   <meta
+     property="og:image"
+     content="https://www.hongomcc.net/thumbnail.webp"
+    />
  </head>
 ...
</html>
```

リンクカードとして表示させたい画像を指定します。

## かぶっているタグ

以下の設定項目は、HTMLの仕様と一部重複しています。
SNSがどちらの要素を読み取るかわからないので両方に同じ内容を記述しておいた方がいいでしょう。

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
    <meta property="og:type" content="website" />  
    <meta property="og:url" content="https://www.hongomcc.net/" />
    <meta property="og:site_name" content="Hongo M.C.C. Website" />
    <meta
      property="og:image"
      content="https://www.hongomcc.net/thumbnail.webp"
     />
+    <meta property="og:locale" content="ja_JP" />
+    <meta property="og:title" content="Top | 本郷学園マイコン部" />
+    <meta
+      property="og:description"
+      content="東京都巣鴨にある中高一貫制男子校、本郷中学校・高等学校のマイコン部HPです。活動内容などを掲載しています。"
+     />
  </head>
 ...
</html>
```

- `<meta property="og:locale">` : 使用言語を指定します。複数言語に対応している場合は`og:locale:alternate`を使用できます。`<html lang="ja">`とかぶっています。
- `<meta property="og:title">` : タイトルを指定します。`<title>`とかぶっています。
- `<meta property="og:description">` : 説明文を指定します。

# `<meta name="twitter:hoge">` : Twitterカード

https://developer.x.com/ja/docs/tweets/optimize-with-cards/guides/getting-started

https://developer.x.com/en/docs/x-for-websites/cards/overview/abouts-cards

Twitterカード(Xカード)は、OGPのTwitter(X)版です。
こちらも、多くのSNS等でリンクカードの表示に使用されています。

仕様がOGPと重複する部分がありますが、[ドキュメント](https://developer.x.com/ja/docs/tweets/optimize-with-cards/guides/getting-started)にそのような項目は設定しなくて良い旨が書かれています。

> TwitterのカードタグはOpen Graphのタグと似ており、Open Graphのプロトコルと同じ規則に基づいています。
> Open Graphプロトコルを使用してページのデータを記述すると、タグやデータを複製することなくTwitterカードを簡単に生成できます。
> Twitterカードプロセッサがページのタグを探す場合、最初にTwitter固有のプロパティがチェックされ、存在しない場合は、サポートされているOpen Graphのプロパティにフォールバックします。
> そのため、両方を独立してページで定義することができるとともに、コンテンツやエクスペリエンスを記述するために必要なマークアップの重複を最小限に抑えることができます。

ここでは、Twitterカード固有の設定項目について触れます。

## `<meta name="twitter:card">` : カード種別

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
+   <meta name="twitter:card" content="summary_large_image" />
  </head>
 ...
</html>
```
リンクカードにしたときの表示方法を指定します。

- `summary` : Webサイトの要約。
- `summary_large_image` : Webサイトの要約。画像を大きく表示する。
- `app` : モバイルアプリを直接ダウンロードするためのリンクを表示する。
- `player` : 動画・音声などのメディアを表示する。

**これが私的に一番大事だと思う要素です。**

XやDiscordでは、この要素によってリンクカードの体裁がガラッと変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2097267/b261b803-09d7-f938-de3c-9a2a0766f53d.png)
↑未指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2097267/584b5d5f-d9d2-9edf-c237-5ffd30c30e52.png)
↑`content="summary_large_image"`指定後

一気にいい感じになりました。
OGPだけだとこの指定はできないので、見落としがちなポイントだと思います。


## `<meta name="twitter:site">`・ <br>`<meta name="twitter:creator">`<br> : ユーザー名

```diff_jsx
<html lang="ja">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
    ...
     <meta name="twitter:card" content="summary_large_image" />
+    <meta name="twitter:site" content="@HongoMCC" />
+    <meta name="twitter:creator" content="@HongoMCC" />
  </head>
 ...
</html>
```

`twitter:site`にはサイトの所有者・Webサイトが取り扱うTwitterのユーザ名を`@hogefuga`形式で指定します。
`twitter:site`はWebサイトを**制作した**ユーザー名を指定します。


# おわりに

あんなに寂しかったリンクカードが...まぁなんということでしょう。こんなにも美しく生まれ変わりました！
サイトの印象に劇的な差を生み出す`<meta>`要素や、OGP・Twitterカードについて知っていただけましたら幸いです。
ご指摘等ありましたらコメントまでお願いします。

それではみなさん、良いWeb開発ライフを！

明日は、 [@yosshi9990](https://qiita.com/yosshi9990) さんの、「Google ColaboratoryでC++で並列処理」です。