Debugging

Ruby Native reads your pages through signals: hidden elements carrying data-native-* attributes that tell the app to show a tab bar, a navigation bar, a badge, and so on. The helpers in your views render them for you.

Signals are ignored when the app does not recognize them. That is what lets the same page work in a browser and in the app, and it is why a mistyped signal never raises anything. The page renders, the app opens, and the tab bar is simply missing.

This page covers the two places Ruby Native tells you about that: a warning while you are testing, and a command you can run before a build.

#Warnings in the Ruby Native app

When you open your site in the Ruby Native app, it checks every page it renders and shows a warning toast when something looks wrong:

⚠️ Ruby Native: unknown data-native-tabss, duplicate data-native-form

It appears on both platforms, shows at most two problems with a +2 more suffix beyond that, and stays quiet if you revisit a page with the same problems. A new problem warns again.

This only ever appears in the Ruby Native app. Your own builds drop it silently, so your users never see it. That also means it will not help you once you have moved off ruby_native preview, which is what the next section is for.

#Checking before a build

ruby_native check reads every view in your app and reports the same problems, without waiting for someone to open the page:

bundle exec ruby_native check
app/views/layouts/native.html.erb
  12:  error   Unknown signal `data-native-tabss`. Did you mean `data-native-tabs`?
  31:  warning 2 elements carry `data-native-form`; only the first one is used.

Checked 48 templates: 1 error, 1 warning.

It exits 1 on an error and 0 otherwise, and deploy runs it for you before triggering a build. See the CLI reference for the options.

check needs the herb gem, which Rails 8.2 and later already include through Action View. On earlier versions, add gem "herb" to your Gemfile.

Running it on every commit is the point, and it needs no token. See Continuous integration.

#What goes wrong

Problem What you see Fix
Mistyped signal Nothing happens Use the helper (native_tabs_tag) rather than writing the attribute by hand
Duplicated signal Only the first one works Some signals are read once per page. Render it in one place, usually the layout
Signal is too new Nothing happens The signal was added in a later version of Ruby Native than your Gemfile has. Update the gem
Signal is newer than your build Works locally, not for users Your users have an older build. Deploy, or check with ruby_native check --deployed

#The signal is there and still nothing happens

The most common cause is a layout that does not render it on every request. Ruby Native reads the page it is given, so a tab bar signal inside a conditional that is false, or in a layout that a particular action skips, reads as "this page has no tabs" and the app removes the tab bar accordingly.

Rendering the signal from your native layout, unconditionally, is the reliable shape:

<%# app/views/layouts/native.html.erb %>
<%= native_tabs_tag %>

If a signal should only apply to signed-in users, gate the whole layout rather than the signal inside it.

#Checking against the app your users have

The gem in your Gemfile says what your views may emit. The build in the store says what your app can honor, and those drift apart as soon as you update the gem without deploying.

bundle exec ruby_native check --deployed

This compares your views against the most recent build for each platform and reports signals that will not work for anyone who has already installed your app. It needs you to be logged in, or RUBY_NATIVE_TOKEN set.