プロフィール

arismmn timeline blog

← ブログ一覧に戻る

つぶやきにX(Twitter)埋め込み表示機能を実装した

AstroセキュリティUI/UX

概要

つぶやき(タイムライン上のノート)のテキストに X(Twitter)のツイートURLが含まれていた場合、<blockquote class="twitter-tweet"> と Twitter の公式ウィジェットスクリプトを使ってツイートを埋め込み表示する機能を追加した。

既存の YouTube 埋め込み機能(extractYouTubeVideoIds / stripYouTubeUrls)と同じパターンで実装した。

背景と目的

これまで、つぶやきにツイートの URL を貼り付けても単なるテキストとして表示されるだけだった。ツイートの内容を確認するには URL を開く必要があった。

この機能により、タイムライン上でツイートをインラインで読めるようになった。

実装内容

対応する URL の形式

以下の形式の URL を自動検出する:

  • https://twitter.com/{username}/status/{tweetId}
  • https://x.com/{username}/status/{tweetId}

追加した関数と変数

YouTube 埋め込みと同じ設計パターンで、以下の3要素を実装した。

extractXTweetUrls(text)

テキスト中の X/Twitter ツイート URL をすべて抽出して返す。クエリパラメータやフラグメントは除去し、https://twitter.com/{user}/status/{id} の正規形に統一する。ツイート ID は数字のみ(最大20桁)に制限する。

stripXUrls(text)

テキストから X/Twitter URL をすべて除去した文字列を返す。埋め込みが成功した URL をテキスト中に重複して表示しないための処理。

isEmbedOnly

YouTube URL と X/Twitter URL をすべて除去した後のテキストが空かどうかを判定するフラグ。true のときはつぶやきのテキスト枠を表示せず、埋め込みのみを表示する。

なお、YouTube 埋め込みに使っていた isYouTubeOnly は、この isEmbedOnly に統合して廃止した。X と YouTube が混在する投稿でも正しく動作する。

表示の仕組み

<blockquote class="twitter-tweet" data-theme="dark" data-dnt="true">
  <a href="{tweetUrl}"></a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

X の公式ウィジェット(platform.twitter.com/widgets.js)が blockquote をインタラクティブなカードに変換する。ウィジェットスクリプトは、ツイート埋め込みが存在するページにのみ条件付きで挿入する。

data-dnt="true" を指定してトラッキングをオプトアウトする。

変更したファイル

  • src/components/TimelineItem.astro — タイムライン上の表示(ダークテーマ)
  • src/pages/notes/[id].astro — 個別ページの表示(ライトテーマ)

個別ページは白背景のため data-theme="light" を指定している。

セキュリティ対策

ツイート ID の厳密な検証

URL から抽出したツイート ID を <blockquote>href に設定する前に、数字のみ(最大20桁)であることを正規表現で検証する。これにより、URL に細工された文字列がそのまま DOM に流れ込むことを防ぐ。

if (/^\d{1,20}$/.test(tweetId)) {
  urls.push(`https://twitter.com/${match[1]}/status/${tweetId}`);
}

ユーザー名の長さ制限

URL パターンのユーザー名部分を \w{1,50} に制限し、異常に長い文字列でのマッチを防ぐ。

クエリパラメータの除去

?s=21 などのトラッキングパラメータが付いたツイート URL も正規形(パラメータなし)に正規化してから出力する。

テキスト表示の仕様まとめ

投稿内容 テキスト枠 埋め込み
テキストのみ 表示 なし
テキスト + YouTube URL URL 省略して表示 YouTube
テキスト + X URL URL 省略して表示 X ツイート
YouTube URL のみ 非表示 YouTube
X URL のみ 非表示 X ツイート
YouTube + X URL のみ 非表示 YouTube + X ツイート

URL のみの投稿でテキスト枠を非表示にする処理は、YouTube 埋め込みの実装時に導入した isYouTubeOnly フラグを発展させて isEmbedOnly に統合した。

Claude Code
Powered by
Claude Code
(使用モデル Sonnet 4.6)
← ブログ一覧に戻る