Badges

Update the app icon badge and tab bar badge from regular page loads. Badges stay in sync as users navigate, without needing to send a push notification.

The tab bar badge works on iOS and Android. The app icon badge is iOS-only: Android has no per-app numeric badge API, so launcher badges there come from notification channels instead. A home: count is simply ignored on Android, and the same call still updates the tab badge.

Tab bar badge
Tab bar badge on iOS

#Setup

Mark which tab should display the badge in config/ruby_native.yml:

tabs:
  - title: Home
    path: /
    icon: house
  - title: Notifications
    path: /notifications
    icon: bell
    badge: true

Only one tab can have badge: true. The tab badge appears on this tab whenever a count is set.

#Basic usage

Add native_badge_tag to any page. When the page loads, the app updates the badge counts.

<%= native_badge_tag(@unread_count) %>
import { NativeBadge } from "@ruby-native/react"

<NativeBadge count={unreadCount} />
<script setup>
import { NativeBadge } from "@ruby-native/vue"
</script>

<template>
  <NativeBadge :count="unreadCount" />
</template>

A single number sets both the Home Screen (app icon) badge and the tab bar badge to the same count. Passing 0 clears both badges.

#Independent counts

Set the Home Screen badge and tab badge to different values with keyword arguments:

<%= native_badge_tag(home: @total_unread, tab: @inbox_unread) %>

Omitted parameters leave that badge unchanged. For example, updating only the tab badge:

<%= native_badge_tag(tab: @inbox_unread) %>

Or only the Home Screen badge:

<%= native_badge_tag(home: @total_unread) %>

NativeBadge takes the same three values as props in Inertia: count, home, and tab.

#JavaScript API

Update badges programmatically from JavaScript:

RubyNative.setBadge(5)                     // both = 5
RubyNative.setBadge({ home: 2, tab: 3 })   // independent counts
RubyNative.setBadge(0)                      // clears both

Use it when badge counts change without a full page load, like after reading a message via a Turbo Stream.

Badges persist across page navigations. If a page does not include native_badge_tag, the current badge counts remain unchanged. No push notification permissions are required.