メインコンテンツへスキップ
Code & Craft
Web制作 約6分で読めます

Web Share API 実装ガイド|ネイティブアプリ風のシェア機能を作る

Web Share API でネイティブアプリ風のシェア機能を実装する方法を解説。スマホ・PC両対応の実装パターン、ファイル共有、フォールバック戦略を実例付きで紹介。

ネイティブアプリではお馴染みの「シェアシート」を Web でも実装できるのが Web Share API です。デバイスの OS 標準のシェア機能を呼び出せるため、LINE・X・Gmail など、ユーザーがインストールしているアプリに直接共有できます。2026年現在、スマートフォンを中心に広く使える機能となっています。

Web Share API とは

Web Share API は、ブラウザからネイティブのシェア機能を呼び出す JavaScript API です。

navigator.share({
  title: '記事タイトル',
  text: '素晴らしい記事を見つけました',
  url: 'https://example.com/article',
});

このコードを実行すると、スマートフォンでは OS のシェアシートが開き、インストール済みアプリ(LINE、X、Gmail 等)に共有できます。

ブラウザ対応(2026年4月)

プラットフォームサポート
Chrome Android
Safari iOS
Safari macOS
Chrome macOS
Chrome Windows
Edge Windows
Firefox⚠️ 部分対応

主要ブラウザで広くサポートされています。Firefox での対応が遅れていますが、フォールバック実装があれば問題ありません。

基本的な使い方

シェアボタンの実装

<button id="share-btn">シェアする</button>

<script>
document.getElementById('share-btn').addEventListener('click', async () => {
  if (!navigator.share) {
    alert('お使いのブラウザはシェア機能に対応していません');
    return;
  }

  try {
    await navigator.share({
      title: 'Code & Craft',
      text: 'Web制作の実践ノウハウを発信するテックブログ',
      url: window.location.href,
    });
  } catch (err) {
    // ユーザーがキャンセルした場合も含む
    if (err.name !== 'AbortError') {
      console.error('Share failed:', err);
    }
  }
});
</script>

シェアデータの構成要素

interface ShareData {
  title?: string;     // タイトル
  text?: string;      // 本文・説明
  url?: string;       // URL
  files?: File[];     // 共有するファイル(画像、PDF等)
}

最低1つは必須: title、text、url、files のうち、少なくとも1つは指定する必要があります。

タイトル + URL

navigator.share({
  title: '記事タイトル',
  url: 'https://example.com/article',
});

説明文付き

navigator.share({
  title: 'Code & Craft',
  text: '現場で使える技術Tipsを発信',
  url: 'https://clvr.lol',
});

ファイル共有

画像や PDF などのファイルも共有できます(canShare() での事前チェックが必要)。

async function shareImage(imageBlob) {
  const file = new File([imageBlob], 'screenshot.png', { type: 'image/png' });

  const shareData = {
    title: 'スクリーンショット',
    files: [file],
  };

  if (navigator.canShare && navigator.canShare(shareData)) {
    try {
      await navigator.share(shareData);
    } catch (err) {
      console.error(err);
    }
  } else {
    console.log('このデバイスはファイル共有に対応していません');
  }
}

対応ファイル形式(プラットフォーム依存)

形式Android ChromeiOS Safari
JPEG
PNG
WebP
PDF
MP4
テキスト

実践パターン

記事のシェアボタン

<button class="share-button" data-title="..." data-url="...">
  <svg>...</svg>
  <span>シェア</span>
</button>

<script>
document.querySelectorAll('.share-button').forEach(btn => {
  btn.addEventListener('click', async () => {
    const title = btn.dataset.title;
    const url = btn.dataset.url;

    if (navigator.share) {
      try {
        await navigator.share({ title, url });
      } catch (err) {
        if (err.name !== 'AbortError') {
          fallbackShare(title, url);
        }
      }
    } else {
      fallbackShare(title, url);
    }
  });
});

function fallbackShare(title, url) {
  // クリップボードにコピー
  navigator.clipboard.writeText(url);
  alert('URLをコピーしました');
}
</script>

