inertia-coder について
inertia-coderは、RailsバックエンドとReact、Vue、Svelteを組み合わせたInertia.jsのシングルページアプリ開発を支援するスキルです。セットアップ、ページコンポーネント、フォーム、共有プロパティ、ファイルアップロードを扱い、サーバー側ルーティングを活用します。
主な機能
- 01RailsとInertia.jsのセットアップ
- 02React、Vue、Svelteのページパターン
- 03useFormによるフォーム処理
- 04共有プロパティとフラッシュメッセージ
- 05進捗表示付きファイルアップロード
活用シーン
- 01Inertia.jsとRailsのアプリ構築
- 02サーバー提供のプロパティによるページ作成
- 03フォームとファイルアップロードの処理
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill inertia-coderインストール後、Claude Code で/inertia-coderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/react-patterns.mdsvelte-patterns.mdvue-patterns.md詳細
Inertia.js + Rails
Inertia.js と Rails バックエンドを使用して、モダンなシングルページアプリケーションを構築します。
このスキルを使う場面
- Rails で Inertia.js をセットアップする
- Inertia のページコンポーネントを作成する
- useForm フックでフォームを処理する
- 共有プロップとフラッシュメッセージを管理する
- API の複雑さを避けてクライアント側ルーティングを行う
- 進行状況を追跡しながらファイルをアップロードする
Inertia.js とは?
Inertia.js を使うと、従来のサーバーサイドルーティングとコントローラーを使用して SPA を構築できます。
| アプローチ | メリット | デメリット |
|---|---|---|
| 従来の Rails ビュー | シンプルで、サーバー側でレンダリングされる | インタラクティブ性に制限がある |
| Rails API + React SPA | 完全な SPA 体験 | ルーティングの重複、複雑な状態管理 |
| Inertia.js | SPA + サーバールーティング | 両方の利点を兼ね備える |
クイックセットアップ
# 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
コントローラーパターン
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 ページコンポーネント
// 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>
)
}
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>}
<textarea
value={data.body}
onChange={e => setData('body', e.target.value)}
/>
{errors.body && <div className="error">{errors.body}</div>}
<button disabled={processing}>
{processing ? 'Creating...' : 'Create'}
</button>
</form>
)
}
共有レイアウト
// 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 && <div className="alert-success">{flash.success}</div>}
<main>{children}</main>
</div>
)
}
// Assign layout to page
Index.layout = page => <AppLayout>{page}</AppLayout>
ファイルアップロード
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>
ベストプラクティス
推奨事項
<a>タグの代わりに<Link>を使用する- 共通データ(認証、フラッシュメッセージ)を config 経由で共有する
- サーバー側で検証する。クライアント側は UX のみを担当する
processingを使って読み込み状態を表示する- 一貫したナビゲーションにはレイアウトを使用する
禁止事項
window.locationを使用しない。SPA が機能しなくなります- REST API を作成しない。Inertia に API は不要です
- クライアント側でデータを取得しない。サーバーがプロップを提供します
- Inertia ルーターを迂回しない。動作に支障が出ます
詳細リファレンス
フレームワーク固有のパターンについては、以下を参照してください。
references/react-patterns.md- React フック、TypeScript、高度なパターンreferences/vue-patterns.md- Vue 3 Composition API のパターンreferences/svelte-patterns.md- Svelte のストアとリアクティビティのパターン
コメント
Markdown 対応