Customization Guide
White-label the VIH Messenger SDK
Reshape the SDK's UI to match your app โ split the chat into category tabs, inject your brand colors, and rename or re-icon the tabs โ all from a single VihConfig you pass at launch. No custom build, no fork.
Available on Android and iOS. Android requires 1.1.3+ โ use com.github.ViH-Metaverse.ViH_SDK:vih-sdk:1.2.1 (the prod artifact, compiled against https://api.platform.vihresearchlabs.ai/); iOS: the same Swift Package (https://github.com/ViH-Metaverse/ViH_SDK.git) at tag 1.2.1. The examples below are Kotlin โ see the iOS section for the Swift equivalents. Assumes you've completed the base integration guide.
Moving Discover into your own app? To render the enterprise list in your host UI and deep-link straight into the SDK chat, see the Custom Discover Integration guide.
โจ What you can customize
| Capability | What it does |
|---|---|
| Split tabs | Replace the single "Chats" tab with category tabs โ Promotions, Transactions, OTP โ each showing only that kind of message. |
| Compose tabs | Pick exactly which tabs appear (Discover, Chats/categories, Settings) and their order. Omit a tab to hide it. |
| Brand colors | Pass your app's hex codes; the SDK's nav, buttons, and headers adopt them. |
| Names & icons | Rename any tab and swap its icon for one of your drawables. |
Everything lives on one optional object, VihConfig, passed to a new startSdk overload. Anything you don't set falls back to the channel's server settings, then the SDK default โ so your config always wins, and a partial config is fine.
๐งฉ The VihConfig object
Build a VihConfig and hand it to startSdk alongside the phone + hashcode. The existing positional startSdk(context, phone, hashcode, โฆ) still works unchanged โ the config overload is purely additive.
import com.vihmessenger.vihchatbot.config.*
import com.vihmessenger.vihchatbot.utils.FloatingButtonView
val config = VihConfig(
theme = VihTheme(
primary = "#0B5FFF", // brand color โ nav, buttons, headers
onPrimary = "#FFFFFF" // text/icons on the brand color
),
navigation = VihNavigation(
tabs = listOf(
VihTab(VihTabId.DISCOVER),
VihTab(VihTabId.PROMO, label = "Offers"),
VihTab(VihTabId.OTP, label = "Codes"),
VihTab(VihTabId.SETTINGS)
),
defaultTab = VihTabId.PROMO
)
)
FloatingButtonView.startSdk(
context = this,
phone = "919876543210",
hashcode = "your-channel-hashcode",
config = config
)
The full shape:
VihConfig(
theme: VihTheme? = null,
navigation: VihNavigation? = null
)
VihTheme(
primary: String? = null, // "#RRGGBB"
onPrimary: String? = null,
secondary: String? = null,
accent: String? = null
)
VihNavigation(
tabs: List<VihTab>, // exactly the tabs shown, in order
defaultTab: VihTabId? = null // selected on open
)
VihTab(
id: VihTabId, // DISCOVER, CHATS, PROMO, TRANSACTIONAL, OTP, SETTINGS
label: String? = null, // rename the tab
icon: Int? = null // R.drawable.your_icon
)
๐๏ธ Split the chat into tabs
The default "Chats" tab shows every conversation. To split it, list the tabs you want instead of CHATS. The chat surface is a list of conversations (one row per business you chat with); each tab decides which conversations appear:
| Tab id | Shows | Filter |
|---|---|---|
CHATS | All active conversations | none |
PROMO | All active conversations (your chats) | none โ see note |
OTP | Conversations whose latest message is an OTP | latest template_type == 1 |
TRANSACTIONAL | Conversations whose latest message is transactional | latest template_type == 3 |
navigation = VihNavigation(
tabs = listOf(
VihTab(VihTabId.DISCOVER),
VihTab(VihTabId.PROMO, label = "Offers"), // shows your active chats
VihTab(VihTabId.OTP), // OTP messages only
VihTab(VihTabId.SETTINGS)
),
defaultTab = VihTabId.DISCOVER
)
Why Promo shows all chats. The chat surface is a list of conversations, but a "promotional" flag lives on individual messages, not whole conversations โ the chat-list API doesn't expose a conversation-level promo category. So the PROMO/Offers tab shows all your active chats (rather than filtering to empty). OTP and TRANSACTIONAL do filter, by each conversation's latest message type โ so they populate as OTP/transactional messages arrive. A true per-category message split would need the backend to tag conversations.
Use either the unified CHATS tab or a subset of the category tabs. The bottom bar supports up to 5 tabs; extra tabs are dropped.
๐จ Brand colors
Pass your app's hex codes in VihTheme. primary drives the bottom-nav selection, buttons, and header accents; onPrimary is the text/icon color that sits on the brand color. Your colors override the channel's server-configured colors.
theme = VihTheme(
primary = "#0B5FFF",
onPrimary = "#FFFFFF",
secondary = "#00C2A8" // optional secondary accent
)
This first release themes the highest-impact chrome (bottom nav, buttons, headers). A few deep surfaces are still being migrated to full tokens โ set primary + onPrimary for the biggest visual win. Dark mode is respected automatically. Malformed hex is ignored (the SDK keeps the previous color, never crashes).
๐ท๏ธ Tab names & icons
Set label to rename a tab and icon to a drawable resource in your app (or the SDK). Omit either to keep the SDK's default.
tabs = listOf(
VihTab(VihTabId.DISCOVER, label = "Explore", icon = R.drawable.ic_explore),
VihTab(VihTabId.CHATS, label = "Messages", icon = R.drawable.ic_messages),
VihTab(VihTabId.SETTINGS, label = "Account", icon = R.drawable.ic_account)
)
Icons should be a bottom-nav-sized vector/PNG drawable (โ24โ32dp). If a drawable can't be resolved, the SDK falls back to its default icon for that tab.
๐ Recipes
Split chat: Discover ยท Promo ยท OTP ยท Settings
VihConfig(
navigation = VihNavigation(
tabs = listOf(
VihTab(VihTabId.DISCOVER),
VihTab(VihTabId.PROMO),
VihTab(VihTabId.OTP),
VihTab(VihTabId.SETTINGS)
),
defaultTab = VihTabId.DISCOVER
)
)
Brand colors + renamed, re-iconed tabs
VihConfig(
theme = VihTheme(primary = "#0B5FFF", onPrimary = "#FFFFFF"),
navigation = VihNavigation(
tabs = listOf(
VihTab(VihTabId.DISCOVER, label = "Explore", icon = R.drawable.ic_explore),
VihTab(VihTabId.CHATS, label = "Messages", icon = R.drawable.ic_messages),
VihTab(VihTabId.SETTINGS, label = "Account", icon = R.drawable.ic_account)
)
)
)
Everything: split + brand + renames
VihConfig(
theme = VihTheme(primary = "#0B5FFF", onPrimary = "#FFFFFF"),
navigation = VihNavigation(
tabs = listOf(
VihTab(VihTabId.DISCOVER, label = "Explore"),
VihTab(VihTabId.PROMO, label = "Offers"),
VihTab(VihTabId.OTP, label = "Codes"),
VihTab(VihTabId.SETTINGS, label = "Account")
),
defaultTab = VihTabId.PROMO
)
)
iOS Swift
The same customization is available on iOS via VihUIConfig โ identical concepts, Swift syntax. Pass it at launch through configure(_:ui:), or apply it later with setUIConfig(_:).
import VihChatBotSDK
let ui = VihUIConfig(
theme: VihTheme(primary: "#0B5FFF", onPrimary: "#FFFFFF"),
navigation: VihNavigation(
tabs: [
VihTab(.discover),
VihTab(.promo, label: "Offers"),
VihTab(.otp),
VihTab(.settings, label: "Account",
icon: UIImage(systemName: "person.circle"))
],
defaultTab: .discover
)
)
VihChatBotSDK.shared.configure(config, ui: ui) // config = your VihSDKConfig
// or apply/replace later: VihChatBotSDK.shared.setUIConfig(ui)
The types mirror Android one-to-one:
VihUIConfig(theme: VihTheme?, navigation: VihNavigation?)
VihTheme(primary: String?, onPrimary: String?, secondary: String?, accent: String?)
VihNavigation(tabs: [VihTab], defaultTab: VihTabId?)
VihTab(_ id: VihTabId, label: String? = nil, icon: UIImage? = nil)
enum VihTabId { case discover, chats, promo, transactional, otp, settings }
Behavior matches Android exactly: tabs render from navigation.tabs (omit a tab to hide it); otp / transactional filter by message type while promo / chats show all active chats; brand colors override the server palette (host wins). Icons are any UIImage (SF Symbols work well). Custom tabs cap at 5.
โ๏ธ How it behaves
- Precedence: your
VihConfig> the channel's server settings > the SDK default. Set only what you want to change. - Non-breaking: omit
configand the SDK behaves exactly as before (Discover ยท Chats ยท Settings, server colors). - Fail-safe: unknown tab ids, missing icons, or bad hex are logged and fall back to defaults โ never a crash.
- Dark mode: honored automatically; your brand colors are preserved, body surfaces adapt.
๐ฎ Support
Questions on customization, a tab surface you need that isn't listed, or iOS timing? Reach the VIH team with your channel hashcode, SDK version, and the VihConfig you're using.