Customize the Genuin video player
Set the size, tile layout, profile menu, onboarding prompts, and deep-link behaviour 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 apply to every view of your brand on the platforms that read them.
This page covers Android SDK 2.1.5, iOS SDK 2.1.5, Web SDK 2.0.6, React Native 3.0.3, and Flutter 1.0.1. React Native 3.0.3 wraps the 2.1.5 native SDKs. Flutter 1.0.1 wraps the older native SDKs, Android 1.1.9.3 and iOS 1.1.9, so a few options behave differently there.
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 behaviour, 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 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 |
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 2.1.5 | iOS 2.1.5 | Web SDK 2.0.6 | React Native 3.0.3 | Flutter 1.0.1 |
|---|---|---|---|---|---|
| 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, carouselInset, 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 | — | — |
| Colour 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.
Sizing and 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 in 1.0.1 | The native 1.1.9 layout |
Tile aspect ratio and scroll direction aren't code options in the 2.x 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, Integrate the Genuin iOS SDK, Integrate the Genuin SDK with React Native apps, and Initialize the Genuin SDK and load a feed in Flutter.
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
ssoTokenyou 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,
setPlacementParamshas no profile parameter. On iOS,PlacementConfigurationhasisShowProfileEnabled. - Web: The Web SDK has no profile menu.
Signing out from this menu ends the Genuin session only; your app's session continues. To keep the two in step, see Sign members out and handle expired sessions.
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.
Deep-link behaviour
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 2.1.5, React Native on Android, Flutter |
| isDirectDeepLinkEnabled | boolean | false | The SDK opens the current video's share URL, which is on your white-labelled 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 |
Android 2.1.5 handles interactionDeepLink in four steps:
- If the value has no
http://orhttps://prefix, the SDK addshttps://. - 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. - If the member is signed in, it appends
token=<access token>. - It opens the URL with an
ACTION_VIEWintent. 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.
Caution: interactionDeepLink on Android and isDirectDeepLinkWithLoginEnabled everywhere put the member's Genuin access token in the URL as the token query parameter. The token stays valid for 14 days. 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.
Examples
Each example opens a full-screen feed with the profile menu on and interactions sent to your app.
Android
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
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
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
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:
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
});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. You turn each one on in Settings > Guided Onboarding Controls. The Mobile App tab applies to the Android and iOS SDKs, and the Web tab to the Web SDK.
| 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
HomeFeedrenders and the deprecatedGenuinSDK.loadSDKopens. 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.
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.registerInterfacewithGenuinInterface.onLogin(activity). - iOS:
GenuinSDK.shared.delegatewithpresentLoginViewController(baseViewController:). - React Native:
registerCallback(), which emitsNavigateToScreenwithLogin.
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.
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 white-labelled community site.
Flutter 1.0.1 has no sign-in callback, and its native 1.1.9 SDKs have no registerInterface or GenuinDelegate, so Genuin's own sign-in sheet always opens there.
Note: 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.
Earlier names
Options and views that were renamed or removed, and what to use now.
| Earlier name | Where | Current name | Notes |
|---|---|---|---|
| GenuinCarouselEmbedView | Flutter 1.0.0 | Carousel | Same parameters. Import genuin_carousel_embed_view.dart. |
| GenuinFeedEmbedView | Flutter 1.0.0 | Feed | Same parameters. StandardWall is new in 1.0.1. |
| GenuinFeedView | Flutter 1.0.0 | HomeFeed | Android only |
| CarouselEmbedView in com.begenuin.sdk.ui.customview.embed | Android 1.1.9 | GenuinEmbedView in com.begenuin.core.ui.customview.embed | setEmbedParams keeps the same parameter names; 2.x adds the tile layout setters |
| EmbedConfiguration.interactionDeepLink | iOS 1.x GenuinSDK pod | None | Removed in 2.x. Use isDirectDeepLinkEnabled. |
| GenuinCarouselConfiguration.carouselInset | iOS 1.x | viewInset on GenuinTileConfiguration | Same UIEdgeInsets value |
| aspectRatio, scrollDirection | iOS 1.x carousel configuration | None | Removed in 2.x; the embed's layout in Brand Control Center decides |
| isVerticalScrollDirection | React Native typings | None | Declared but has no effect in 3.0.3 |
| data-video-id | Web SDK 1.2 | data-start-video-slug | Still accepted in 2.0.6, marked deprecated |
| authInfo | Web SDK 1.2 | auth_info | Still accepted in 2.0.6, marked deprecated |
Troubleshooting
| 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-labelled domain | Set up App Links or universal links for the domain. See Handle Genuin deep links in your app. |
| interactionDeepLink is ignored on iOS | iOS 2.1.5 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. Flutter 1.0.1 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:
interactionDeepLinkexists on Android 2.1.5 and Flutter only. React Native forwards it on Android only. - React Native on iOS forwards fewer props:
interactionDeepLinkandisDirectDeepLinkWithLoginEnableddon't reach the native view. - Flutter runs the 1.1.9 natives: Flutter 1.0.1 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-labelled 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.

