> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nudj.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# Embedding Modes

> Four ways Nudj renders inside your surface: Shopify storefront widgets, the universal embed widget, iframe, and mobile webview.

Nudj ships four distinct embedding modes. Pick one based on where your users are and what authentication you already have.

<CardGroup cols={2}>
  <Card title="Shopify storefront widgets" icon="shopify" href="/enterprise/shopify/storefront-widgets">
    Theme app extension blocks a merchant drops into their storefront. First-class path if your storefront is Shopify.
  </Card>

  <Card title="Universal embed widget" icon="code" href="/enterprise/universal-embed-widget">
    Cross-platform embed script + admin customisation panel (PR #1971). Works on any CMS or hand-rolled site.
  </Card>

  <Card title="Iframe embed" icon="browser">
    Host the Nudj user app in an `<iframe>` on your own domain. Requires CSP frame-ancestors entries (see below).
  </Card>

  <Card title="Mobile webview (in-app browser)" icon="mobile">
    Wrap Nudj in a native iOS/Android webview component. Use with API Link authentication.
  </Card>
</CardGroup>

## 1. Shopify storefront widgets

If you run Shopify, the default path is a **theme app extension**: small Liquid blocks the merchant places directly into their storefront via the theme editor. Each block renders an isolated, themed widget backed by the Nudj user app.

See the dedicated [storefront widgets page](/enterprise/shopify/storefront-widgets) for the full widget catalog and theme editor configuration.

## 2. Universal website embed widget

PR #1971 introduced the universal embed: a small script tag your site includes that injects a configurable widget anywhere a placeholder `<div>` exists.

* **Admin customisation panel**: configure the widget layout, theme, and auth mode without writing code.
* **Works anywhere**: Shopify (non-theme-extension surfaces), custom sites, CMS-hosted pages.
* **CSP**: PR #2333 opened the Nudj user app's `frame-ancestors` directive so this widget can embed on arbitrary third-party domains.

See the [Universal Embed Widget](/enterprise/universal-embed-widget) page for the embed script and setup.

## 3. Iframe embed

Host the Nudj user app directly in an `<iframe>` on your domain.

```html theme={null}
<iframe
  src="https://your-org.nudj.cx"
  width="100%"
  height="640"
  frameborder="0"
  allow="camera; microphone; fullscreen">
</iframe>
```

### CSP requirements

The Nudj user app sets a `Content-Security-Policy` with a `frame-ancestors` directive. For the iframe to render on your domain you must either:

* Be embedded from a Shopify storefront domain — PR #1638 added Shopify hosts to the allowlist.
* Use the universal embed allowance — PR #2333 opened `frame-ancestors` for universal embedding.
* Ask your account manager to add your host to the organisation's allowlist.

Authenticate the iframe user via [OIDC SSO](/enterprise/sso-authentication) or [API Link](/enterprise/api-link-user-authentication) — cross-origin iframe cookies are subject to the user's browser settings.

## 4. Mobile webview

Wrap Nudj in a native webview when your surface is a mobile app. The only supported authentication mode here is [API Link](/enterprise/api-link-user-authentication) — your native app issues a Nudj token server-side and passes it into the webview.

<Tabs>
  <Tab title="iOS (Swift / WKWebView)">
    ```swift theme={null}
    import UIKit
    import WebKit

    class NudjViewController: UIViewController {
      var webView: WKWebView!

      override func loadView() {
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: config)
        view = webView
      }

      override func viewDidLoad() {
        super.viewDidLoad()
        let token = fetchNudjApiLinkToken() // server-issued
        let url = URL(string: "https://your-org.nudj.cx/api/link?token=\(token)")!
        webView.load(URLRequest(url: url))
      }
    }
    ```
  </Tab>

  <Tab title="Android (Kotlin / WebView)">
    ```kotlin theme={null}
    import android.webkit.WebView
    import androidx.appcompat.app.AppCompatActivity

    class NudjActivity : AppCompatActivity() {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val webView = WebView(this)
        webView.settings.javaScriptEnabled = true
        val token = fetchNudjApiLinkToken() // server-issued
        webView.loadUrl("https://your-org.nudj.cx/api/link?token=$token")
        setContentView(webView)
      }
    }
    ```
  </Tab>
</Tabs>

## Picking a mode

| Your surface                                  | Recommended mode           |
| --------------------------------------------- | -------------------------- |
| Shopify storefront                            | Shopify storefront widgets |
| Non-Shopify ecommerce / CMS                   | Universal embed widget     |
| Custom web portal, user already authenticated | Iframe + API Link          |
| Custom web portal, user logging in fresh      | Iframe + OIDC SSO          |
| Native iOS / Android app                      | Mobile webview + API Link  |

## Next steps

<CardGroup cols={2}>
  <Card title="Universal embed widget" icon="code" href="/enterprise/universal-embed-widget">
    Setup script and admin panel for the cross-platform embed.
  </Card>

  <Card title="Shopify storefront widgets" icon="shopify" href="/enterprise/shopify/storefront-widgets">
    Widget catalog for theme app extensions.
  </Card>
</CardGroup>

> Last reviewed: 2026-04 · Related PRs: #1971, #2333, #1638
