Inertia (React & Vue)

Ruby Native includes first-class support for Inertia.js apps using React or Vue. This guide covers the one-time setup. Once configured, all the feature guides (navbar, forms, badges, etc.) include Inertia examples alongside ERB.

#1. Include the concern

Add RubyNative::InertiaSupport to your application controller. It shares nativeApp and nativeForm props automatically via inertia_share.

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include RubyNative::InertiaSupport
end

Your own InertiaSharedData concern handles app-specific props (flash, current_user, etc.). The gem concern only shares what it owns.

#2. Install the npm package

React and Vue components ship as two scoped npm packages under the Ruby Native org. Install the one that matches your frontend.

npm install @ruby-native/react
npm install @ruby-native/vue

Import the components directly in your pages and layouts.

import { NativeTabs, NativePush, NativePresentation } from "@ruby-native/react"
import { NativeTabs, NativePush, NativePresentation } from "@ruby-native/vue"

#3. Use the nativeApp prop

The InertiaSupport concern shares a nativeApp boolean prop on every page. Use it to hide web-only elements when the native app is connected.

import { usePage } from "@inertiajs/react"

export default function Index() {
  const { nativeApp } = usePage().props

  return (
    <>
      {!nativeApp && <h1>Habits</h1>}
      {/* ... */}
    </>
  )
}
<script setup>
import { usePage } from "@inertiajs/vue3"
import { computed } from "vue"

const page = usePage()
const nativeApp = computed(() => page.props.nativeApp)
</script>

<template>
  <h1 v-if="!nativeApp">Habits</h1>
  <!-- ... -->
</template>

This is the Inertia equivalent of the native_app? helper used in ERB views.

#4. Check the platform with nativePlatform()

Both packages also export nativePlatform(), which reads the User-Agent and returns "ios", "android", or null on the web. Reach for it when an element belongs on one platform only, or to hide native-only controls like the scan button from web visitors.

import { nativePlatform } from "@ruby-native/react"

{nativePlatform() && <ScanButton />}
<script setup>
import { nativePlatform } from "@ruby-native/vue"
</script>

<template>
  <ScanButton v-if="nativePlatform()" />
</template>

Unlike the nativeApp prop, nativePlatform() runs client-side, so it also works outside a page component: in a shared layout, a plain script, or an event handler. During server-side rendering it returns null.

#Feature guides

With setup complete, follow the feature guides to add native functionality. Each guide includes Inertia examples alongside ERB.