Tips & Tricks

Web Share API Usage Guide with Claude Code

Learn about web share api usage guide using Claude Code. Practical tips and code examples included.

Web Share APIでネイティブの共有体験を提供

Web Share APIを使えば、OSネイティブの共有ダイアログを呼び出せます。モバイルではLINEやX(Twitter)など、インストール済みのアプリに直接共有でき、ユーザー体験が大幅に向上します。

基本的な共有ボタンの実装

> Web Share APIを使った共有ボタンを作成して。
> 非対応ブラウザにはSNSリンクのフォールバックを表示して。
// components/ShareButton.tsx
import { useState } from 'react';

interface ShareButtonProps {
  title: string;
  text: string;
  url: string;
}

export function ShareButton({ title, text, url }: ShareButtonProps) {
  const [showFallback, setShowFallback] = useState(false);
  const canShare = typeof navigator !== 'undefined' && !!navigator.share;

  const handleShare = async () => {
    if (canShare) {
      try {
        await navigator.share({ title, text, url });
      } catch (err) {
        if ((err as Error).name !== 'AbortError') {
          setShowFallback(true);
        }
      }
    } else {
      setShowFallback(true);
    }
  };

  return (
    <div className="relative">
      <button
        onClick={handleShare}
        className="flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
      >
        <ShareIcon />
        共有する
      </button>

      {showFallback && (
        <ShareFallback title={title} url={url} onClose={() => setShowFallback(false)} />
      )}
    </div>
  );
}

function ShareIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
      <path d="M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8" />
      <polyline points="16 6 12 2 8 6" />
      <line x1="12" y1="2" x2="12" y2="15" />
    </svg>
  );
}

SNSフォールバックコンポーネント

// components/ShareFallback.tsx
interface ShareFallbackProps {
  title: string;
  url: string;
  onClose: () => void;
}

function ShareFallback({ title, url, onClose }: ShareFallbackProps) {
  const encodedUrl = encodeURIComponent(url);
  const encodedTitle = encodeURIComponent(title);

  const platforms = [
    {
      name: 'X (Twitter)',
      href: `https://twitter.com/intent/tweet?text=${encodedTitle}&url=${encodedUrl}`,
      color: 'bg-black',
    },
    {
      name: 'Facebook',
      href: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
      color: 'bg-blue-600',
    },
    {
      name: 'LINE',
      href: `https://social-plugins.line.me/lineit/share?url=${encodedUrl}`,
      color: 'bg-green-500',
    },
    {
      name: 'はてなブックマーク',
      href: `https://b.hatena.ne.jp/entry/${url}`,
      color: 'bg-blue-400',
    },
  ];

  return (
    <div className="absolute right-0 top-full mt-2 w-56 rounded-xl border bg-white p-3 shadow-lg dark:bg-gray-800">
      <div className="mb-2 flex items-center justify-between">
        <span className="text-sm font-medium">共有先を選択</span>
        <button onClick={onClose} className="text-gray-400 hover:text-gray-600">&times;</button>
      </div>
      <div className="space-y-1">
        {platforms.map(p => (
          <a
            key={p.name}
            href={p.href}
            target="_blank"
            rel="noopener noreferrer"
            className={`block rounded-lg ${p.color} px-3 py-2 text-sm text-white transition-opacity hover:opacity-80`}
          >
            {p.name}
          </a>
        ))}
      </div>
      <button
        onClick={() => { navigator.clipboard.writeText(url); onClose(); }}
        className="mt-2 w-full rounded-lg bg-gray-100 px-3 py-2 text-sm hover:bg-gray-200 dark:bg-gray-700"
      >
        URLをコピー
      </button>
    </div>
  );
}

ファイルの共有

// 画像やファイルの共有
async function shareFile(file: File, title: string): Promise<void> {
  if (!navigator.canShare?.({ files: [file] })) {
    console.log('ファイル共有は非対応です');
    return;
  }

  await navigator.share({
    title,
    files: [file],
  });
}

// Canvas画像の共有
async function shareCanvasImage(canvas: HTMLCanvasElement): Promise<void> {
  const blob = await new Promise<Blob | null>(resolve =>
    canvas.toBlob(resolve, 'image/png')
  );
  if (!blob) return;

  const file = new File([blob], 'image.png', { type: 'image/png' });
  await shareFile(file, '生成した画像');
}

Web Share Target API

PWAとして共有ターゲットに登録することで、他のアプリからの共有を受け取ることもできます。

{
  "share_target": {
    "action": "/share-receiver",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "title": "title",
      "text": "text",
      "url": "url",
      "files": [
        {
          "name": "media",
          "accept": ["image/*", "video/*"]
        }
      ]
    }
  }
}

Zusammenfassung

Web Share APIは、モバイルユーザーに特に効果的な共有機能を提供します。Claude Codeを使えば、クリップボードAPIと連携したフォールバック付きの実装を効率的に構築できます。PWAと組み合わせれば、共有ターゲットとしての機能も追加可能です。詳しい仕様はMDN Web Docs - Web Share APIを参照してください。

#Claude Code #Web Share API #SNS共有 #mobile #PWA