Docs

Appearance and languages

The chat should feel like a screen you built yourself. This page shows how to set its colours, font and wording in code, how languages work, and how to show an unread badge.

Style it in code

Set Hollo.theme once, right after Hollo.start(appKey:):

Hollo.theme = HolloTheme(
    accent: .black,
    background: Color(.systemBackground),
    font: .custom("Inter", size: 16),
    title: "Help",
    welcome: "Ask us anything. We usually reply within minutes."
)

Every setting is optional. Anything you leave out uses Hollo's default, which follows the system look.

SettingWhat it changes
accentButtons, links, the send button and the user's own message bubbles.
backgroundThe chat's background.
userBubbleThe user's message bubbles, if you want something other than accent.
teamBubbleBubbles for replies from your team and the AI.
fontThe text in messages and the composer. Use a font your app already bundles.
titleThe title at the top of the chat, for example "Help" or "Support".
welcomeThe text on the welcome screen before the first message.
welcomeIconThe image on the welcome screen. Defaults to your app icon.
colorScheme.light or .dark to force one look. Leave it out to follow the system.
closeButtonHow the close button looks when the chat is shown with Hollo.present().

Light and dark mode

The chat follows light and dark mode automatically. If you pass colours, use ones that adapt, like Color(.systemBackground) or a colour from your asset catalogue with light and dark variants. A fixed colour like .white stays white in dark mode.

Hollo.theme = HolloTheme(
    accent: Color("BrandAccent"),       // asset catalogue colour with dark variant
    background: Color(.systemGroupedBackground)
)

UIKit

HolloTheme takes SwiftUI colours and fonts. From UIKit, wrap your existing values:

Hollo.theme = HolloTheme(
    accent: Color(uiColor: .brandAccent),
    font: Font(UIFont.preferredFont(forTextStyle: .body))
)

Tips

  • Match your app, not ours. Start with your accent colour and font, and see how far that gets you. Usually it's most of the way.
  • Keep text readable. Check that message text on your bubble colours is easy to read in both light and dark mode.
  • Respect Dynamic Type. If you set a custom font, use one that scales, for example with Font.custom(_:size:relativeTo:).

Change it from the dashboard

Languages

The chat's own buttons and labels (the composer placeholder, "Sending…", "Retry" and so on) appear in the user's language. Hollo uses the device language by default. To override it, for example if your app has its own language setting:

Hollo.language = "fr"

Use a language code like "fr", "de" or "pt-BR". Set it back to nil to follow the device again.

  • English and a handful of major languages are available first. More are added during early access.
  • Arabic, Hebrew and Urdu use a right-to-left layout.
  • Hollo AI replies in the user's language, whichever language they write in.
  • Your own title and welcome text are shown as you wrote them. If your app is translated, pass the localised strings, for example with String(localized:).
Hollo.theme = HolloTheme(
    title: String(localized: "Help"),
    welcome: String(localized: "Ask us anything. We usually reply within minutes.")
)

Unread badge

Hollo.unreadCount tells you how many replies the user hasn't seen. It updates live, including when a reply arrives while the app is open.

SwiftUI

SwiftUI redraws any view that reads Hollo.unreadCount when it changes:

struct SettingsView: View {
    var body: some View {
        List {
            Button("Support") { Hollo.present() }
                .badge(Hollo.unreadCount)
        }
    }
}

On a tab:

TabView {
    HomeView()
        .tabItem { Label("Home", systemImage: "house") }
    HolloChat()
        .tabItem { Label("Support", systemImage: "bubble.left") }
        .badge(Hollo.unreadCount)
}

UIKit

Use the Observation framework's withObservationTracking to update a badge when the count changes:

import Observation

final class SettingsViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        observeUnread()
    }

    private func observeUnread() {
        withObservationTracking {
            let count = Hollo.unreadCount
            tabBarItem.badgeValue = count > 0 ? "\(count)" : nil
        } onChange: { [weak self] in
            Task { @MainActor in self?.observeUnread() }
        }
    }
}

App icon badge

To show the count on your app icon, set it yourself whenever it changes:

try? await UNUserNotificationCenter.current().setBadgeCount(Hollo.unreadCount)

The count drops to zero when the user opens the chat and sees your reply.

Good to know

  • Set Hollo.theme before the chat opens. Changes made while the chat is on screen apply the next time it opens.
  • The chat uses system controls where it can, so VoiceOver, Dynamic Type and Reduce Motion work without extra setup.
  • Messages can be up to about 4,000 characters. Links in messages are tappable, and a long press copies a message.