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

# 앱 임베드 가이드

{% hint style="info" %}
**젠서 디스커버리 전용 기능**입니다.
{% endhint %}

앱 임베드는 고객사 앱 안에 젠서 디스커버리를 WebView 또는 iframe으로 넣는 기능입니다. 임베드된 화면에서는 젠서 헤더가 숨겨지고 상품 상세가 오버레이로 표시됩니다.

고객사가 할 일은 **"앱에서 열렸다"는 신호를 보내는 것**뿐입니다. 헤더 숨김과 상품 상세 오버레이는 **젠서가 자동으로 처리**합니다.

***

## **1. 연동 방식**

"앱에서 열렸다"는 신호를 전달하는 방법입니다. 신호에 쓰는 값(토큰·파라미터)은 **젠서와 협의해 정합니다.**

{% tabs %}
{% tab title="iOS (WKWebView)" %}
WebView의 UserAgent에 협의한 토큰을 추가합니다.

```swift
let config = WKWebViewConfiguration()
// UA 끝에 "앱이름/버전 + 협의 토큰" 형식으로 추가 (GenserApp은 예시)
config.applicationNameForUserAgent = "MyApp/1.0.0 GenserApp"
let webView = WKWebView(frame: .zero, configuration: config)
```

{% endtab %}

{% tab title="Android (WebView)" %}
WebView의 UserAgent에 협의한 토큰을 추가합니다.

```kotlin
val defaultUA = webView.settings.userAgentString
// 중복 추가 방지: 이미 포함돼 있지 않을 때만 추가
if (!defaultUA.contains("GenserApp")) {
    webView.settings.userAgentString = "$defaultUA MyApp/1.0.0 GenserApp"
}
```

{% endtab %}

{% tab title="웹앱 / iframe" %}
임베드 URL에 협의한 파라미터를 추가합니다.

```
https://<젠서 디스커버리 주소>?embed=1    // 예시 파라미터, 실제 값은 젠서와 협의
```

{% endtab %}
{% endtabs %}

***

## **2. 적용 화면**

신호가 전달되면 아래처럼 동작합니다. **◇ 자동 적용** 은 genser가 자동으로 처리하는 부분, **◇ 적용 가이드** 는 고객사 앱에서 살짝 구현해 주시면 되는 부분입니다.

{% tabs %}
{% tab title="헤더 숨김 (자동)" %}
고객사(파트너) 앱의 헤더는 **그대로 유지**되고, genser 화면 자체의 헤더만 **자동으로 사라집니다.** 덕분에 로고가 중복되지 않고 genser 화면이 앱에 자연스럽게 이어집니다. 고객사에서 따로 하실 일은 없습니다.

<figure><img src="/files/Pq7oKk8fGKi6VjTnfOj0" alt=""><figcaption></figcaption></figure>

{% endtab %}

{% tab title="상품 상세 오버레이 (구현)" %}
여기 뜨는 상품 상세는 **고객사의 상품 상세 페이지(PDP)** 입니다. 상품을 선택하면 고객사 PDP가 새 화면으로 열리는데, 이때 **전체 화면 전환 대신 오버레이(레이어)로 띄워 주시면** 위 이미지처럼 앱을 벗어나지 않고 매끄럽게 이어집니다.

<figure><img src="/files/bPACl6xd5IQ4GsiQYkMO" alt=""><figcaption></figcaption></figure>

아래처럼 고객사 PDP를 오버레이로 열도록 구현해 주시면 됩니다.

**iOS** — 모달 시트로 present

```swift
let vc = UIViewController()
let web = WKWebView(frame: vc.view.bounds)
web.load(URLRequest(url: pdpURL))          // 고객사 PDP 주소
vc.view.addSubview(web)
vc.modalPresentationStyle = .pageSheet     // 시트로 떠오르는 오버레이
present(vc, animated: true)
```

**Android** — BottomSheet로 표시

```kotlin
val dialog = BottomSheetDialog(context)
val web = WebView(context).apply { loadUrl(pdpUrl) }  // 고객사 PDP 주소
dialog.setContentView(web)
dialog.show()
```

**웹앱 / iframe** — 고정 오버레이 레이어

```html
<!-- 전체 화면 전환 대신 오버레이 레이어로 -->
<div class="pdp-overlay">        <!-- position:fixed; inset:0; background:rgba(0,0,0,.5) -->
  <iframe src="/products/123"></iframe>   <!-- 고객사 PDP -->
</div>
```

{% endtab %}
{% endtabs %}

***

## **3. 진입 버튼 배치**

AI 검색으로 들어가는 버튼은 고객사가 앱에 직접 배치합니다. 아래 두 가지 배치를 권장하니 서비스에 맞는 쪽을 선택해 주세요. 이미지의 **◇ 적용 가이드**는 고객사가 앱에서 설정하는 부분입니다.

{% tabs %}
{% tab title="옵션 A · 별도 버튼" %}
검색창 아래에 별도의 AI 진입 버튼을 배치합니다.

<figure><img src="/files/eaGIKLZ27OiFs3BQXzez" alt=""><figcaption></figcaption></figure>

{% endtab %}

{% tab title="옵션 B · 검색창 우측 버튼" %}
검색창 우측에 컴팩트한 AI 버튼을 배치합니다.

<figure><img src="/files/VRCIkAwQ4a8lVuG4NLKS" alt=""><figcaption></figcaption></figure>

{% endtab %}
{% endtabs %}

***

## **자주 묻는 질문**

<details>

<summary><strong>Q. 네이티브 앱에서만 되나요? 웹앱에서도 되나요?</strong></summary>

웹을 렌더하는 환경(WebView 또는 iframe)이면 모두 됩니다. 신호 전달 방식만 환경에 맞게(UA 토큰 또는 URL 파라미터) 선택하면 됩니다.

</details>

<details>

<summary><strong>Q. 일반 웹 브라우저 접속에서도 헤더가 숨겨지나요?</strong></summary>

아니요. 협의한 임베드 신호가 있는 경우에만 숨겨집니다. 신호 없는 일반 접속에서는 헤더가 정상 노출됩니다.

</details>

<details>

<summary><strong>Q. 식별 값이 다른 서비스와 겹치지 않나요?</strong></summary>

토큰·파라미터 값은 고객사마다 젠서와 협의해 고유하게 정하므로 다른 서비스와 겹치지 않습니다.

</details>

<details>

<summary><strong>Q. 상품 상세가 오버레이로 뜨지 않고 전체 화면으로 떠요.</strong></summary>

오버레이는 앱이 상품 상세를 모달 시트(iOS) 또는 BottomSheet(Android)로 열 때 나타납니다. 전체 화면으로 열면 일반 화면 전환으로 표시됩니다.

</details>

<details>

<summary><strong>Q. iframe으로도 임베드할 수 있나요?</strong></summary>

가능합니다. 다만 iframe은 크로스도메인 쿠키·스토리지 제약(특히 iOS)이 있어 로그인 세션이 필요한 화면은 별도 검토가 필요합니다. UserAgent를 지정할 수 있는 WebView 방식이 더 안정적입니다.

</details>

***
