SNSへシェアするボタンの作り方

· 8 min read

このブログにBlueskyへシェアするためのボタンを実装してみました。
この記事ではSNSへの共有ボタンを実装するのに必要な「調査の方法」「その実例」を備忘録として残しておきます。

完成物から

見た目はこんな感じです。

シェアボタンの見た目

クリックすると、Blueskyへ「タイトル」と「URL」を含む投稿の作成画面が表示されます。

Blueskyへの投稿

Blueskyの共有ボタン実装の流れ

実装の仕方は使っているフレームワークによって異なるため、「調査過程」「本ブログの例」の順で解説します。

調査過程

他のSNSが大きくなった時にも参考にできるように、共有ボタンを実装する際の調査方法を解説します。

実装方法が公式であるか?

まずは公式ドキュメントを漁り、シェアボタンの実装が無いか探します。
たいていの場合、「このURLにアクセスすると投稿画面が出ます」とか「このHTMLタグをそのまま埋め込めばボタンが設置できます」といった情報が書いてあります。

Blueskyでは、公式ドキュメントにURLについて書いてありました。https://bsky.app/intent/compose?text=ああああのようにtextパラメータに文字列を指定してあげればよさそうです。

メディアキットを探す

ボタンのアイコンとして使える画像をメディアキットから探しましょう。
メディアキットとは、メディア向けに「この画像を使ってください」とロゴやアイコンなどをまとめた資料のことです。

Blueskyにもメディアキットが用意されています。
SVGもあります。Bluesky for Journalistsの”Do you have a media kit?”の欄にリンクがあります。

さまざまなアイコンをまとめているFont AwesomeSimple Iconsにも用意されています。手っ取り早く使いたい人はこちらから探してみましょう。

筆者がよく使っているIconifyの検索結果も載せておきます。
Iconify “bluesky”

IconifyはSVGだけではなく、「React」「Svelte」「Vue」「Astro」「Tailwind CSS」などなどいろんな形で使えるようにコピペできるため重宝しています。

本ブログの例

筆者はAstroWindというブログテンプレートを元に、AstroTailwind CSSdaisyUIを使って作りました。

<div class="tooltip" data-tip="Blueskyへ投稿する">
<button
class="btn bg-[#1185FE]"
data-aw-social-share="bluesky"
data-aw-url={url}
data-aw-text={text}
>
<svg
viewBox="0 0 256 256"
class="h-7 w-7"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 60.901 37.747 C 88.061 58.137 117.273 99.482 127.999 121.666 C 138.727 99.482 167.938 58.137 195.099 37.747 C 214.696 23.034 246.45 11.651 246.45 47.874 C 246.45 55.109 242.302 108.648 239.869 117.34 C 231.413 147.559 200.6 155.266 173.189 150.601 C 221.101 158.756 233.288 185.766 206.966 212.776 C 156.975 264.073 135.115 199.905 129.514 183.464 C 128.487 180.449 128.007 179.038 127.999 180.238 C 127.992 179.038 127.512 180.449 126.486 183.464 C 120.884 199.905 99.024 264.073 49.033 212.776 C 22.711 185.766 34.899 158.756 82.81 150.601 C 55.4 155.266 24.587 147.559 16.13 117.34 C 13.697 108.648 9.55 55.109 9.55 47.874 C 9.55 11.651 41.304 23.034 60.901 37.747 Z"
fill="white"></path>
</svg>
</button>
</div>

具体的に参考になっているのはBasicScripts.astroSocialShare.astroです。URLやタイトルの受け渡しについてはそちらを参照してください。

クリックイベントについても載せておきます。

function (_, elem) {
const network = elem.getAttribute('data-aw-social-share');
const url = encodeURIComponent(elem.getAttribute('data-aw-url'));
const text = encodeURIComponent(elem.getAttribute('data-aw-text'));
let href;
switch (network) {
case 'twitter':
href = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
break;
case 'bluesky':
href = `https://bsky.app/intent/compose?text=${text}+${url}`;
break;
case 'hatebu':
href = `https://b.hatena.ne.jp/add?mode=confirm&url=${url}`;
break;
default:
return;
}
const newlink = document.createElement('a');
newlink.target = '_blank';
newlink.href = href;
newlink.click();
}

元になったAstroWindではFacebookやLinkedInなどもありましたが本ブログでは使っていません。代わりに「はてなブックマーク」を設置しています。

いっそのことコピーボタンも作る

全SNSへの共有ボタンを設置するのは不可能であるため、記事のタイトルとURLをコピーできるボタンも合わせて設置することにしました。

画像の茶色のボタンです。

シェアボタンの見た目

daisyUIを使い、コピー時にツールチップで「コピーしました!」と表示させます。

import { useState, type ReactNode } from 'react';
import { cn } from '~/utils';
type Props = {
url: string | URL;
text: string;
className: string;
children: ReactNode;
};
function ClipboardButton({ url, text, className, children }: Props) {
const defaultText = 'タイトルとURLをコピーする';
const [dataTip, setDataTip] = useState(defaultText);
const [open, setOpen] = useState(false);
return (
<div
className={cn('tooltip', open ? 'tooltip-open' : '')}
data-tip={dataTip}
>
<button
className={className}
onClick={async () => {
try {
await navigator.clipboard.writeText(`${text}\n${url}`);
setDataTip('コピーしました!');
setOpen(true);
setTimeout(() => {
setOpen(false);
}, 3000);
setTimeout(() => {
setDataTip(defaultText);
}, 4000);
} catch (error) {
// 失敗
}
}}
>
{children}
</button>
</div>
);
}
export default ClipboardButton;

cnshadcn/uiなどにも書いてあるヘルパー関数です。
childrenは子コンポーネントで、ここにアイコンを渡します。

クリックした時の処理だけにフォーカスしてみましょう。

await navigator.clipboard.writeText(`${text}\n${url}`);
setDataTip('コピーしました!');
setOpen(true);
setTimeout(() => {
setOpen(false);
}, 3000);
setTimeout(() => {
setDataTip(defaultText);
}, 4000);

やっていることは次の3つです。

  1. クリップボードへの書き込み
  2. ツールチップでコピーを知らせる
  3. 数秒後にツールチップをもとに戻す

Twitter(X)の共有ボタン

前述のとおり今回はAstroWindを使ったため、Xの共有ボタンはほとんど自分で実装していません。
しかし、公式ドキュメントは漁ってメモしていたため、備忘録として残しておきます。

上記のドキュメント、旧名TwitterとXがすごく混ざっています(どっちで書けばいいんだ?)。

はてなブックマークの共有ボタン

はてなブックマークについては、公式でコピペで使えるものが用意されています。

はてなブックマークボタンの作成・設置について

ただ、筆者は読み込むscriptを減らしたかったため、次の記事を参考にhttps://b.hatena.ne.jp/add?mode=confirm&url=${url}を使って実装しました。

記事ページのSNSシェアボタン設定 – はてなブログMediaヘルプセンター


以上、シェアボタンの実装の調査記録と実例の備忘録でした。