inertia-coder

Build modern single-page applications using Inertia.js with React/Vue/Svelte and Rails backend.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "inertia-coder" with this command: npx skills add majesticlabs-dev/majestic-marketplace/majesticlabs-dev-majestic-marketplace-inertia-coder

Inertia.js + Rails

Build modern single-page applications using Inertia.js with React/Vue/Svelte and Rails backend.

When to Use This Skill

  • Setting up Inertia.js with Rails

  • Creating Inertia page components

  • Handling forms with useForm hook

  • Managing shared props and flash messages

  • Client-side routing without API complexity

  • File uploads with progress tracking

What is Inertia.js?

Inertia.js allows you to build SPAs using classic server-side routing and controllers.

Approach Pros Cons

Traditional Rails Views Simple, server-rendered Limited interactivity

Rails API + React SPA Full SPA experience Duplicated routing, complex state

Inertia.js SPA + server routing Best of both worlds

Quick Setup

Gemfile

gem 'inertia_rails' gem 'vite_rails'

bundle install rails inertia:install # Choose: React, Vue, or Svelte

config/initializers/inertia_rails.rb

InertiaRails.configure do |config| config.version = ViteRuby.digest

config.share do |controller| { auth: { user: controller.current_user&.as_json(only: [:id, :name, :email]) }, flash: controller.flash.to_hash } end end

Controller Pattern

class ArticlesController < ApplicationController def index articles = Article.published.order(created_at: :desc)

render inertia: 'Articles/Index', props: {
  articles: articles.as_json(only: [:id, :title, :excerpt])
}

end

def create @article = Article.new(article_params)

if @article.save
  redirect_to article_path(@article), notice: 'Article created'
else
  redirect_to new_article_path, inertia: { errors: @article.errors }
end

end end

React Page Component

// app/frontend/pages/Articles/Index.jsx import { Link } from '@inertiajs/react'

export default function Index({ articles }) { return ( <div> <h1>Articles</h1> {articles.map(article => ( <Link key={article.id} href={/articles/${article.id}}> <h2>{article.title}</h2> </Link> ))} </div> ) }

Forms with useForm

import { useForm } from '@inertiajs/react'

export default function New() { const { data, setData, post, processing, errors } = useForm({ title: '', body: '' })

function handleSubmit(e) { e.preventDefault() post('/articles') }

return ( <form onSubmit={handleSubmit}> <input value={data.title} onChange={e => setData('title', e.target.value)} /> {errors.title && <div className="error">{errors.title}</div>}

  &#x3C;textarea
    value={data.body}
    onChange={e => setData('body', e.target.value)}
  />
  {errors.body &#x26;&#x26; &#x3C;div className="error">{errors.body}&#x3C;/div>}

  &#x3C;button disabled={processing}>
    {processing ? 'Creating...' : 'Create'}
  &#x3C;/button>
&#x3C;/form>

) }

Shared Layout

// app/frontend/layouts/AppLayout.jsx import { Link, usePage } from '@inertiajs/react'

export default function AppLayout({ children }) { const { auth, flash } = usePage().props

return ( <div> <nav> <Link href="/">Home</Link> {auth.user ? ( <Link href="/logout" method="delete">Logout</Link> ) : ( <Link href="/login">Login</Link> )} </nav>

  {flash.success &#x26;&#x26; &#x3C;div className="alert-success">{flash.success}&#x3C;/div>}

  &#x3C;main>{children}&#x3C;/main>
&#x3C;/div>

) }

// Assign layout to page Index.layout = page => <AppLayout>{page}</AppLayout>

File Upload

import { useForm } from '@inertiajs/react'

const { data, setData, post, progress } = useForm({ avatar: null })

<input type="file" onChange={e => setData('avatar', e.target.files[0])} />

{progress && <progress value={progress.percentage} max="100" />}

<button onClick={() => post('/profile/avatar', { forceFormData: true })}> Upload </button>

Best Practices

DO

  • Use <Link> instead of <a> tags

  • Share common data via config (auth, flash)

  • Validate on server - client is UX only

  • Show loading states with processing

  • Use layouts for consistent navigation

DON'T

  • Don't use window.location

  • breaks SPA

  • Don't create REST APIs - Inertia doesn't need them

  • Don't fetch data client-side - server provides props

  • Don't bypass Inertia router - breaks behavior

Detailed References

For framework-specific patterns:

  • references/react-patterns.md

  • React hooks, TypeScript, advanced patterns

  • references/vue-patterns.md

  • Vue 3 Composition API patterns

  • references/svelte-patterns.md

  • Svelte stores and reactivity patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

google-ads-strategy

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

viral-content

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

market-research

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

free-tool-arsenal

No summary provided by upstream source.

Repository SourceNeeds Review