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.
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.
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.
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.
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.