画像のスクリーンショットシェア

Canvas から生成した画像を直接シェアする例です。

async function shareCanvasAsImage() {
  const canvas = document.querySelector('canvas');

  canvas.toBlob(async (blob) => {
    const file = new File([blob], 'design.png', { type: 'image/png' });

    const shareData = {
      title: 'デザインを共有',
      text: '私のデザインを見てください',
      files: [file],
    };

    if (navigator.canShare && navigator.canShare(shareData)) {
      await navigator.share(shareData);
    }
  }, 'image/png');
}

フォールバック戦略

Web Share API 未対応環境では、代替手段を用意しましょう。

戦略1: 個別のシェアボタン

<div class="share-buttons">
  <a href="https://twitter.com/intent/tweet?url=..." target="_blank">X</a>
  <a href="https://social-plugins.line.me/lineit/share?url=..." target="_blank">LINE</a>
  <a href="https://b.hatena.ne.jp/entry/..." target="_blank">はてブ</a>
</div>

戦略2: クリップボードコピー

async function shareWithFallback(data) {
  if (navigator.share) {
    try {
      await navigator.share(data);
      return;
    } catch (err) {
      if (err.name === 'AbortError') return;
    }
  }

  // フォールバック: URLコピー
  await navigator.clipboard.writeText(data.url);
  showToast('URLをコピーしました');
}

戦略3: プログレッシブエンハンスメント

<!-- デフォルト: 個別シェアリンク -->
<div class="share-links">
  <a href="https://twitter.com/...">X</a>
  <a href="https://line.me/...">LINE</a>
</div>

<!-- JavaScript で Web Share 対応を検出したら切り替え -->
<script>
if (navigator.share) {
  document.querySelector('.share-links').innerHTML = `
    <button id="native-share">シェア</button>
  `;
  document.getElementById('native-share').addEventListener('click', async () => {
    await navigator.share({
      title: document.title,
      url: window.location.href,
    });
  });
}
</script>

セキュリティと制約

1. HTTPS 必須

Web Share API は HTTPS 環境でのみ動作します。localhost は例外です。

2. ユーザーアクション起点

navigator.share() は、クリックやタップなどのユーザーアクションから呼ばれなければなりません。ページロード時の自動実行は拒否されます。

// NG: ページロード時に実行
window.addEventListener('load', () => {
  navigator.share({ ... }); // エラー
});

// OK: ユーザークリックで実行
button.addEventListener('click', () => {
  navigator.share({ ... }); // OK
});

3. iframe 内での制約

iframe 内では allow="web-share" 属性が必要です。

<iframe src="..." allow="web-share"></iframe>

UI デザインの注意点

iOS と Android の違い

  • iOS Safari: シェアシートが画面下から全画面で表示
  • Android Chrome: ボトムシートが小さく表示

ボタンの文言

デバイスの言語設定に応じて、シェア機能の表示が変わります。ボタンは「シェア」「共有」等、一般的な文言で統一しましょう。

アイコン

汎用的な「シェアアイコン」を使用するのが一般的です。

<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
  <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
  <polyline points="16 6 12 2 8 6"/>
  <line x1="12" y1="2" x2="12" y2="15"/>
</svg>

アクセシビリティ対応

シェアボタンにも適切な ARIA 属性を付けましょう。

<button
  type="button"
  aria-label="この記事をシェアする"
  class="share-button"
>
  <svg aria-hidden="true">...</svg>
  <span class="sr-only">シェア</span>
</button>

まとめ

Web Share API は、以下のようなサービスで特に効果を発揮します。

  • ブログ・ニュースサイト: 記事のシェア
  • ECサイト: 商品ページの共有
  • レシピサイト: お気に入りレシピの共有
  • 画像ギャラリー: 写真の送信
  • ドキュメントサービス: PDF の共有

実装コストは低く、フォールバックも用意すれば全ユーザーに対応できます。特にモバイル向けのコンテンツでは、ネイティブアプリ並みのユーザー体験を提供できるため、導入する価値は大きいです。

参考リンク

#Web API #シェア #モバイル #JavaScript
シェア: