inertia-rails-setup

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Inertia Rails Setup

Inertia Rails 搭建指南

This skill helps you set up Inertia.js in a Ruby on Rails application with your choice of frontend framework.
本技能可帮助你在Ruby on Rails应用中搭配所选前端框架完成Inertia.js的搭建。

Recommended: Official Starter Kits

推荐方案:官方启动模板

For new projects, the fastest way to get started is cloning an official starter kit. These include authentication, shadcn/ui components, TypeScript, and optional SSR support out of the box.
对于新项目,最快的入门方式是克隆官方启动模板。这些模板默认包含身份验证、shadcn/ui组件、TypeScript,以及可选的SSR支持。

React Starter Kit (Recommended)

React启动模板(推荐)

bash
git clone https://github.com/inertia-rails/react-starter-kit myapp
cd myapp
bin/setup
Includes:
  • React 19 + TypeScript
  • shadcn/ui component library (20+ components)
  • User authentication (login, register, password reset)
  • Settings pages (profile, password, email, sessions, appearance)
  • Multiple layouts (sidebar, header, auth variants)
  • Dark mode support
  • Kamal deployment config
  • Optional SSR support
  • Flash messages with Sonner toasts
bash
git clone https://github.com/inertia-rails/react-starter-kit myapp
cd myapp
bin/setup
包含内容:
  • React 19 + TypeScript
  • shadcn/ui组件库(20+个组件)
  • 用户身份验证(登录、注册、密码重置)
  • 设置页面(个人资料、密码、邮箱、会话、外观)
  • 多种布局(侧边栏、头部、身份验证变体)
  • 深色模式支持
  • Kamal部署配置
  • 可选SSR支持
  • 基于Sonner提示框的Flash消息

Vue Starter Kit

Vue启动模板

bash
git clone https://github.com/inertia-rails/vue-starter-kit myapp
cd myapp
bin/setup
bash
git clone https://github.com/inertia-rails/vue-starter-kit myapp
cd myapp
bin/setup

Svelte Starter Kit

Svelte启动模板

bash
git clone https://github.com/inertia-rails/svelte-starter-kit myapp
cd myapp
bin/setup
bash
git clone https://github.com/inertia-rails/svelte-starter-kit myapp
cd myapp
bin/setup

Customizing the Starter Kit

自定义启动模板

After cloning:
  1. Rename the app:
    bash
    # Update config/application.rb
    module YourAppName
      class Application < Rails::Application
  2. Update database config:
    bash
    # Edit config/database.yml with your settings
  3. Remove example pages you don't need:
    bash
    # Delete from app/frontend/pages/ and corresponding controllers
  4. Add your own pages:
    bash
    bin/rails generate controller Products index show
    # Create app/frontend/pages/products/index.tsx
  5. Customize the layout:
    • Edit
      app/frontend/layouts/app-layout.tsx
      for main app
    • Edit
      app/frontend/components/nav-main.tsx
      for navigation

克隆完成后:
  1. 重命名应用:
    bash
    # 更新 config/application.rb
    module YourAppName
      class Application < Rails::Application
  2. 更新数据库配置:
    bash
    # 编辑 config/database.yml 配置你的数据库信息
  3. 移除不需要的示例页面:
    bash
    # 删除 app/frontend/pages/ 下的文件及对应的控制器
  4. 添加自定义页面:
    bash
    bin/rails generate controller Products index show
    # 创建 app/frontend/pages/products/index.tsx
  5. 自定义布局:
    • 编辑
      app/frontend/layouts/app-layout.tsx
      配置主应用布局
    • 编辑
      app/frontend/components/nav-main.tsx
      配置导航栏

Alternative: Generator Setup

替代方案:生成器搭建

If you prefer starting from scratch or adding Inertia to an existing Rails app:
如果你偏好从空白项目开始,或是为现有Rails应用添加Inertia支持:

Quick Setup

快速搭建

bash
undefined
bash
undefined

Create new Rails app (if needed)

(如有需要)创建新的Rails应用

rails new myapp --skip-javascript
rails new myapp --skip-javascript

Add inertia_rails gem

添加 inertia_rails gem

bundle add inertia_rails
bundle add inertia_rails

Run the generator

运行生成器

bin/rails generate inertia:install

