How do I tell if a request came from the native mobile app?
Use the hotwire_native_app? helper in app/controllers/application_controller.rb. The shells append "Hotwire Native" to the user agent, and the helper reads it. That check is how you show the native purchase trigger in the app and the Stripe button on the web, which the store rules require you to get right.
The helper
hotwire_native_app? # true in either shell
hotwire_native_android? # true in the Android shell specifically
Both are declared as helper_method in app/controllers/application_controller.rb, so views can
call them directly. The Android-specific one exists because the two platforms differ on what has to
be hidden, not because the code needs to know which phone it is talking to in general. The shells
that set the user agent are in mobile/ios and mobile/android.
The case that actually matters
<% if hotwire_native_app? %>
<%= link_to "Subscribe", iap_subscribe_path %>
<% else %>
<%= button_to "Subscribe", checkout_path %>
<% end %>
Showing a Stripe checkout button inside the iOS app is the most common reason an app of this shape is rejected. Apple requires digital subscriptions to go through StoreKit, and a link out to an external payment page is what reviewers look for.
Do not use it for authentication
A user agent is a string the client sends and anyone can set. It is fine for deciding which button to
render and wrong for deciding who someone is or what they may do. Entitlement still goes through
Entitlement.for(Current.account) and record access still goes through Pundit, regardless of the
client.
Use it sparingly
Every branch on this helper is a second version of a page that has to be kept working. Two or three in an app is normal: the purchase trigger, the subscription management link, and perhaps hiding a footer. A dozen means the app and the site have quietly become different products.
Check it while developing
bin/dev
Then load a page in the shell and one in a browser side by side. If you want to test the branch without building, override the user agent in your browser's devtools to include "Hotwire Native" and reload. That is faster than a rebuild for checking which button renders.