Skip to content
reception

Search documentation

Loading documentation…

    Log in
    Browse documentation

    Customization

    Appearance

    Customize the native Support chat with your app’s colors, typography, welcome text, and dismissal controls. All 14 Reception.Appearance options accept matching values from your Swift variables, including your existing app theme.

    View Markdown

    Use your app’s theme and variables

    You can assign values from your own constants, variables, or theme objects to Reception.shared.appearance. Use a SwiftUI Color for a color property, a String for text or a registered font name, and the matching type for other options, such as Bool or Font.Design. The individual options below list their types and defaults.

    For example, place this function in your app’s appearance setup code. Here, AppTheme represents your own app’s theme type, with accentColor, onAccentColor, and backgroundColor properties of type Color, and a fontDesign property of type Font.Design?. Replace these names with your existing theme’s names.

    Swift
    import SwiftUI
    import ReceptionKit
    
    @MainActor
    func applySupportTheme(_ theme: AppTheme) {
        Reception.shared.appearance.accentColor = theme.accentColor
        Reception.shared.appearance.onAccentColor = theme.onAccentColor
        Reception.shared.appearance.chatBackground = theme.backgroundColor
        Reception.shared.appearance.fontDesign = theme.fontDesign
    }

    Call applySupportTheme(yourCurrentTheme) on the main actor after configuring Reception and whenever your app selects or changes a theme. Each assignment takes the current value; it does not bind ReceptionKit to the original variable or observe your theme object. Reassigning local appearance values updates the chat, including while it is open, unless a published remote override takes precedence.

    Adaptive asset colors such as Color("SupportAccent") keep their light/dark variants and respond automatically to the chat’s color scheme. A light/dark switch alone does not require reassigning those colors. If your theme changes which color, font, or custom string to use, assign the new value again. Your app also owns localizing custom text.

    To keep these values controlled by your app, leave the corresponding dashboard overrides unset, or set Reception.shared.usesRemoteAppearance = false on the main actor to use only local settings. Swift variable names belong in your app’s code; the dashboard accepts explicit values. See Precedence.

    Defaults

    Without customization, Reception uses your app’s accent color, white text on accent surfaces, system backgrounds, and the system font. It follows your app’s light or dark appearance. The chat title and welcome text use built-in translations. Sheets show a native drag indicator; the optional close button starts hidden.

    These settings apply to Reception’s chat, not your app’s support entry button, unread badge, or dashboard interface. The public appearance API does not expose arbitrary layouts, bubble shapes, spacing, or avatars. Your app owns its entry point and surrounding navigation; see Entry point.

    Default light appearance with native iOS 26 Liquid Glass controls. Example messages.

    Default light appearance with native iOS 26 Liquid Glass controls. Example messages.

    Default dark appearance with native iOS 26 Liquid Glass controls. Example messages.

    Default dark appearance with native iOS 26 Liquid Glass controls. Example messages.

    Native controls

    On iOS 26 and later, the chat title, optional close button, photo button, and message field use native Liquid Glass. Earlier iOS versions use system materials. Message bubbles keep their own background colors. There is no separate appearance option to enable glass; its rendering adapts to the system and presentation.

    Header detail: title and optional close control on iOS 26.

    Header detail: title and optional close control on iOS 26.

    Composer detail: native glass controls beneath a regular message bubble.

    Composer detail: native glass controls beneath a regular message bubble.

    Set appearance in code

    Reception.shared.appearance is a read/write Reception.Appearance value. Read and change it on the main actor, normally during app setup before presenting chat. Reception.Appearance() constructs a fresh set of local defaults.

    Place this function in your app’s setup code and call it from a main-actor context. Add a SupportAccent color asset with light and dark variants first.

    Example: use your app’s accent

    Swift
    import SwiftUI
    import ReceptionKit
    
    @MainActor
    func configureSupportAppearance() {
        Reception.shared.appearance.accentColor = Color("SupportAccent")
    }

    All short assignment examples below belong inside this main-actor setup function. Named color assets are examples of resources supplied by your app. Every option is configurable in Swift; all except fontFamily are also available in the dashboard.

    OptionLocal default
    accentColor.accentColor
    onAccentColornil → white
    chatBackgroundnil → system background
    incomingBackgroundnil → secondary system background
    incomingForegroundnil → primary label color
    preferredColorSchemenil → follows app
    titleLocalized “Support”
    welcomeTitleLocalized “Questions, feedback, or a bug?”
    welcomeTextLocalized “You're chatting directly with our team.”
    fontDesignnil → default system design
    fontFamilynil → system font
    showsCloseButtonfalse
    closeIcon.xmark
    fadesOlderMessagestrue

    Precedence

    For each option, a valid value in the active published remote appearance overrides your local value. Your local value otherwise applies, using the SDK default when you have left it unset. Reception.shared.usesRemoteAppearance defaults to true.

    • Remote colors inherit locally for each missing or invalid light/dark variant independently.

    • Remote text applies only when a valid translation matches the selected app language or the SDK’s supported language match; otherwise the local text applies.

    • Explicit remote defaults are overrides: “Follow app” clears a local forced color scheme, false can hide a locally enabled close button, and the default font design can replace a local rounded design.

    • A non-nil local fontFamily takes precedence over both local and remote fontDesign.

    Reading Reception.shared.appearance returns your local settings, not the merged appearance displayed by the chat. Remote appearance never rewrites that value.

    To use only local settings, put this assignment in your main-actor setup function:

    Swift
    Reception.shared.usesRemoteAppearance = false

    This ignores remote settings without deleting their cache. Newly fetched remote settings take effect on the next chat opening, rather than changing the currently open chat. See Remote appearance for publishing and offline behavior.

    The comparisons below show focused details from the native chat on iOS 26, using example messages.

    Colors and color scheme

    All five local color properties accept SwiftUI Color values from your variables, theme objects, or adaptive color assets. See Use your app’s theme and variables for an example and how to handle theme changes. The dashboard supports separate six-digit hex colors for light and dark mode. Test both modes with real messages; light accents may need a dark onAccentColor to keep text readable.

    accentColor

    Signature: public var accentColor: Color. Default: .accentColor, using your app’s accent. Accepts any SwiftUI Color, including a theme variable.

    Colors outgoing text bubble fills, the enabled send button, the review action, and accented controls such as Retry. Older outgoing fills may be lightened by fadesOlderMessages.

    Blue accent

    Blue accent

    Purple accent

    Purple accent

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.accentColor = Color("SupportAccent")

    When you change the accent, check that onAccentColor stays readable on it in light and dark mode, and set it too if not.

    The dashboard calls this Accent & outgoing bubbles. Assign .accentColor to restore the local default.

    onAccentColor

    Signature: public var onAccentColor: Color?. Default: nil, which uses white. Accepts any SwiftUI Color, including a theme variable, or nil.

    Colors text and symbols on accent surfaces: outgoing message text, the enabled send arrow, and review and paywall button labels and symbols. It does not automatically choose a contrasting color for your accent.

    White text

    White text

    Black text

    Black text

    In your main-actor setup function, after adding the named asset:

    Swift
    Reception.shared.appearance.onAccentColor = Color("SupportOnAccent")

    The dashboard calls this Text on accent. Assign nil to restore white locally.

    chatBackground

    Signature: public var chatBackground: Color?. Default: nil, which uses Color(uiColor: .systemBackground). Accepts any SwiftUI Color, including a theme variable, or nil.

    Sets the chat’s background surface. It does not recolor photos or the full-screen photo viewer’s black background.

    White background

    White background

    Blue background

    Blue background

    In your main-actor setup function, after adding the named asset:

    Swift
    Reception.shared.appearance.chatBackground = Color("SupportBackground")

    The dashboard calls this Chat background. Assign nil to restore the adaptive system background locally.

    incomingBackground

    Signature: public var incomingBackground: Color?. Default: nil, which uses Color(uiColor: .secondarySystemBackground). Accepts any SwiftUI Color, including a theme variable, or nil.

    Sets incoming text bubble, review card, and paywall card backgrounds. Pair it with an incoming text color that remains readable in both modes.

    Gray bubble

    Gray bubble

    Blue bubble

    Blue bubble

    In your main-actor setup function, after adding the named asset:

    Swift
    Reception.shared.appearance.incomingBackground = Color("SupportIncoming")

    The dashboard calls this Incoming bubbles. Assign nil to restore the adaptive secondary system background locally.

    incomingForeground

    Signature: public var incomingForeground: Color?. Default: nil, which uses .primary. Accepts any SwiftUI Color, including a theme variable, or nil.

    Sets incoming message text and the body text of review and paywall cards. Card button labels use onAccentColor; secondary labels keep their own colors.

    Black text

    Black text

    Blue text

    Blue text

    In your main-actor setup function, after adding the named asset:

    Swift
    Reception.shared.appearance.incomingForeground = Color("SupportIncomingText")

    The dashboard calls this Incoming text. Assign nil to restore the adaptive primary label color locally.

    preferredColorScheme

    Signature: public var preferredColorScheme: ColorScheme?. Default: nil. Allowed values: nil, .light, .dark.

    nil follows the app’s inherited color scheme. .light or .dark forces the chat’s appearance, including the variant selected by adaptive colors. Presented chat applies a presentation preference; embedded chat applies the scheme to its content.

    .light

    .light

    .dark

    .dark

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.preferredColorScheme = .dark

    The dashboard offers Follow app, Always light, or Always dark. Assign nil to follow the app locally. A published Follow app value overrides a local .light or .dark; clearing the remote override instead inherits the local choice.

    Title and welcome text

    title

    Signature: @MainActor public var title: String { get set }. Default: the localized “Support” title. Accepts any local String; there is no local length validation. Dashboard translations are limited to 80 characters.

    Sets the chat’s navigation title. Keep it short enough to fit the navigation bar.

    Support · default

    Support · default

    Help

    Help

    In your main-actor setup function, using copy from your app’s string catalog:

    Swift
    Reception.shared.appearance.title = String(localized: "Help")

    A custom string is displayed as supplied; see Localization of texts and Return to defaults before replacing built-in copy.

    welcomeTitle

    Signature: @MainActor public var welcomeTitle: String { get set }. Default: the localized “Questions, feedback, or a bug?” headline. Accepts any local String; there is no local length validation. Dashboard translations are limited to 160 characters.

    Sets the heading in the empty chat. It is not an introductory message inserted into conversation history.

    Default heading

    Default heading

    Custom heading

    Custom heading

    In your main-actor setup function, using copy from your app’s string catalog:

    Swift
    Reception.shared.appearance.welcomeTitle = String(localized: "How can we help?")

    Leave it unset to retain the built-in translated heading; resetting an assigned string requires the approach in Return to defaults.

    welcomeText

    Signature: @MainActor public var welcomeText: String { get set }. Default: the localized “You're chatting directly with our team.” text. Accepts any local String; there is no local length validation. Dashboard translations are limited to 1,000 characters.

    Sets the explanatory text below the empty chat’s welcome heading. It does not set an automatic reply or alter existing messages.

    Default text

    Default text

    Custom text

    Custom text

    In your main-actor setup function, using copy from your app’s string catalog:

    Swift
    Reception.shared.appearance.welcomeText = String(localized: "Tell us what you need help with.")

    Leave it unset to retain the built-in translated text; see Return to defaults after assigning custom copy.

    Typography

    fontDesign

    Signature: public var fontDesign: Font.Design?. Default: nil, which uses the default system design. Allowed values: nil, .default, .rounded, .serif, .monospaced.

    Selects the system font design used by chat text, including the title, message text, composer, and status labels. System symbols and native controls retain their own rendering. A non-nil fontFamily takes precedence.

    .default

    .default

    .rounded

    .rounded

    .serif

    .serif

    .monospaced

    .monospaced

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.fontDesign = .rounded

    Assign nil to restore the local default system design. Also clear fontFamily if you previously selected a custom font.

    fontFamily

    Signature: public var fontFamily: String?. Default: nil, which uses the system font. Accepts a custom font name string or nil.

    ReceptionKit passes this name to SwiftUI’s Font.custom. When your app uses a custom font for its main UI text, reuse the exact registered font/PostScript name already working in the host’s Font.custom or UIFont(name:size:) call, preferably through its existing font constant. Despite the property name, the value is a technical font name: its display label, .ttf/.otf filename, and family name can differ. Do not derive the value from those labels.

    If you need to find the name, call UIFont.fontNames(forFamilyName:) in the running host app to list the registered names for its existing family, then confirm your chosen name returns a non-nil font from UIFont(name:size:). Preserve the host’s existing font registration; do not add fonts or assets just for support chat. If the host uses the system font, leave fontFamily as nil; use fontDesign only to match an existing system design.

    Custom fonts scale with Dynamic Type. This property overrides fontDesign, including a design published from the dashboard.

    System font · nil

    System font · nil

    Georgia

    Georgia

    In your main-actor setup function, using Georgia, which is already registered on iOS:

    Swift
    Reception.shared.appearance.fontFamily = "Georgia"

    Available only in Swift; the dashboard cannot upload or select a custom font. Assign nil to return to the resolved system fontDesign. An empty string is still a non-nil custom font name, not a reset.

    Dismissal and message behavior

    showsCloseButton

    Signature: public var showsCloseButton: Bool. Default: false. Allowed values: true, false.

    When true, a presented chat shows a trailing close button that dismisses its presentation. The SDK-owned sheet and a host-owned SwiftUI sheet supply this presentation context. The sheet’s native drag indicator stays visible regardless of this setting. Hiding the button does not disable swipe-to-dismiss.

    false · default

    false · default

    true

    true

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.showsCloseButton = true

    Assign false to restore the local default. A directly embedded chat outside a presentation does not gain a close button; your app supplies its navigation or dismissal controls. Reception.shared.closeChat() dismisses an SDK-owned sheet, not a host-owned ReceptionChatView. See Entry point for presentation ownership.

    closeIcon

    Signature: public var closeIcon: Reception.CloseIcon. Default: .xmark. Allowed values: .xmark, .chevronDown, .arrowDown. Their raw symbol names are xmark, chevron.down, and arrow.down.

    Selects the optional chat close button’s symbol. It does not change the dismissal action, show the button by itself, or change the photo viewer’s close symbol.

    .xmark

    .xmark

    .chevronDown

    .chevronDown

    .arrowDown

    .arrowDown

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.showsCloseButton = true
    Reception.shared.appearance.closeIcon = .chevronDown

    Assign .xmark to restore the local default.

    fadesOlderMessages

    Signature: public var fadesOlderMessages: Bool. Default: true. Allowed values: true, false.

    Lightens older outgoing text bubble fills toward white. The newest outgoing text bubble keeps the accent color. Text, photos, and incoming bubbles are unaffected. Increase Contrast disables fading. Sending-state dimming is separate.

    true · default

    true · default

    false

    false

    In your main-actor setup function:

    Swift
    Reception.shared.appearance.fadesOlderMessages = false

    false keeps outgoing fills at the accent color; assign true to restore local age-based fading.

    Localization of texts

    Leave the three text properties unset to retain built-in translations. An assigned String is a local override, even when its contents equal the English default. ReceptionKit does not translate that string for you. Resolve custom strings through your app’s string catalog and reassign them when your app’s own language selection changes.

    See Language for every supported language code, Reception.shared.languageOverride, and matching rules. See Remote appearance for dashboard translation selection, limits, and fallbacks.

    Dashboard appearance

    Publish colors, text, typography, and behavior from the dashboard without shipping a new app build. The Remote appearance guide explains the editor, draft and published states, language-specific text, caching, and when changes become visible. Custom font files and fontFamily remain host-app resources.

    Return to defaults

    Optional color properties, preferredColorScheme, fontDesign, and fontFamily reset locally with nil. Restore nonoptional properties using their defaults listed above.

    Assigning an empty string or the displayed default doesn't restore automatic translation. For example, Reception.shared.appearance.title = Reception.Appearance().title copies the current translated text into a fixed override; it does not restore future automatic language changes.

    To restore automatic localized defaults, construct a fresh Reception.Appearance and reapply only the customization you want to keep. Put this in your main-actor setup function to keep an accent while restoring all other local defaults:

    Swift
    var appearance = Reception.Appearance()
    appearance.accentColor = Color("SupportAccent")
    Reception.shared.appearance = appearance

    For a complete local reset, use this assignment in the same main-actor context:

    Swift
    Reception.shared.appearance = Reception.Appearance()

    These assignments do not disable remote appearance or clear published settings. In the dashboard, removing an override restores inheritance from the app’s local value. Restore defaults clears the editor’s draft; publish the reset to deliver it. It does not reset your Swift configuration. See Remote appearance.

    Verify your customization

    Open both an empty chat and a chat containing incoming and outgoing messages. Check light and dark mode, larger Dynamic Type sizes, Increase Contrast, your supported languages, and your actual sheet or embedded presentation.

    If an option appears ineffective, check whether a published remote override applies. For fonts, clear fontFamily before checking fontDesign. For close controls, confirm that the chat is presented and showsCloseButton resolves to true. For welcome text, inspect an empty chat. After publishing dashboard changes, allow the refresh to complete and reopen chat; the dashboard preview cannot reproduce your app’s local overrides or bundled fonts.