> For the complete documentation index, see [llms.txt](https://docs.nubrick.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nubrick.app/experiment_menu/embed/embedding_guide.md).

# 実装ガイド

`Nubrick` のエディタで作成された埋め込みエクスペリメントを、アプリ内の特定の場所に埋め込むことができます。

{% hint style="info" %}
コード側では、エクスペリメントIDまたは任意のカスタムID（IDエイリアス）を設定し、使用できます。\
場所ごとにカスタムIDを事前に設定しておくことをお勧めします。これにより、コードを編集せずに、`Nubrick` の管理画面で柔軟にエクスペリメントを変更できます。
{% endhint %}

## 基本的な使い方 <a href="#basic-usage" id="basic-usage"></a>

{% tabs %}
{% tab title="iOS (SwiftUI)" %}

```swift
NubrickSDK.embedding("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
```

{% endtab %}

{% tab title="iOS (UIKit)" %}

```swift
let view = NubrickSDK.embeddingUIView("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
self.addSubview(view)
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}

```kotlin
import app.nubrick.nubrick.NubrickSDK

NubrickSDK.Embedding("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
```

{% endtab %}

{% tab title="Android (Java / XML)" %}

```xml
<app.nubrick.nubrick.view.NubrickEmbeddingView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:nubrickExperimentId="EXPERIMENT_ID_OR_EXPERIMENT_ID_ALIAS" />
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:nubrick_flutter/embedding.dart';

NubrickEmbedding("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
```

{% endtab %}
{% endtabs %}

## 埋め込みコンポーネントのサイズ

埋め込みコンポーネントのサイズは、次の2種類の指定方法があります

### 1. アプリ側で指定する

アプリ内で明示的にサイズを指定することで、親レイアウトとの整合が取りやすく、エディタ側での高さ未指定によるレイアウト崩れなど、意図しない挙動を防ぐことができます。 高さの異なるコンテンツを配信するユースケースがない場合は、こちらの方法を推奨しております。

{% tabs %}
{% tab title="iOS (SwiftUI)" %}

```swift
NubrickSDK.embedding("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
    .frame(height: 200)
```

{% endtab %}

{% tab title="iOS (UIKit)" %}

```swift
let view = NubrickSDK.embeddingUIView("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>")
view.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
self.addSubview(view)
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}

```kotlin
import app.nubrick.nubrick.NubrickSDK

NubrickSDK.Embedding(
    "<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>",
    modifier = Modifier.height(200f.dp),
)
```

{% endtab %}

{% tab title="Android (Java / XML)" %}

```xml
<app.nubrick.nubrick.view.NubrickEmbeddingView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    app:nubrickExperimentId="EXPERIMENT_ID_OR_EXPERIMENT_ID_ALIAS" />
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:nubrick_flutter/embedding.dart';

NubrickEmbedding("<EXPERIMENT_ID or EXPERIMENT_ID_ALIAS>", height: 200)
```

{% endtab %}
{% endtabs %}

### 2. エディタ側で指定する

アプリ側の変更なしで、異なるサイズの施策を配信したり、A/Bテストを実施することが可能です。

エディタ上で該当のframeを選択した状態で、右のパネルからframeのサイズを変更できます。

<figure><img src="/files/9SeEhdWhoGj9S35iNlA6" alt="Frame size setting"><figcaption></figcaption></figure>

### ⚠️ 高さの指定ミスに注意

アプリ側でもエディタ側でもサイズが指定されていない場合、**親ビューの制約に従う（fill）** 挙動になります。

* 親がサイズを持っている場合は、その領域いっぱいに表示されます
* 親が軸方向に無制限な場合（`VStack` / `Column` / スクロール内など）は、高さが潰れる・レイアウトが崩れることがあります

また、アプリ側とエディタ側で異なる数値が指定されている場合も、予期しない表示となるおそれがあるため、ご注意ください。

### 埋め込みコンポーネントのサイズを取得する

`onSizeChange` を使うと、埋め込みコンポーネントの実サイズ（`fill` / `fixed`）を受け取れます。\
このコールバックは、実際の埋め込みページが表示されたときだけ呼ばれます。読み込み中や `not found` の状態では呼ばれません。

`fill` は固定サイズを適用しない（親ビューの制約に従う）ことを表します。

{% tabs %}
{% tab title="iOS (SwiftUI)" %}

```swift
NubrickSDK.embedding(
    "<EXPERIMENT_ID>",
    onSizeChange: { width, height in
        print(width, height)
    }
)
```

{% endtab %}

{% tab title="iOS (UIKit)" %}

```swift
let view = NubrickSDK.embeddingUIView(
    "<EXPERIMENT_ID>",
    onSizeChange: { width, height in
        print(width, height)
    }
)
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}

```kotlin
NubrickSDK.Embedding(
    "<EXPERIMENT_ID> or <EXPERIMENT_CUSTOM_ID>",
    onSizeChange = { width, height ->
        println("width=$width, height=$height")
    }
)
```

{% endtab %}

{% tab title="Android (Java / XML)" %}

```java
NubrickEmbeddingView embeddingView = findViewById(R.id.nubrick_embedding);
embeddingView.setOnSizeChangeListener((width, height) -> {
    System.out.println("width=" + width + ", height=" + height);
});
```

{% endtab %}
{% endtabs %}

## イベントハンドラーの追加

埋め込みタイプのエクスペリメントに、イベントハンドラーを追加することができます。

{% tabs %}
{% tab title="iOS (SwiftUI)" %}

```swift
NubrickSDK.embedding("<EXPERIMENT_ID>", onEvent: { event in
    print(event)
})
.frame(height: 200)
```

{% endtab %}

{% tab title="iOS (UIKit)" %}

```swift
let view = NubrickSDK.embeddingUIView("<EXPERIMENT_ID>", onEvent: { event in
    print(event)
})
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}

```kotlin
import app.nubrick.nubrick.NubrickSDK

NubrickSDK.Embedding(
    "<EXPERIMENT_ID> or <EXPERIMENT_CUSTOM_ID>",
    onEvent = { event ->
        println("Event: ${event.name}, deepLink: ${event.deepLink}")
    }
)
```

{% endtab %}

{% tab title="Android (Java / XML)" %}
XML で `NubrickEmbeddingView` に ID を設定し、Java でイベントリスナーを登録します。

```xml
<app.nubrick.nubrick.view.NubrickEmbeddingView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nubrick_embedding"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    app:nubrickExperimentId="EXPERIMENT_ID_OR_EXPERIMENT_ID_ALIAS" />
```

```java
import app.nubrick.nubrick.view.NubrickEmbeddingView;

NubrickEmbeddingView embeddingView = findViewById(R.id.nubrick_embedding);
embeddingView.setOnEventListener(event -> {
    System.out.println(
        "Event: " + event.getName() + ", deepLink: " + event.getDeepLink()
    );
});
```

{% endtab %}

{% tab title="Flutter" %}

```dart
NubrickEmbedding(
  "<EXPERIMENT_ID> or <EXPERIMENT_ID_ALIAS>",
  height: 200,
  onEvent: (event) {
    print("Nubrick Embedding Event: ${event.payload}");
  },
),
```

{% endtab %}
{% endtabs %}

## ローディング状態のカスタマイズ

読み込み中、失敗、完了の各フェーズでビューをカスタマイズできます。

{% tabs %}
{% tab title="iOS (SwiftUI)" %}
`SwiftUIEmbeddingPhase` を使って各フェーズをハンドリングします。

```swift
NubrickSDK.embedding("<EXPERIMENT_ID>", onEvent: nil) { phase in
    switch phase {
    case .loading:
        Text("loading")
    case .notFound:
        Text("not found")
    case .failed:
        Text("error")
    case .completed(let view):
        view.frame(height: 200)
    }
}
```

{% endtab %}

{% tab title="iOS (UIKit)" %}
`UIKitEmbeddingPhase` を使って各フェーズをハンドリングします。

```swift
let view = NubrickSDK.embeddingUIView("<EXPERIMENT_ID>", onEvent: nil) { phase in
    switch phase {
    case .loading:
        return UIActivityIndicatorView()
    case .notFound:
        return UILabel()
    case .failed:
        return UILabel()
    case .completed(let component):
        return component
    }
}
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}
`content` パラメータを使って `EmbeddingLoadingState` をハンドリングします。

```kotlin
import app.nubrick.nubrick.NubrickSDK
import app.nubrick.nubrick.component.EmbeddingLoadingState

NubrickSDK.Embedding("<EXPERIMENT_ID> or <EXPERIMENT_CUSTOM_ID>") { state ->
    when (state) {
        is EmbeddingLoadingState.Loading -> CircularProgressIndicator()
        is EmbeddingLoadingState.Completed -> state.view()
        is EmbeddingLoadingState.NotFound -> Text("Not found")
        is EmbeddingLoadingState.Failed -> Text("Error")
    }
}
```

{% endtab %}

{% tab title="Android (Java / XML)" %}
`NubrickEmbeddingView` は読み込み状態を内部で処理し、読み込みが完了した埋め込みコンポーネントを表示します。読み込み状態ごとのビューをカスタマイズする場合は、アプリモジュールで Kotlin/Jetpack Compose を有効にし、埋め込み部分だけを `NubrickSDK.Embedding(...)` で実装して、`ComposeView` を介して既存の XML レイアウトに組み込んでください。
{% endtab %}

{% tab title="Flutter" %}
`builder` を使って各フェーズをハンドリングします。

```dart
NubrickEmbedding(
  "<EXPERIMENT_ID> or <EXPERIMENT_ID_ALIAS>",
  builder: (context, phase, child) {
    case ExperimentPhase.loading:
      return const SizedBox(height: 200, child: Center(child: CircularProgressIndicator()));
    case ExperimentPhase.completed:
      return const SizedBox(height: 200, child: child);
    case ExperimentPhase.notFound:
      return const SizedBox(height: 200, child: Center(child: Text("Experiment not found.")));
    default:
      return const SizedBox.shrink();
  },
),
```

{% endtab %}
{% endtabs %}

## 引数の渡し方

`arguments` としてパラメータを渡すと、コンポーネント内で展開される動的な変数として利用することができます。

{% tabs %}
{% tab title="iOS (SwiftUI)" %}

```swift
NubrickSDK.embedding(
    "<EXPERIMENT_ID>",
    arguments: ["item_id": itemId]
)
.frame(height: 200)
```

{% endtab %}

{% tab title="iOS (UIKit)" %}

```swift
let view = NubrickSDK.embeddingUIView(
    "<EXPERIMENT_ID>",
    arguments: ["item_id": itemId]
)
```

作成後に `arguments` を更新する場合は、返された `UIView` を `NubrickEmbeddingUpdatable` にキャストして `update(arguments:)` を呼び出します。

```swift
(view as? NubrickEmbeddingUpdatable)?.update(arguments: ["item_id": itemId])
```

{% endtab %}

{% tab title="Android (Kotlin / Compose)" %}

```kotlin
import app.nubrick.nubrick.NubrickSDK

NubrickSDK.Embedding(
    "<EXPERIMENT_ID> or <EXPERIMENT_CUSTOM_ID>",
    arguments = mapOf("item_id" to itemId)
)
```

{% endtab %}

{% tab title="Android (Java / XML)" %}
XML で ID を設定した `NubrickEmbeddingView` に、Java から `arguments` を渡します。

```java
import app.nubrick.nubrick.view.NubrickEmbeddingView;

import java.util.Collections;

NubrickEmbeddingView embeddingView = findViewById(R.id.nubrick_embedding);
embeddingView.setArguments(
    Collections.singletonMap("item_id", itemId)
);
```

{% endtab %}

{% tab title="Flutter" %}

```dart
NubrickEmbedding(
  "<EXPERIMENT_ID> or <EXPERIMENT_ID_ALIAS>",
  height: 200,
  arguments: {
    'item_id': itemId,
  },
),
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.nubrick.app/experiment_menu/embed/embedding_guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
