記事ページによくある「Xでシェア」「Facebookでシェア」といったボタンは、各SNSが提供している シェア用URL(Share Intent URL) に遷移させるだけで実装できます。公式のJavaScript SDKを読み込む必要はなく、<a href="..."> や window.open() だけで済むのでパフォーマンス面でも有利です。
ただしプラットフォームごとにURLのエンドポイント・パラメータ名・URLエンコードの扱いが異なり、仕様を押さえずに書くと日本語が文字化けしたりOGP画像が出なかったりします。
この記事では主要5プラットフォーム(X / Facebook / LINE / はてなブックマーク / LinkedIn)のシェアURL仕様を、実装時のハマりどころと合わせて整理します。
実装の前に押さえておく共通事項
URLエンコードは必須
どのプラットフォームでも シェア対象のURLや本文はパーセントエンコードして渡します。生の & や ? # が混ざるとクエリパラメータの区切りと誤認されて壊れるためです。
JavaScript なら encodeURIComponent() を通すか、URLSearchParams を使います。
const pageUrl = 'https://example.com/article?id=123';
const shareUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(pageUrl)}`;
URLSearchParams を使うと set した時点で自動エンコードされるので、手で encodeURIComponent を書くより安全です。
const params = new URLSearchParams({ url: pageUrl, text: '記事タイトル' });
const shareUrl = `https://twitter.com/intent/tweet?${params}`;
target="_blank" と rel="noopener" をセットで
同じタブでSNSに遷移させるとユーザーが元ページに戻れなくなるので、別タブで開くのが一般的です。
<a href="..." target="_blank" rel="noopener">Xでシェア</a>
rel="noopener" を付けないと、開いた先のページから window.opener 経由で元ページを操作される Tabnabbing 攻撃のリスクがあります。モダンブラウザは target="_blank" に対して暗黙的に noopener を付けますが、明示的に書くのが安全です。
URLの実用上の長さ上限
URLそのものの厳密なバイト上限はブラウザやサーバーで差がありますが、実用上は 2,000 文字以内 を目安にしておくと事故が起きません。本文を極端に長くする場合は注意します。
プラットフォーム別の仕様
X (Twitter)
https://twitter.com/intent/tweet?url={URL}&text={TEXT}&hashtags={TAGS}
| パラメータ | 用途 | 備考 |
|---|---|---|
url | シェア対象のURL | 必須ではないが実質必須 |
text | 投稿本文 | 改行は %0A |
hashtags | ハッシュタグ | カンマ区切り、# は付けない |
via | @{username} を末尾に付加 | 省略可 |
ポイント:
text + url + hashtagsの合計文字数で投稿画面に収まるかが決まるhashtagsはweb,frontendのように カンマ区切りで、#はXが自動で付与する#web,#frontendのように#を含めると、URLエンコードされて%23になり壊れる
https://www.facebook.com/sharer/sharer.php?u={URL}
パラメータは URL のみ。タイトル・本文・画像はすべてOGPタグから自動取得されます。ユーザーがシェア画面で本文を入力する仕様なので、こちら側から本文を渡す手段はありません。
したがって シェア対象ページに og:title og:description og:image が正しく設定されていることが前提条件になります。OGPが未整備だとカードが崩れます。
LINE
https://social-plugins.line.me/lineit/share?url={URL}&text={TEXT}
| パラメータ | 用途 | 備考 |
|---|---|---|
url | シェア対象のURL | 必須 |
text | 本文 | 省略可 |
ポイント:
- モバイル(LINEアプリインストール済み)から開くと、アプリ内のトーク選択画面に直接遷移する
- PCからはメッセージ送信用のWeb画面が開く
textはOGPのタイトルと重複させないのがコツ(画面で同じ文字列が二重に出る)
はてなブックマーク
https://b.hatena.ne.jp/entry/{URL}
はてブだけは クエリパラメータ形式ではなくURLをパスに埋め込むのが特徴です。https:// 部分も含めてそのままパスに続けます。
https://b.hatena.ne.jp/entry/https://example.com/article
encodeURIComponent を通すと https%3A%2F%2F のようになって、はてブ側がURLとして認識できません。パスに埋め込む形式ではエンコードしないのが原則です。ただし対象URL内にクエリ文字列や日本語が含まれる場合は部分的にエンコードが必要になり、扱いが他のプラットフォームと異なるので注意が必要です。
ポイント:
- HTTPSページをHTTPとして渡すと別エントリ扱いになるので、canonical URLと一致させる
- コメント本文をURLで指定することはできない(ユーザーが画面で入力する仕様)
https://www.linkedin.com/sharing/share-offsite/?url={URL}
かつては title summary パラメータも使えましたが、現在は url のみが公式サポートです。Facebookと同様、タイトル・説明・画像はOGPから取得されます。
ポイント:
og:imageは 1200×627以上推奨(小さいとカードに画像が出ない)og:typeがarticleでないとうまく表示されない場合がある
実装テンプレ
HTMLリンクで静的に配置
<a
href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fexample.com%2Farticle&text=%E8%A8%98%E4%BA%8B%E3%82%BF%E3%82%A4%E3%83%88%E3%83%AB&hashtags=web,frontend"
target="_blank"
rel="noopener"
aria-label="Xでシェア"
>Xでシェア</a>
aria-label を付けておくとスクリーンリーダーで内容が伝わりやすくなります。
JavaScript で動的に生成
function buildShareUrls({ url, text = '', hashtags = '' }) {
const enc = encodeURIComponent;
const params = new URLSearchParams({ url });
if (text) params.set('text', text);
if (hashtags) params.set('hashtags', hashtags);
return {
twitter: `https://twitter.com/intent/tweet?${params}`,
facebook: `https://www.facebook.com/sharer/sharer.php?u=${enc(url)}`,
line: `https://social-plugins.line.me/lineit/share?url=${enc(url)}`,
hatena: `https://b.hatena.ne.jp/entry/${url}`,
linkedin: `https://www.linkedin.com/sharing/share-offsite/?url=${enc(url)}`,
};
}
このコードで はてブだけ encodeURIComponent を通していない のは前述のとおりです。パスに埋め込む仕様のため、フルエンコードするとリンクが動きません。
ポップアップで開く
SNSの投稿画面を小窓で開きたい場合は window.open を使います。
function openShareWindow(url) {
window.open(url, 'share', 'width=600,height=500,noopener');
}
モバイルブラウザではポップアップが無視されて新しいタブで開くことが多いですが、PCでの投稿画面専用表示として使えます。
よくあるハマりどころ
日本語が文字化けする
encodeURIComponent を通し忘れているか、URLSearchParams を使わずに文字列結合でURLを組み立てています。URLSearchParams を使うと自動でエンコードされるので確実です。
FacebookやLinkedInでタイトル・画像が出ない
OGPタグが不足しているか、プラットフォーム側のキャッシュが残っています。
- OGP不足:
og:titleog:descriptionog:imageを揃える - キャッシュ: Facebookは Sharing Debugger、LinkedInは Post Inspector で再取得を実行
OGPタグを後から追加・修正した場合、デバッガーで強制的にキャッシュを更新しないと古いカードが表示され続けます。
はてブでコメントが付けられない
はてブのシェアURLは ブックマーク追加画面に誘導するだけ で、コメント本文をURLで指定することはできません(仕様)。ユーザーが追加画面で自分でコメントを入力する形になります。
ハッシュタグに # を付けてしまう
Xでは hashtags=web,frontend のように # なしのカンマ区切りです。#web,#frontend と書くとURLエンコードで %23 に変換されてしまい、ハッシュタグとして認識されません。
UTMパラメータ付きURLで url が途中で切れる
シェア対象URLにクエリ文字列(UTMパラメータなど)が含まれているのに、エンコードが不十分だとX・Facebook側で途中でクエリが切れることがあります。encodeURIComponent または URLSearchParams を必ず使うのが対策です。
まとめ
SNSシェアボタンはSDKなしでも、各プラットフォームのシェアURLに遷移させるだけで実装できます。押さえるポイントは3つです。
- URLエンコードを確実に(
encodeURIComponentかURLSearchParams) target="_blank" rel="noopener"を忘れない- Facebook / LinkedInはOGP依存なので
og:*タグを揃える
プラットフォームごとに仕様が違うので、5SNS分を一度に実装する場合はコードが煩雑になりがちです。本記事の内容を踏まえてテンプレを作っておくか、Share URL Builder のようなツールで一括生成すると抜け漏れを防げます。OGPタグの整備も併せて確認するなら Meta Tag Generator も参考にしてみてください。