Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/generators.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
strategy:
fail-fast: false
matrix:
framework: [react, vue, svelte, svelte4]
framework: [react, vue, svelte]
typescript: [true, false]
tailwind: [true, false]
ruby: ['3.3']
ruby: ['3.4']
node: ['22']
inertia_version: ['latest']

Expand Down
4 changes: 2 additions & 2 deletions bin/generate_scaffold_example
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ options = {
OptionParser.new do |opts|
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"

opts.on('--framework FRAMEWORK', %w[react vue svelte svelte4],
'Choose framework (react/vue/svelte4/svelte)') do |f|
opts.on('--framework FRAMEWORK', %w[react vue svelte],
'Choose framework (react/vue/svelte)') do |f|
options[:framework] = f
end

Expand Down
4 changes: 2 additions & 2 deletions docs/guide/server-side-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This command will:

- Check for Vite Rails and install it if not present
- Ask if you want to use TypeScript
- Ask you to choose your preferred frontend framework (React, Vue, Svelte 4, or Svelte 5)
- Ask you to choose your preferred frontend framework (React, Vue, Svelte)
- Ask if you want to install Tailwind CSS
- Install necessary dependencies
- Set up the application to work with Inertia
Expand All @@ -49,7 +49,7 @@ Vite Rails gem successfully installed
Vite Rails successfully installed
Would you like to use TypeScript? (y/n) y
Adding TypeScript support
What framework do you want to use with Inertia? [react, vue, svelte4, svelte] (react)
What framework do you want to use with Inertia? [react, vue, svelte] (react)
run npm add @types/react @types/react-dom typescript --silent from "."
Would you like to install Tailwind CSS? (y/n) y
Installing Tailwind CSS
Expand Down
52 changes: 16 additions & 36 deletions lib/generators/inertia/install/frameworks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ react:
vite_plugin_import: "import react from '@vitejs/plugin-react'"
vite_plugin_call: "react()"
copy_files_ts:
"InertiaExample.tsx": "%{js_destination_path}/pages/InertiaExample.tsx"
"InertiaExample.tsx": "%{js_destination_path}/pages/inertia_example/index.tsx"
"tsconfig.json": "tsconfig.json"
"tsconfig.app.json": "tsconfig.app.json"
"tsconfig.node.json": "tsconfig.node.json"
"vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts"
"types/vite-env.d.ts": "%{js_destination_path}/types/vite-env.d.ts"
"types/globals.d.ts": "%{js_destination_path}/types/globals.d.ts"
"types/index.ts": "%{js_destination_path}/types/index.ts"
copy_files_js:
"InertiaExample.jsx": "%{js_destination_path}/pages/InertiaExample.jsx"
"InertiaExample.jsx": "%{js_destination_path}/pages/inertia_example/index.jsx"
copy_files:
"InertiaExample.module.css": "%{js_destination_path}/pages/InertiaExample.module.css"
"InertiaExample.module.css": "%{js_destination_path}/pages/inertia_example/index.module.css"
"../assets/react.svg": "%{js_destination_path}/assets/react.svg"
"../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
"../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
Expand All @@ -41,39 +43,15 @@ vue:
"../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
"../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
copy_files_ts:
"InertiaExample.ts.vue": "%{js_destination_path}/pages/InertiaExample.vue"
"InertiaExample.ts.vue": "%{js_destination_path}/pages/inertia_example/index.vue"
"tsconfig.json": "tsconfig.json"
"tsconfig.app.json": "tsconfig.app.json"
"tsconfig.node.json": "tsconfig.node.json"
"vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts"
"types/vite-env.d.ts": "%{js_destination_path}/types/vite-env.d.ts"
"types/globals.d.ts": "%{js_destination_path}/types/globals.d.ts"
"types/index.ts": "%{js_destination_path}/types/index.ts"
copy_files_js:
"InertiaExample.vue": "%{js_destination_path}/pages/InertiaExample.vue"

svelte4:
inertia_package: "@inertiajs/svelte"
packages:
- "svelte@4"
- "@sveltejs/vite-plugin-svelte@3"
- "vite@5"
packages_ts:
- "@tsconfig/svelte@4"
- "svelte-check"
- "typescript"
- "tslib"
vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'"
vite_plugin_call: "svelte()"
copy_files_ts:
"InertiaExample.ts.svelte": "%{js_destination_path}/pages/InertiaExample.svelte"
"tsconfig.json": "tsconfig.json"
"tsconfig.node.json": "tsconfig.node.json"
"vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts"
copy_files_js:
"InertiaExample.svelte": "%{js_destination_path}/pages/InertiaExample.svelte"
copy_files:
"svelte.config.js": "svelte.config.js"
"../assets/svelte.svg": "%{js_destination_path}/assets/svelte.svg"
"../assets/inertia.svg": "%{js_destination_path}/assets/inertia.svg"
"../assets/vite_ruby.svg": "%{js_destination_path}/assets/vite_ruby.svg"
"InertiaExample.vue": "%{js_destination_path}/pages/inertia_example/index.vue"

svelte:
inertia_package: "@inertiajs/svelte"
Expand All @@ -89,12 +67,14 @@ svelte:
vite_plugin_import: "import { svelte } from '@sveltejs/vite-plugin-svelte'"
vite_plugin_call: "svelte()"
copy_files_ts:
"InertiaExample.ts.svelte": "%{js_destination_path}/pages/InertiaExample.svelte"
"InertiaExample.ts.svelte": "%{js_destination_path}/pages/inertia_example/index.svelte"
"tsconfig.json": "tsconfig.json"
"tsconfig.node.json": "tsconfig.node.json"
"vite-env.d.ts": "%{js_destination_path}/vite-env.d.ts"
"types/vite-env.d.ts": "%{js_destination_path}/types/vite-env.d.ts"
"types/globals.d.ts": "%{js_destination_path}/types/globals.d.ts"
"types/index.ts": "%{js_destination_path}/types/index.ts"
copy_files_js:
"InertiaExample.svelte": "%{js_destination_path}/pages/InertiaExample.svelte"
"InertiaExample.svelte": "%{js_destination_path}/pages/inertia_example/index.svelte"
copy_files:
"svelte.config.js": "svelte.config.js"
"../assets/svelte.svg": "%{js_destination_path}/assets/svelte.svg"
Expand Down
59 changes: 51 additions & 8 deletions lib/generators/inertia/install/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,21 @@ def install
install_example_page if options[:example_page]

say 'Copying bin/dev'
copy_file "#{__dir__}/templates/dev", 'bin/dev'
copy_file 'dev', 'bin/dev'
chmod 'bin/dev', 0o755, verbose: verbose?

if install_vite?
say 'Adding redirect to localhost'
routing_code = <<~RUBY
\n # Redirect to localhost from 127.0.0.1 to use same IP address with Vite server
constraints(host: "127.0.0.1") do
get "(*path)", to: redirect { |params, req| "\#{req.protocol}localhost:\#{req.port}/\#{params[:path]}" }
end
RUBY

route routing_code
end

say "Inertia's Rails adapter successfully installed", :green
end

Expand All @@ -87,12 +99,15 @@ def install_inertia
end

say "Copying #{inertia_entrypoint} entrypoint"
template "#{framework}/#{inertia_entrypoint}", js_file_path("entrypoints/#{inertia_entrypoint}")
copy_file "#{framework}/#{inertia_entrypoint}", js_file_path("entrypoints/#{inertia_entrypoint}")

say 'Copying InertiaController'
copy_file 'inertia_controller.rb', file_path('app/controllers/inertia_controller.rb')

if application_layout.exist?
say "Adding #{inertia_entrypoint} script tag to the application layout"
headers = <<-ERB
<%= #{vite_tag} "inertia" %>
<%= #{vite_tag} %>
<%= inertia_ssr_head %>
ERB
insert_into_file application_layout.to_s, headers, after: "<%= vite_client_tag %>\n"
Expand All @@ -103,14 +118,14 @@ def install_inertia
before: '<%= vite_client_tag %>'
end

gsub_file application_layout.to_s, /<title>/, '<title inertia>' unless svelte?
gsub_file application_layout.to_s, /<title>/, '<title data-inertia>' unless svelte?
else
say_error 'Could not find the application layout file. Please add the following tags manually:', :red
say_error '- <title>...</title>'
say_error '+ <title inertia>...</title>'
say_error '+ <title data-inertia>...</title>'
say_error '+ <%= inertia_ssr_head %>'
say_error '+ <%= vite_react_refresh_tag %>' if framework == 'react'
say_error "+ <%= #{vite_tag} \"inertia\" %>"
say_error "+ <%= #{vite_tag} %>"
end
end

Expand Down Expand Up @@ -192,6 +207,8 @@ def install_vite
say_error 'Failed to install Vite Rails', :red
exit(false)
end

add_package_manager_to_bin_setup
end
end
end
Expand Down Expand Up @@ -258,11 +275,13 @@ def typescript?
end

def inertia_entrypoint
"inertia.#{typescript? ? 'ts' : 'js'}"
"inertia.#{typescript? ? 'ts' : 'js'}#{'x' if react?}"
end

def vite_tag
typescript? ? 'vite_typescript_tag' : 'vite_javascript_tag'
tag = typescript? ? 'vite_typescript_tag' : 'vite_javascript_tag'
filename = "\"#{react? ? inertia_entrypoint : 'inertia'}\""
"#{tag} #{filename}"
end

def inertia_resolved_version
Expand All @@ -280,6 +299,10 @@ def svelte?
framework.start_with? 'svelte'
end

def react?
framework.start_with? 'react'
end

def inertia_package
"#{FRAMEWORKS[framework]['inertia_package']}@#{options[:inertia_version]}"
end
Expand All @@ -288,6 +311,26 @@ def framework
@framework ||= options[:framework] || ask('What framework do you want to use with Inertia?', :green,
limited_to: FRAMEWORKS.keys, default: 'react')
end

def add_package_manager_to_bin_setup
setup_file = file_path('bin/setup')
return unless File.exist?(setup_file)

content = File.read(setup_file)
pm_name = package_manager.name

# Check if package manager install already exists
return if content.include?("#{pm_name} install")

if content.match?(/system\('bundle check'\) \|\| system!\('bundle install'\)/)
say 'Adding package manager install to bin/setup'
cmd = "system! '#{pm_name} install'"
insert_into_file setup_file, " #{cmd}\n",
after: /system\('bundle check'\) \|\| system!\('bundle install'\)\n/
else
say_status "Couldn't add `#{cmd}` script to bin/setup, add it manually", :red
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable cmd is referenced in the error message but is never defined in the scope. It should be defined before the conditional check, e.g., cmd = "#{pm_name} install" before line 311.

Copilot uses AI. Check for mistakes.
end
end
end
end
end
12 changes: 6 additions & 6 deletions lib/generators/inertia/install/js_package_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ def initialize(generator)
end

def present?
package_manager.present?
name.present?
end

def add_dependencies(*dependencies)
options = @generator.options[:verbose] ? '' : ' --silent'
@generator.in_root do
@generator.run "#{package_manager} add #{dependencies.join(' ')}#{options}"
@generator.run "#{name} add #{dependencies.join(' ')}#{options}"
end
end

private

def package_manager
@package_manager ||= @generator.options[:package_manager] || detect_package_manager
def name
@name ||= @generator.options[:package_manager] || detect_package_manager
end

private

def detect_package_manager
return nil unless file?('package.json')

Expand Down
6 changes: 2 additions & 4 deletions lib/generators/inertia/install/templates/controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# frozen_string_literal: true

class InertiaExampleController < ApplicationController
class InertiaExampleController < InertiaController
def index
render inertia: 'InertiaExample', props: {
name: params.fetch(:name, 'World'),
}
render inertia: { name: params.fetch(:name, 'World') }
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The render inertia: syntax is incorrect. It should be render inertia: 'inertia_example/index', props: { ... }. The current syntax render inertia: { name: ... } is missing the component name and will not work properly.

Suggested change
render inertia: { name: params.fetch(:name, 'World') }
render inertia: 'inertia_example/index', props: { name: params.fetch(:name, 'World') }

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

little does copilot know, this was part of the goal!

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

class InertiaController < ApplicationController
inertia_share flash: -> { flash.to_hash }
end
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import inertiaSvg from '/assets/inertia.svg'
import reactSvg from '/assets/react.svg'
import viteRubySvg from '/assets/vite_ruby.svg'

import cs from './InertiaExample.module.css'
import cs from './index.module.css'

export default function InertiaExample({ name }) {
const [count, setCount] = useState(0)
Expand Down Expand Up @@ -47,7 +47,7 @@ export default function InertiaExample({ name }) {
count is {count}
</button>
<p>
Edit <code>app/frontend/pages/InertiaExample.jsx</code> and save to
Edit <code>app/frontend/pages/inertia_example/index.jsx</code> and save to
test HMR
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import inertiaSvg from '/assets/inertia.svg'
import reactSvg from '/assets/react.svg'
import viteRubySvg from '/assets/vite_ruby.svg'

import cs from './InertiaExample.module.css'
import cs from './index.module.css'

export default function InertiaExample({ name }: { name: string }) {
const [count, setCount] = useState(0)
Expand Down Expand Up @@ -47,7 +47,7 @@ export default function InertiaExample({ name }: { name: string }) {
count is {count}
</button>
<p>
Edit <code>app/frontend/pages/InertiaExample.jsx</code> and save to
Edit <code>app/frontend/pages/inertia_example/index.tsx</code> and save to
test HMR
</p>
</div>
Expand Down
45 changes: 0 additions & 45 deletions lib/generators/inertia/install/templates/react/inertia.js

This file was deleted.

Loading