logo

Inertia Rage

The official Inertia.js adapter for the Rage framework.

This gem handles Inertia page responses, provides flexible prop types, and integrates seamlessly with Vite.

Usage

Create a Rage app and add the gem:

rage new my-app -d postgresql
bundle add inertia-rage

Create a frontend project in any directory within your project's root or app folder:

npm create vite@latest app/frontend

Install the required packages and initialize your Inertia app. Refer to the Inertia documentation for client-side setup.

If you are using React

Vite's React template uses root as the container element id, but Inertia expects app. Update index.html accordingly:

<body>
-  <div id="root"></div>
+  <div id="app"></div>
  <script type="module" src="/src/main.ts"></script>
</body>

Start the app:

rage s

Rage automatically starts the Vite dev server in development and pre-builds assets in other environments. In most cases, rage s is all you need to run your app.

Rendering

Use render inertia: to render Inertia responses in your controller actions:

class PostsController < ApplicationController
  def index
    render inertia: "Posts/Index", props: { posts: current_user.posts }
  end
end

Rage can also infer the component name from the current controller and action. The following will render the Posts/Index component:

class PostsController < ApplicationController
  def index
    render inertia: { posts: current_user.posts }
  end
end

Redirects are supported via redirect_to, redirect_back, and redirect_back_or_to:

class PostsController < ApplicationController
  def create
    Post.create!(post_params)
    redirect_back fallback_location: "/"
  end
end

Props

Inertia Rage supports several prop types to optimize data loading and improve performance.

Lazy Props

Define lazy props using procs:

render inertia: {
  user:,
  posts: -> { user.posts }
}

Lazy props are evaluated on the initial page load just like regular props. The difference emerges during partial reloads: lazy props are only evaluated when explicitly requested. For example, if a partial reload requests only user, the posts query is skipped entirely.

Deferred Props

Deferred props are excluded from the initial page load and fetched automatically in a subsequent request:

render inertia: {
  user:,
  comments: Inertia.deferred { user.build_comments_tree }
}

Use deferred props for expensive operations that would otherwise slow down the initial page load.

Optional Props

Optional props are never evaluated during the initial page load. The frontend must explicitly request them:

render inertia: {
  user:,
  last_posted_at: Inertia.optional { user.posts.last.created_at }
}

Once Props

Once props are cached by the frontend after their first evaluation. On subsequent requests, the cached value is used and the prop is not re-evaluated. Since Inertia resets the cache for once props that are absent from the page, you'll typically want to use them inside inertia_share blocks:

class ApplicationController < RageController::API
  inertia_share do
    { permissions: Inertia.once { current_user.permissions } }
  end
end

Shared Data

Use inertia_share to share data across all Inertia responses:

class ApplicationController < RageController::API
  inertia_share do
    { has_new_notifications: current_user.notifications.unread.exists? }
  end
end

inertia_share accepts the same arguments as before_action:

class DashboardsController < ApplicationController
  inertia_share if: :user_signed_in?, except: :destroy do
    { all_dashboards: Dashboard.where.not(user: current_user) }
  end
end

Testing with RSpec

The gem provides an inertia helper for testing Inertia responses. Require inertia/rspec in your request specs to access it:

require "inertia/rspec"

RSpec.describe UsersController, type: :request do
  it "renders user posts" do
    get "posts"

    expect(inertia.component).to eq("Posts/Index")
    expect(inertia.props).to have_key(:posts)
  end
end

Configuration

Use Inertia.configure to customize the default behavior:

Inertia.configure do |config|
  config.build_on_start = false
  config.dev_server.port = 5000
end

See the API documentation for the complete list of configuration options.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/rage-rb/inertia-rage. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Inertia::Rage project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.