Rails 7 has been released and Webpacker is being phased out.
And if you're anything like me and prefer to use HMR and component frameworks over Hotwire and importmaps, you might want to look for a Webpacker alternative now. I found Vite Ruby to be a capable replacement, which also (supposedly) makes your development flow more faster™.
So let's take a look at how to set up a new Rails 7 app using my favorite frameworks out there (Inertia and Svelte) and bundle it all up with Vite.
Let's go
Start off by initializing a new Rails 7 app without Javascript and asset pipeline:
rails new app --skip-javascript --skip-asset-pipeline
Once this is done, add the inertia_rails
and vite_rails
gems:
bundle add inertia_rails
bundle add vite_rails
The vite_rails
gem adds an installer to your project. Run it with
bundle exec vite install
This generates default vite config files, a frontend
directory, and also updates your layout file to include the vite bundle. It will also setup our initial package.json. We'll need more packages. Add them:
npm install -D axios svelte @sveltejs/vite-plugin-svelte @inertiajs/svelte
IMPORTANT UPDATE:
Since vite-plugin-svelte version 2.0, it is required that your package.json contains"type": "module"
. You will have to add this manually if it doesn't already.
Then find application.js
in our new app/frontend/entrypoints
directory and replace its contents with:
import axios from 'axios'
import { createInertiaApp } from '@inertiajs/svelte'
const pages = import.meta.glob('../pages/**/*.svelte')
const csrfToken = document.querySelector('meta[name=csrf-token]').content
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
createInertiaApp({
resolve: name => pages[`../pages/${name}.svelte`](),
setup({ el, App, props }) {
new App({ target: el, props })
},
})
Next, open up your vite.config.ts
file and change it like so:
import { defineConfig } from 'vite'
import RubyPlugin from 'vite-plugin-ruby'
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
resolve: {
dedupe: ['axios']
},
plugins: [
RubyPlugin(),
svelte()
]
})
This config file ensures that axios is only included once in your bundle, and Inertia and your own imports will actually resolve to the same axios.
Now you can place your Inertia page components into app/frontend/pages
, start your rails server with rails s
, the dev server with ./bin/vite dev
, and it should all work as usual.
Bonus: Persistent Layouts
In the example above you might have noticed the lack of a persistent layout - a parent component that won't change upon navigation. To add a persistent layout, update your application.js
like this:
import axios from 'axios'
import Layout from '../pages/_layout.svelte'
import { createInertiaApp } from '@inertiajs/svelte'
const pages = import.meta.glob('../pages/**/*.svelte')
const csrfToken = document.querySelector('meta[name=csrf-token]').content
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken
createInertiaApp({
resolve: async name => {
const page = await pages[`../pages/${name}.svelte`]()
return Object.assign({layout: Layout}, page)
},
setup({ el, App, props }) {
new App({ target: el, props })
},
})
Now you can use persistent layouts with Inertia and Vite.
Happy coding 😊
Top comments (9)
Thanks – great article! For anyone else new to Rails like me who gets stuck rendering their first Svelte view after following the article here, create/edit these files:
(Feedback appreciated. I don't know if this is the standard "Rails way" or not.)
The component file names are case-sensitive. Try
render inertia: 'home'
This is an excellent article that I used as the starting project for my side project. I found I needed to tweak the
vite.config.ts
file:that's a nice tip, thanks
Thanks for posting this, I will start a new project and this setup is great
Awesome article! Just used this to get an app up and running in ~10 mins, love using this stack honestly.
Thanks, great article.
Had trouble how to access variables from Server, what i missed: i had to export the variable from the javascript, so the code is:
Controller (see: inertia docs)
Svelte (see: svelte docs)
I had to combine the old ujs and i'm using Hotwired on Vite. Here's how i integreated it all together: Setup Vite, Svelte, Inertia, Stimulus, Bootstrap / Foundation on Rails-7. On the parts Svelte and Inertia it references back to this Tutorial.
I visited your browser-based game link. LOL, very creative name. XD