Inertia.js Rails Adapter
Installation
Backend
Just add the inertia rails gem to your Gemfile
gem 'inertia_rails'
Frontend
Rails 7 specific frontend docs coming soon. For now, check out the official Inertia docs at https://inertiajs.com/ or see an example using React/Vite here
Usage
Responses
Render Inertia responses is simple, just use the inertia renderer in your controller methods. The renderer accepts two arguments, the first is the name of the component you want to render from within your pages directory (without extension). The second argument is an options hash where you can provide props
to your components. This options hash also allows you to pass view_data
to your layout, but this is much less common.
def index
render inertia: 'Event/Index', props: {
events: Event.all,
}
end
Rails Component and Instance Props
Starting in version 3.0, Inertia Rails allows you to provide your component name and props via common rails conventions.
class EventsController < ApplicationController
use_inertia_instance_props
def index
@events = Event.all
end
end
is the same as
class EventsController < ApplicationController
def index
render inertia: 'events/index', props: {
events: Event.all
}
end
end
Instance Props and Default Render Notes
In order to use instance props, you must call use_inertia_instance_props
on the controller (or a base controller it inherits from). If any props are provided manually, instance props
are automatically disabled for that response. Instance props are only included if they are defined after the before filter is set from use_inertia_instance_props
.
Automatic component name is also opt in, you must set the default_render
config value to true
. Otherwise, you can simply render inertia: true
for the same behavior explicitly.
Layout
Inertia layouts use the rails layout convention and can be set or changed in the same way. The original layout
config option is still functional, but will likely be deprecated in the future in favor
of using rails layouts.
class EventsController < ApplicationController
layout 'inertia_application'
end
Shared Data
If you have data that you want to be provided as a prop to every component (a common use-case is informationa about the authenticated user) you can use the shared_data
controller method.
class EventsController < ApplicationController
# share syncronously
inertia_share app_name: env['app.name']
# share lazily, evaluated at render time
inertia_share do
if logged_in?
{
user: logged_in_user,
}
end
end
# share lazily alternate syntax
inertia_share user_count: lambda { User.count }
end
Lazy Props
On the front end, Inertia supports the concept of "partial reloads" where only the props requested are returned by the server. Sometimes, you may want to use this flow to avoid processing a particularly slow prop on the intial load. In this case, you can use Lazy props. Lazy props aren't evaluated unless they're specifically requested by name in a partial reload.
inertia_share some_data: InertiaRails.lazy(lambda { some_very_slow_method })
Routing
If you don't need a controller to handle a static component, you can route directly to a component with the inertia route helper
inertia 'about' => 'AboutComponent'
SSR
Enable SSR via the config settings for ssr_enabled
and ssr_url
Configuration
Inertia Rails has a few different configuration options that can be set anywhere, but the most common location is from within an initializer.
The default config is shown below
InertiaRails.configure do |config|
# set the current version for automatic asset refreshing. A string value should be used if any.
config.version = nil
# enable default inertia rendering (warning! this will override rails default rendering behavior)
config.default_render = true
# ssr specific options
config.ssr_enabled = false
config.ssr_url = 'http://localhost:13714'
end
Testing
If you're using Rspec, Inertia Rails comes with some nice test helpers to make things simple.
To use these helpers, just add the following require statement to your spec/rails_helper.rb
require 'inertia_rails/rspec'
And in any test you want to use the inertia helpers, add the inertia flag to the describe block
RSpec.describe EventController, type: :request do
describe '#index', inertia: true do
# ...
end
end
Assertions
RSpec.describe EventController, type: :request do
describe '#index', inertia: true do
# check the component
expect_inertia.to render_component 'Event/Index'
# access the component name
expect(inertia.component).to eq 'TestComponent'
# props (including shared props)
expect_inertia.to have_exact_props({name: 'Brandon', sport: 'hockey'})
expect_inertia.to include_props({sport: 'hockey'})
# access props
expect(inertia.props[:name]).to eq 'Brandon'
# view data
expect_inertia.to have_exact_view_data({name: 'Brian', sport: 'basketball'})
expect_inertia.to include_view_data({sport: 'basketball'})
# access view data
expect(inertia.view_data[:name]).to eq 'Brian'
end
end
Maintained and sponsored by the team at bellaWatt