The generator will prompt you to select:
- Frontend framework (React, Vue, or Svelte)
- TypeScript support
- Tailwind CSS integration
bin/rails generate inertia:install

生成器会提示你选择:
- 前端框架(React、Vue或Svelte)
- TypeScript支持
- Tailwind CSS集成

Manual Setup Steps

手动搭建步骤

1. Add the Gem

1. 添加Gem包

ruby
undefined
ruby
undefined

Gemfile

Gemfile

gem 'inertia_rails'

```bash
bundle install
gem 'inertia_rails'

```bash
bundle install

2. Install Vite Rails (if not present)

2. 安装Vite Rails(如未安装)

bash
bundle add vite_rails
bundle exec vite install
bash
bundle add vite_rails
bundle exec vite install

3. Configure the Root Layout

3. 配置根布局

Create or update
app/views/layouts/application.html.erb
:
erb
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csp_meta_tag %>
    <%= inertia_ssr_head %>
    <%= vite_client_tag %>
    <%= vite_javascript_tag 'application' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
创建或更新
app/views/layouts/application.html.erb
erb
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csp_meta_tag %>
    <%= inertia_ssr_head %>
    <%= vite_client_tag %>
    <%= vite_javascript_tag 'application' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

4. Install Frontend Dependencies

4. 安装前端依赖

For React:
bash
npm install @inertiajs/react react react-dom
For Vue 3:
bash
npm install @inertiajs/vue3 vue
For Svelte:
bash
npm install @inertiajs/svelte svelte
React环境:
bash
npm install @inertiajs/react react react-dom
Vue 3环境:
bash
npm install @inertiajs/vue3 vue
Svelte环境:
bash
npm install @inertiajs/svelte svelte

5. Configure the Frontend Entry Point

5. 配置前端入口文件

Create
app/frontend/entrypoints/application.js
:
React:
javascript
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.jsx', { eager: true })
    return pages[`../pages/${name}.jsx`]
  },
  setup({ el, App, props }) {
    createRoot(el).render(<App {...props} />)
  },
})
Vue 3:
javascript
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
    return pages[`../pages/${name}.vue`]
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})
Svelte:
javascript
import { createInertiaApp } from '@inertiajs/svelte'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.svelte', { eager: true })
    return pages[`../pages/${name}.svelte`]
  },
  setup({ el, App }) {
    new App({ target: el })
  },
})
创建
app/frontend/entrypoints/application.js
React:
javascript
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.jsx', { eager: true })
    return pages[`../pages/${name}.jsx`]
  },
  setup({ el, App, props }) {
    createRoot(el).render(<App {...props} />)
  },
})
Vue 3:
javascript
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
    return pages[`../pages/${name}.vue`]
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})
Svelte:
javascript
import { createInertiaApp } from '@inertiajs/svelte'

createInertiaApp({
  resolve: (name) => {
    const pages = import.meta.glob('../pages/**/*.svelte', { eager: true })
    return pages[`../pages/${name}.svelte`]
  },
  setup({ el, App }) {
    new App({ target: el })
  },
})

6. Create the Pages Directory

6. 创建页面目录

bash
mkdir -p app/frontend/pages
bash
mkdir -p app/frontend/pages

7. Configure the Initializer

7. 配置初始化器

Create
config/initializers/inertia_rails.rb
:
ruby
undefined
创建
config/initializers/inertia_rails.rb
ruby
undefined

frozen_string_literal: true

frozen_string_literal: true

InertiaRails.configure do |config|

Asset versioning - triggers full reload when assets change

config.version = -> { ViteRuby.digest }

Flash keys exposed to frontend

config.flash_keys = %i[notice alert]

Deep merge shared data with page props

config.deep_merge_shared_data = true

Encrypt history for sensitive data (requires HTTPS)

config.encrypt_history = Rails.env.production?

end
undefined
InertiaRails.configure do |config|

资源版本控制 - 资源变更时触发全量重载

config.version = -> { ViteRuby.digest }

暴露给前端的Flash键

config.flash_keys = %i[notice alert]

深度合并共享数据与页面属性

config.deep_merge_shared_data = true

加密历史记录以保护敏感数据(需HTTPS)

config.encrypt_history = Rails.env.production?

end
undefined

8. Set Up Shared Data

8. 设置共享数据

