# Customize the Genuin video player

Set the size, tile layout, profile menu, deep links, and onboarding prompts of Genuin carousels, standard walls, and full-screen feeds on every SDK.

Every Genuin view plays video in the same player. A carousel or grid plays it inline, and tapping a tile opens the full-screen view, where members react, comment, share, and follow link-outs. In the Android and iOS SDKs, a standard wall or a full-screen feed starts in that full-screen view.

You control the player in two places. Options you set in code apply to the one view you configure. Settings in Brand Control Center (BCC) apply to every view of your brand on the platforms that read them.

BCC settings are part of Control, the product that holds the rules every other product reads. For the whole product, see [Control: what it does and where to start](https://begenuin.com/developers/browse-by-products/control/control-what-it-does-and-where-to-start).

This page covers the Android, iOS, Web, React Native, and Flutter SDKs. The React Native SDK wraps the current Android and iOS SDKs. The Flutter SDK wraps an older generation of the native SDKs, so a few options behave differently there. Each SDK's install guide lists the version it's on.

## Where each setting lives

| What you change | Where | Applies to |
| --- | --- | --- |
| Feed source, layout (carousel, grid, standard wall, or feed), and expand view | The embed in Brand Control Center, under Grow > On Site > Embed | Every view that loads the embed ID |
| Aspect ratio, autoplay, start with sound, looping, resume point, tap behavior, in-feed reaction, playback speed, and caption sharing | Settings > Player Controls, with separate Mobile App and Web tabs | Every view of your brand on that surface. Brand Control Center notes that a change can take up to 15 minutes to reach views. |
| When link-outs appear, how their button looks, and where they open | Settings > Linkout Controls | Every view of your brand |
| Sign-in, interest, username, profile, and get-app popups, the idle-time popup, and gesture hints | Settings > Guided Onboarding Controls, with Mobile App and Web tabs | Standard walls. See [Turn on onboarding and sign-in prompts](https://begenuin.com/developers/browse-by-products/control/how-does-a-brand-customize-the-genuin-video-player-controls#turn-on-onboarding-and-sign-in-prompts). |
| View size, tile layout, profile menu, navigation bar, deep links, start video, and theme | Your code | The view you configure |

To create the embed itself, see [Generate an embed code in Brand Control Center](https://begenuin.com/developers/browse-by-products/onsite/how-do-brands-generate-embed-codes-from-brand-control-center). Learn more about the player toggles in [Player Controls and Feed Settings](https://begenuin.com/developers/browse-by-products/control/player-controls-and-feed-settings) and about link-out rules in [Manage and block video linkouts](https://begenuin.com/developers/browse-by-products/control/how-to-mentrally-manage-and-control-all-video-linkouts-in-brand-ecosystem).

The rest of this page documents the code options, plus the onboarding settings, because those change what the SDK shows inside your app.

## Options by platform

A dash means the platform has no such option.

| Option | Android | iOS | Web SDK | React Native | Flutter |
| --- | --- | --- | --- | --- | --- |
| View size | A parent with a fixed height | A container view with a fixed height | Container width and height | style | A bounded parent widget |
| Tile spacing, insets, and corner radius | setInterTileSpacing, setInsets, setTileCornerRadius | GenuinTileConfiguration | — | interTileSpacing, the carouselInset props, tileCornerRadius | — |
| Profile menu | isShowProfileEnabled | isShowProfileEnabled | — | isShowProfileEnabled | isShowProfileEnabled |
| Navigation bar | — | showNavigationBar | — | — | — |
| Send interactions to a URL | interactionDeepLink | — | — | interactionDeepLink, Android only | interactionDeepLink |
| Open the video in your app | isDirectDeepLinkEnabled | isDirectDeepLinkEnabled | — | isDirectDeepLinkEnabled | isDirectDeepLinkEnabled |
| Open the video in your app with the member's session | isDirectDeepLinkWithLoginEnabled | isDirectDeepLinkWithLoginEnabled | — | isDirectDeepLinkWithLoginEnabled, Android only | isDirectDeepLinkWithLoginEnabled |
| Start on a specific video | — | — | start_video_slug | — | — |
| Color theme | — | — | theme | — | — |
| Swipe between tiles | — | — | allow_gesture_scroll | — | — |
| Your own sign-in screen | GenuinSDK.registerInterface | GenuinSDK.shared.delegate | window.genuinAuth or auth_info | registerCallback | — |

On Android, you pass the per-view options to `GenuinEmbedView.setEmbedParams` or `FeedEmbedFragment.newInstance`. On iOS, they're properties of `EmbedConfiguration`, or `PlacementConfiguration` for placements. React Native takes them as component props and Flutter as widget parameters.

The Web SDK reads its options from `window.genuin.init` and from container data attributes, as listed in [Embed the Genuin Web SDK on your website](https://begenuin.com/developers/developer-resources/sdk/how-do-you-embed-and-configure-the-genuin-web-sdk-on-your-website). For the parameters every SDK accepts on an embed or a placement, see the [Embed configuration reference](https://begenuin.com/developers/get-started/any-business/embed-configuration-reference).

## Size the view and set the tile layout

Carousels and grids render inside a container you size. Standard walls and full-screen feeds fill their container, so give that container the whole screen.

| Platform | Size the view with | Tile layout options | Defaults |
| --- | --- | --- | --- |
| Android | A parent with a fixed height. A wrap_content parent renders nothing. | setInterTileSpacing(px), setInsets(left, top, right, bottom), and setTileCornerRadius(px) in pixels, or the XML attributes app:interTileSpacing, app:leftInset, app:topInset, app:rightInset, app:bottomInset, and app:tileCornerRadius in dp | Spacing 8 dp; insets left 16, top 8, right 16, bottom 0 dp; radius 8 dp |
| iOS | A container view with a height constraint | interTileSpacing, viewInset, and tileCornerRadius in points, on EmbedConfiguration.genuinCarouselConfiguration or PlacementConfiguration.tileConfiguration | Spacing 8; inset top 8, left 16, bottom 0, right 16; radius 8 |
| Web | A container with a non-zero width and height. The SDK then sets the height to fit the content. | None. The SDK renders in a Shadow DOM, so your CSS doesn't reach the tiles. | — |
| React Native | style with a height and a width | interTileSpacing, carouselInsetTop, carouselInsetLeft, carouselInsetBottom, carouselInsetRight, and tileCornerRadius on Carousel, in dp on Android and points on iOS | Spacing 8; insets top 8, left 16, bottom 0, right 16; radius 8 |
| Flutter | A bounded parent such as SizedBox or Expanded. An unbounded Column throws during layout. | None | The layout of the older native SDKs it wraps |

Tile aspect ratio and scroll direction aren't code options in the current native SDKs. They come from the embed's layout in Brand Control Center.

Full setup code for each platform is in [Integrate the Genuin Android SDK](https://begenuin.com/developers/developer-resources/sdk/how-to-integrate-and-power-your-brand-community-in-android-apps), [Integrate the Genuin iOS SDK](https://begenuin.com/developers/developer-resources/sdk/developer/genuin-sdk/native-compatibility/ios/how-to-integrate-and-power-your-brand-community-in-ios-apps), [Integrate the Genuin SDK with React Native apps](https://begenuin.com/developers/developer-resources/sdk/how-do-you-integrate-the-genuin-react-native-sdk-into-your-application), and [Initialize the Genuin SDK and load a feed in Flutter](https://begenuin.com/developers/developer-resources/sdk/flutter-sdk-developer-reference-how-do-i-initialize-the-genuin-sdk-and-load-a-feed).

## Show the profile menu

`isShowProfileEnabled` (boolean, default `false`) puts the signed-in member's profile picture in the top-right corner of the full-screen view. Tapping the picture opens a menu where the member views their profile, opens account settings, or signs out of Genuin.

- **Signed-in members only**: Guests never see the picture. It appears once the member signs in, for example through the `ssoToken` you pass to the view.
- **Full-screen view**: The option applies to the full-screen view your view opens, including the one a carousel tile opens.
- **Placements**: On Android, `setPlacementParams` has no profile parameter. On iOS, `PlacementConfiguration` has `isShowProfileEnabled`.
- **Web**: The Web SDK has no profile menu.

Signing out from this menu ends the Genuin session only, and your app's session continues. To keep the two in step, see [Sign members out and handle expired sessions](https://begenuin.com/developers/developer-resources/sdk/sign-members-out-and-handle-expired-sessions).

### Show the navigation bar (iOS)

`showNavigationBar` (`Bool`, default `false`) adds a navigation bar with a back button above a full-screen feed or standard wall. It applies to views created with `initializeEmbedFeed`, `initializeStandardWall`, or `getStandardWallController`. No other SDK has an equivalent.

## Send interactions to your app

By default, every interaction in the full-screen view stays inside the SDK. A reaction is recorded, the comments sheet opens, and a community tap opens the community screen. Three options send the member out of the SDK instead.

These interactions redirect: reactions, comments, shares, reposts, the more-options menu, and creating a post. So do joining a community or group, link-outs and their buttons, and taps on a profile, mention, community, or group. Playback controls such as pause, mute, scrubbing, and captions stay in the SDK.

| Parameter | Type | Default | What happens on a redirecting interaction | Platforms |
| --- | --- | --- | --- | --- |
| interactionDeepLink | string | empty | The SDK opens this URL outside the SDK. Empty keeps interactions in the SDK. | Android, React Native on Android, Flutter |
| isDirectDeepLinkEnabled | boolean | false | The SDK opens the current video's share URL, which is on your white-label domain. When your app claims that domain, the URL opens your app, which hands it to the SDK to play that video. Takes precedence over interactionDeepLink. | Android, iOS, React Native, Flutter |
| isDirectDeepLinkWithLoginEnabled | boolean | false | Same as isDirectDeepLinkEnabled, and appends token=<access token> to the URL when the member is signed in. Setting it to true also sets isDirectDeepLinkEnabled. | Android, iOS, React Native on Android, Flutter |

The white-label domain is the one your hosted social experience runs on. To set one up, see [White-label your hosted social experience](https://begenuin.com/developers/browse-by-products/onsite/how-can-you-white-label-your-community-under-your-own-domain).

The Android SDK handles `interactionDeepLink` in four steps:

1. If the value has no `http://` or `https://` prefix, the SDK adds `https://`.
2. It checks the result against a web-address pattern: a lowercase host, a top-level domain of 2 to 6 letters, and an optional path. A custom scheme such as `myapp://`, a port, or uppercase letters fail the check.
3. If the member is signed in, it appends `token=<access token>`.
4. It opens the URL with an `ACTION_VIEW` intent. If your app claims the domain with Android App Links, Android routes the URL to your app.

If the URL fails the check, the interaction has no effect. The SDK doesn't fall back to its own flow. For example, `myapp://join` fails the check, so tapping a reaction does nothing.

> **Caution** The Android interactionDeepLink option, and isDirectDeepLinkWithLoginEnabled on every SDK, put the member's Genuin access token in the URL as the token query parameter. The token stays valid for 14 days, so anyone who reads the URL holds a working token for that long. Point these URLs only at domains you control, and keep the parameter out of logs and analytics.

To receive these links in your app and pass them to the SDK, see [Handle Genuin deep links in your app](https://begenuin.com/developers/developer-resources/sdk/handle-genuin-deep-links-in-your-app).

## Examples

Each example opens a full-screen feed with the profile menu on and interactions sent to your app.

### Android

```kotlin title="FeedActivity.kt"
import com.begenuin.core.ui.fragment.FeedEmbedFragment

val fragment = FeedEmbedFragment.newInstance(
  embedId = "{{EMBED_ID}}",
  uniqueId = "{{UNIQUE_ID}}",
  ssoToken = "{{SSO_TOKEN}}",                  // signs the member in, so the profile picture can show
  isShowProfileEnabled = true,
  isDirectDeepLinkWithLoginEnabled = true      // also turns on isDirectDeepLinkEnabled
)
supportFragmentManager.beginTransaction()
  .add(R.id.frameLayout, fragment)
  .commit()
```

For a carousel, pass the same values to `GenuinEmbedView.setEmbedParams(embedId, uniqueId, interactionDeepLink, isDirectDeepLinkEnabled, isShowProfileEnabled, isDirectDeepLinkWithLoginEnabled)`.

### iOS

```swift title="FeedViewController.swift"
import GenuinCore

let configuration = EmbedConfiguration()
configuration.isShowProfileEnabled = true
configuration.showNavigationBar = true
configuration.isDirectDeepLinkWithLoginEnabled = true   // also sets isDirectDeepLinkEnabled

GenuinSDK.shared.initializeEmbedFeed(
    embedId: "{{EMBED_ID}}",
    containerView: view,
    viewConroller: self,          // the API spells the label this way
    ssoToken: "{{SSO_TOKEN}}",
    embedConfiguration: configuration
)
```

### React Native

```tsx title="FeedScreen.tsx"
import React from 'react';
import { Feed } from 'genuin-react-native';

export default function FeedScreen() {
  return (
    <Feed
      style={{ height: '100%', width: '100%' }}
      embedId="{{EMBED_ID}}"
      ssoToken="{{SSO_TOKEN}}"
      isShowProfileEnabled
      isDirectDeepLinkEnabled
    />
  );
}
```

### Flutter

```dart title="feed_screen.dart"
import 'package:flutter/material.dart';
import 'package:genuin_sdk/genuin_feed_embed_view.dart';

class FeedScreen extends StatelessWidget {
  const FeedScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Feed(
        embedId: '{{EMBED_ID}}',
        interactionDeepLink: 'https://www.example.com/join', // opened on any interaction
        isShowProfileEnabled: true,
      ),
    );
  }
}
```

### Web

The Web SDK has no profile or redirect options. Its player options are the theme, gesture scrolling, and the video to open on load.

```js title="Web SDK player options"
window.genuin.init({
  embed_id: "{{EMBED_ID}}",
  api_key: "<<YOUR_API_KEY>>",
  theme: "dark",                      // "light" by default
  allow_gesture_scroll: false,        // turns off swipe and drag between tiles
  start_video_slug: "{{VIDEO_SLUG}}", // opens this video in the expand view on load
});
```

## Turn on onboarding and sign-in prompts

Brand Control Center calls these guided onboarding controls. They're popups the SDK shows while a member swipes through videos, asking them to sign in, pick interests, choose a username, or complete their profile. No SDK parameter controls them.

1. In Brand Control Center, go to **Settings** > **Guided Onboarding Controls**.
2. Select the **Mobile App** tab for the Android and iOS SDKs, or the **Web** tab for the Web SDK.
3. Select each toggle you want, and choose when its popup appears.

| Toggle | Shown to | Appears after | Mobile App | Web |
| --- | --- | --- | --- | --- |
| Enable Login/signup | Guests | 1 to 5 swipes; 5 when first turned on | Yes | Not shown automatically |
| Enable Interest selection popup | Signed-in members who haven't picked interests | 1 to 5 swipes | Yes | Yes |
| Enable username popup | Signed-in members who still have a generated username | 1 to 5 swipes | Yes | Yes |
| Enable complete profile popup | Signed-in members whose profile has no name or no bio | 1 to 5 swipes | Yes | No |
| Enable Get App | Web visitors | 1 to 5 swipes | No | Only when the web call to action under Settings > Brand Elements is set to get the app |
| Idle Time Interruption | The member the next popup applies to | 60 to 300 seconds without interaction | Yes | Yes |
| Gestures | Everyone | Once per gesture, in the full-screen view | Yes | Yes |

The SDK shows the first popup that applies, in the order of the table, once the member reaches the swipe count. A member who has finished a step doesn't see its popup again. **Gestures** shows one-time hints for the swipe and tap gestures in the full-screen view.

The popups appear only in standard walls:

- **Android and iOS**: In a standard wall whose feed source is Brand Feed. On Android, they also appear in the home feed that React Native's `HomeFeed` renders and the deprecated `GenuinSDK.loadSDK` opens. Carousels, grids, full-screen feed embeds, and community or group standard walls don't show them.
- **Web**: In standard wall embeds. Carousel, grid, feed, and expand-only embeds don't show them.

Onboarding doesn't include a notification permission prompt. Your app asks for notification permission and registers the device token, as described in [Set up push notifications in the Genuin SDK](https://begenuin.com/developers/developer-resources/sdk/developer/genuin-sdk/creation-and-editing-tools/notification/push/how-do-push-notifications-work-with-the-genuin-sdk).

### Hand the sign-in popup to your app

On Android and iOS, the sign-in popup uses the same path as a guest tapping an action that needs an account. If you registered a sign-in callback, the SDK calls it instead of opening Genuin's sign-in sheet:

- **Android**: `GenuinSDK.registerInterface` with `GenuinInterface.onLogin(activity)`.
- **iOS**: `GenuinSDK.shared.delegate` with `presentLoginViewController(baseViewController:)`.
- **React Native**: `registerCallback()`, which emits `NavigateToScreen` with `Login`.

Run your sign-in flow in the callback, then pass the token to `ssoLogin`. The setup is in [Choose how members sign in to the Genuin SDK](https://begenuin.com/developers/developer-resources/guides/user-authentication-mechanisms-in-genuin-sdk).

On the web, the sign-in popup never opens on its own in a standard wall. Sign-in starts when a visitor taps an action, and the embed sends them to `window.genuinAuth`, your `auth_info.signInUrl`, or your hosted social experience on your white-label domain.

The Flutter SDK has no sign-in callback, and the older native SDKs it wraps have no `registerInterface` or `GenuinDelegate`. Genuin's own sign-in sheet always opens there.

## Renamed and removed options

Options and views that were renamed or removed, and what to use now.

| Earlier name | Where | Current name | Notes |
| --- | --- | --- | --- |
| GenuinCarouselEmbedView | Earlier Flutter SDK | Carousel | Same parameters. Import genuin_carousel_embed_view.dart. |
| GenuinFeedEmbedView | Earlier Flutter SDK | Feed | Same parameters. StandardWall was added in the same release. |
| GenuinFeedView | Earlier Flutter SDK | HomeFeed | Android only |
| CarouselEmbedView in com.begenuin.sdk.ui.customview.embed | Earlier Android SDK | GenuinEmbedView in com.begenuin.core.ui.customview.embed | setEmbedParams keeps the same parameter names; the current SDK adds the tile layout setters |
| EmbedConfiguration.interactionDeepLink | Earlier iOS SDK (GenuinSDK pod) | None | Removed in the current iOS SDK. Use isDirectDeepLinkEnabled. |
| GenuinCarouselConfiguration.carouselInset | Earlier iOS SDK | viewInset on GenuinTileConfiguration | Same UIEdgeInsets value |
| aspectRatio, scrollDirection | Earlier iOS SDK carousel configuration | None | Removed in the current iOS SDK; the embed's layout in Brand Control Center decides |
| isVerticalScrollDirection | React Native typings | None | Declared but has no effect |
| data-video-id | Earlier Web SDK | data-start-video-slug | Still accepted, marked deprecated |
| authInfo | Earlier Web SDK | auth_info | Still accepted, marked deprecated |

## Troubleshoot player options

| Symptom | Cause | Fix |
| --- | --- | --- |
| The profile picture doesn't appear | The member isn't signed in, the view is an Android placement, or it's a Web SDK embed | Sign the member in with an SSO token. Android placements and the Web SDK have no profile menu. |
| Tapping a reaction or comment has no effect on Android | interactionDeepLink fails the URL check, for example a custom scheme or an uppercase host | Use a lowercase https:// web address on a domain your app claims. |
| A direct deep link opens the browser instead of your app | Your app doesn't claim the white-label domain | Set up App Links or universal links for the domain. See [Handle Genuin deep links in your app](https://begenuin.com/developers/developer-resources/sdk/handle-genuin-deep-links-in-your-app). |
| interactionDeepLink is ignored on iOS | The iOS SDK and React Native on iOS don't have the option | Use isDirectDeepLinkEnabled. |
| No onboarding popup appears | The embed isn't a standard wall with a Brand Feed source, the toggle is off, or the member already finished that step | Check the embed's style and source, and the toggles under Settings > Guided Onboarding Controls. |
| Genuin's sign-in sheet opens instead of your login | No sign-in callback is registered, or the app uses Flutter | Register the callback for your platform. The Flutter SDK has none. |
| A carousel renders nothing | The container has no fixed height | Give the container a height. |

## Limitations

- **Two option sets**: Android, iOS, React Native, and Flutter share one set of per-view options. The Web SDK has its own and supports neither the profile menu nor the redirect options.
- **iOS has no interaction URL**: `interactionDeepLink` exists on Android and Flutter only. React Native forwards it on Android only.
- **React Native on iOS forwards fewer props**: `interactionDeepLink` and `isDirectDeepLinkWithLoginEnabled` don't reach the native view.
- **Flutter runs older native SDKs**: The Flutter SDK has no tile layout options and no sign-in callback.
- **Onboarding popups are standard-wall only**: They never appear in carousels, grids, or full-screen feed embeds.
- **Direct deep links need a white-label domain**: The share URL opens your app only when your app claims that domain.
- **Player Controls aren't instant**: A change under **Settings** > **Player Controls** can take up to 15 minutes to reach views.

## See also

- [Player Controls and Feed Settings](https://begenuin.com/developers/browse-by-products/control/player-controls-and-feed-settings)
- [Manage and block video linkouts](https://begenuin.com/developers/browse-by-products/control/how-to-mentrally-manage-and-control-all-video-linkouts-in-brand-ecosystem)
- [Handle Genuin deep links in your app](https://begenuin.com/developers/developer-resources/sdk/handle-genuin-deep-links-in-your-app)
- [Choose how members sign in to the Genuin SDK](https://begenuin.com/developers/developer-resources/guides/user-authentication-mechanisms-in-genuin-sdk)
- [Embed configuration reference](https://begenuin.com/developers/get-started/any-business/embed-configuration-reference)
