# 機能設計書 115-YouTube Embed

## 概要

本ドキュメントは、Next.jsの`@next/third-parties`パッケージが提供するYouTube動画埋め込みの最適化統合コンポーネントの設計を記載する。YouTubeEmbedコンポーネントにより、`third-party-capital`ライブラリを活用したYouTube動画プレーヤーの最適な埋め込みを実現する。

### 本機能の処理概要

**業務上の目的・背景**：YouTube動画の埋め込みはコンテンツマーケティング、教育コンテンツ、プロモーションサイトなど多くのビジネスシーンで必要とされる。標準的なiframe埋め込みではパフォーマンスに影響があるため、Next.jsアプリケーション向けに最適化されたコンポーネントを提供する。`third-party-capital`ライブラリがlite-youtube-embedパターンによる最適化を担当する。

**機能の利用シーン**：Webサイトにプロモーション動画を埋め込む場面、教育コンテンツでチュートリアル動画を表示する場面、ブログ記事にYouTube動画を挿入する場面で利用される。

**主要な処理内容**：
1. propsからYouTube Embed APIのパラメータを構築
2. `third-party-capital`のYouTubeEmbed関数でHTML・スクリプト・スタイルシート情報を生成
3. ThirdPartyScriptEmbedで最適にDOM挿入
4. 関連スクリプト（lite-youtube-embed等）のnext/script経由での読み込み
5. スタイルシートの最適な読み込み

**関連システム・外部連携**：YouTube Embed API、lite-youtube-embedライブラリと連携する。

**権限による制御**：特に権限制御はない。公開されたYouTube動画のvideoidが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 任意のページ | 主機能 | YouTubeEmbedコンポーネントの配置による動画表示 |

## 機能種別

外部サービス統合・UI表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| videoid | string | Yes | YouTube動画ID | 空文字でないこと |
| height | number | No | プレーヤー高さ（px） | - |
| width | number | No | プレーヤー幅（px） | - |
| playlabel | string | No | 再生ボタンのアクセシビリティラベル | - |
| params | string | No | YouTube IFrame Player APIパラメータ | - |
| style | string | No | CSSスタイル | - |

### 入力データソース

- コンポーネントのprops（JSX属性として指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| html | string | YouTube埋め込みHTML（lite-youtube-embed等） |
| scripts | Array<{url, strategy}> | 読み込みスクリプト一覧 |
| stylesheets | string[] | 読み込みスタイルシート一覧 |

### 出力先

- DOM（ブラウザ上のdiv要素 + script要素 + link要素）

## 処理フロー

### 処理シーケンス

```
1. YouTubeEmbedコンポーネントのマウント
   └─ propsをTPCYouTubeEmbed関数に渡す
2. HTML・スクリプト・スタイルシートの生成
   └─ third-party-capitalのYouTubeEmbed関数で生成
3. ThirdPartyScriptEmbedでHTML挿入
   └─ div要素にdangerouslySetInnerHTMLでHTML挿入
4. スクリプトの読み込み
   └─ scripts配列をマップしてnext/Scriptコンポーネントで読み込み
5. スタイルシートの読み込み
   └─ next/Scriptのstylesheets propsで関連スタイルシートを読み込み
```

### フローチャート