In
app/controllers/application_controller.rb
:
ruby
class ApplicationController < ActionController::Base
  inertia_share do
    {
      flash: {
        notice: flash.notice,
        alert: flash.alert
      },
      auth: {
        user: current_user&.as_json(only: [:id, :name, :email])
      }
    }
  end
end
app/controllers/application_controller.rb
中:
ruby
class ApplicationController < ActionController::Base
  inertia_share do
    {
      flash: {
        notice: flash.notice,
        alert: flash.alert
      },
      auth: {
        user: current_user&.as_json(only: [:id, :name, :email])
      }
    }
  end
end

9. Create Your First Page

9. 创建你的第一个页面

Controller:
ruby
undefined
控制器:
ruby
undefined

app/controllers/home_controller.rb

app/controllers/home_controller.rb

class HomeController < ApplicationController def index render inertia: { message: 'Welcome to Inertia Rails!' } end end

**Route:**
```ruby
class HomeController < ApplicationController def index render inertia: { message: 'Welcome to Inertia Rails!' } end end

**路由:**
```ruby

config/routes.rb

config/routes.rb

Rails.application.routes.draw do root 'home#index' end

**Page Component (React):**
```jsx
// app/frontend/pages/home/index.jsx
export default function Home({ message }) {
  return (
    <div>
      <h1>{message}</h1>
    </div>
  )
}
Page Component (Vue):
vue
<!-- app/frontend/pages/home/index.vue -->
<script setup>
defineProps(['message'])
</script>

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>
Rails.application.routes.draw do root 'home#index' end

**页面组件(React):**
```jsx
// app/frontend/pages/home/index.jsx
export default function Home({ message }) {
  return (
    <div>
      <h1>{message}</h1>
    </div>
  )
}
页面组件(Vue):
vue
<!-- app/frontend/pages/home/index.vue -->
<script setup>
defineProps(['message'])
</script>

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

10. Start the Development Servers

10. 启动开发服务器

bash
undefined
bash
undefined

Terminal 1: Rails server

终端1:Rails服务器

bin/rails server
bin/rails server

Terminal 2: Vite dev server

终端2:Vite开发服务器

bin/vite dev
undefined
bin/vite dev
undefined

Configuration Options Reference

配置选项参考

OptionDefaultDescription
version
nil
Asset version for cache busting
layout
'application'
Default layout template
flash_keys
[:notice, :alert]
Flash keys to share
deep_merge_shared_data
false
Deep merge props
encrypt_history
false
Encrypt browser history
ssr_enabled
false
Enable SSR
ssr_url
'http://localhost:13714'
SSR server URL
default_render
false
Auto-render Inertia
root_dom_id
'app'
Root element ID
选项默认值说明
version
nil
资源版本号,用于缓存刷新
layout
'application'
默认布局模板
flash_keys
[:notice, :alert]
要共享的Flash键
deep_merge_shared_data
false
深度合并属性
encrypt_history
false
加密浏览器历史记录
ssr_enabled
false
启用SSR
ssr_url
'http://localhost:13714'
SSR服务器地址
default_render
false
自动渲染Inertia页面
root_dom_id
'app'
根元素ID

Environment Variables

环境变量

All config options can be set via
INERTIA_
prefixed env vars:
bash
INERTIA_SSR_ENABLED=true
INERTIA_ENCRYPT_HISTORY=true
所有配置选项均可通过前缀为
INERTIA_
的环境变量设置:
bash
INERTIA_SSR_ENABLED=true
INERTIA_ENCRYPT_HISTORY=true

Troubleshooting

问题排查

"Cannot find module '@inertiajs/react'"

"Cannot find module '@inertiajs/react'"

Run
npm install
to install dependencies.
运行
npm install
安装依赖包。

Blank page with no errors

页面空白且无报错

Check browser console for JavaScript errors. Ensure Vite dev server is running.
检查浏览器控制台的JavaScript错误,确保Vite开发服务器正在运行。

Props not updating

属性未更新

Ensure you're using
render inertia:
not
render json:
.
确保你使用的是
render inertia:
而非
render json:

CSRF token errors

CSRF令牌错误

Inertia handles CSRF automatically via Axios. Ensure
protect_from_forgery
is enabled.
Inertia会通过Axios自动处理CSRF,确保
protect_from_forgery
已启用。