```mermaid
flowchart TD
    A[YouTubeEmbed マウント] --> B[TPCYouTubeEmbed関数呼び出し]
    B --> C[html, scripts, stylesheets取得]
    C --> D[ThirdPartyScriptEmbed]
    D --> E[div要素にHTML挿入]
    D --> F{scriptsあり?}
    F -->|Yes| G[各scriptをnext/Scriptで読み込み]
    G --> H[strategyマッピング]
    H --> I[stylesheets指定]
    F -->|No| J[HTML表示のみ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ストラテジーマッピング | server->beforeInteractive, client->afterInteractive, idle->lazyOnload, worker->workerに変換 | スクリプト読み込み時 |
| BR-02 | デフォルトサイズ | height/widthが未指定の場合nullが渡されautoスタイルが適用される | サイズ未指定時 |

### 計算ロジック

特になし。

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効な動画ID | 存在しないvideoidを指定 | YouTube側のエラー表示 |

### リトライ仕様

リトライ機能は実装されていない。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

- lite-youtube-embedパターンによるサムネイル先行表示で初期ロード最適化
- next/scriptのstrategy設定による読み込みタイミング最適化
- stylesheets propsによるスタイルシートの最適プリロード

## セキュリティ考慮事項

- dangerouslySetInnerHTMLを使用（third-party-capitalが生成したHTMLのみ）
- third-party-capitalライブラリの出力を信頼する前提

## 備考

- GoogleMapsEmbedとは異なり、スクリプトとスタイルシートの動的読み込みが含まれる
- scriptStrategy変換マップにより、third-party-capitalのストラテジーをnext/scriptのストラテジーに変換する
- data-ntpc="YouTubeEmbed"属性がパフォーマンス計測に使用される

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | google.ts | `packages/third-parties/src/types/google.ts` | YouTubeEmbed型の定義（videoid, height, width, playlabel, params, style） |

**読解のコツ**: YouTubeEmbed型のheight/widthはnumber型（GoogleMapsEmbedはnumber | string）。videoidは小文字で定義されている点に注意。

#### Step 2: メインコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | youtube-embed.tsx | `packages/third-parties/src/google/youtube-embed.tsx` | YouTubeEmbedコンポーネントの実装 |

**主要処理フロー**:
- **9-14行目**: scriptStrategyマッピングオブジェクト（server/client/idle/workerをnext/script戦略に変換）
- **16-36行目**: YouTubeEmbedコンポーネント
- **17行目**: TPCYouTubeEmbed関数でhtml, scripts, stylesheetsを取得
- **20-24行目**: ThirdPartyScriptEmbedでHTML・サイズ・data-ntpc設定
- **26-33行目**: scripts配列をnext/Scriptコンポーネントにマップ（key, src, strategy, stylesheets）

#### Step 3: 共通埋め込みコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ThirdPartyScriptEmbed.tsx | `packages/third-parties/src/ThirdPartyScriptEmbed.tsx` | 共通のサードパーティ埋め込み（childrenとhtmlの両方をサポート） |

**主要処理フロー**:
- **33-49行目**: children（Scriptコンポーネント）とhtml（div）の両方をレンダリング
- **20-31行目**: useEffectでperformance.mark送信

### プログラム呼び出し階層図

```
YouTubeEmbed (React Component)
    |
    +-- TPCYouTubeEmbed (third-party-capital)
    |       +-- html, scripts, stylesheets生成
    |
    +-- ThirdPartyScriptEmbed
            |
            +-- children: Script要素群
            |       +-- next/script (strategy変換済み, stylesheets付き)
            |
            +-- div (dangerouslySetInnerHTML)
            |
            +-- useEffect -> performance.mark
```

### データフロー図

```
[入力]                      [処理]                             [出力]

videoid + params -------> TPCYouTubeEmbed() ----------> html (サムネイル+lite-embed)
                               |                        scripts (JSファイルURL一覧)
                               |                        stylesheets (CSSファイルURL一覧)
                               |
                          ThirdPartyScriptEmbed
                               |
                               +-- html -> div要素
                               +-- scripts -> next/Script要素群
                               +-- stylesheets -> Script.stylesheets props
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| youtube-embed.tsx | `packages/third-parties/src/google/youtube-embed.tsx` | ソース | YouTubeEmbedコンポーネント |
| ThirdPartyScriptEmbed.tsx | `packages/third-parties/src/ThirdPartyScriptEmbed.tsx` | ソース | 共通のサードパーティ埋め込みコンポーネント |
| google.ts | `packages/third-parties/src/types/google.ts` | ソース | YouTubeEmbed型定義 |
| index.tsx | `packages/third-parties/src/google/index.tsx` | ソース | パッケージエクスポート |
| script.tsx | `packages/next/src/client/script.tsx` | ソース | next/scriptコンポーネント（依存先） |
