mcpField
A
alba-inertia

alba-inertia

github.com/inertia-railsDevelopment70378 installsUpdated 37w ago
Repository

About alba-inertia

A skill guide for using Alba serializers and Typelizer with Inertia Rails. It helps developers structure Inertia props as reusable resources and generate TypeScript types from them.

Key features

  1. 01Defines entity, page, and shared-props resources
  2. 02Serializes Inertia props with Alba
  3. 03Generates TypeScript types with Typelizer
  4. 04Supports Inertia prop options such as defer and optional
  5. 05Provides convention-based controller rendering

Use cases

  1. 01Replacing untyped as_json props with structured resources
  2. 02Sharing entity data shapes across pages
  3. 03Generating TypeScript types for serialized props
  4. 04Setting Inertia prop behavior for deferred or optional data

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/inertia-rails/skills --skill alba-inertia

After installing, type/alba-inertiain Claude Code to confirm it loaded.

Bundled filesreferences/prop-options.md

Details

From the project README

Alba + Typelizer for Inertia Rails

Requires: alba, typelizer, alba-inertia gems in Gemfile.

Alba serializers for Inertia props with auto-generated TypeScript types. Replaces as_json(only: [...]) with structured, type-safe resources.

Before creating a resource, ask:

  • Reusable data shape (user, course)? → Entity resource (UserResource) — shared across pages
  • Page-specific props bundle? → Page resource (UsersIndexResource) — one per controller action
  • Global data (auth, notifications)? → Shared props resource (SharedPropsResource)

NEVER:

  • Use as_json when Alba is set up — it bypasses type generation and creates untyped props
  • Skip typelize_from when resource name differs from model — Typelizer can't infer column types and generates unknown
  • Put declare module augmentations in serializers/index.ts — Typelizer-generated types go in serializers/index.ts, manual InertiaConfig goes in globals.d.ts

Setup

ApplicationResource (all resources inherit from this)
# app/resources/application_resource.rb
class ApplicationResource
  include Alba::Resource

  helper Typelizer::DSL          # enables typelize, typelize_from
  helper Alba::Inertia::Resource # enables inertia: option on attributes

  include Rails.application.routes.url_helpers
end
Controller Integration
# app/controllers/inertia_controller.rb
class InertiaController < ApplicationController
  include Alba::Inertia::Controller

  inertia_share { SharedPropsResource.new(self).to_inertia }
end

Resource Types

Entity Resource (reusable data shape)
# app/resources/user_resource.rb
class UserResource < ApplicationResource
  typelize_from User  # needed when resource name doesn't match model

  attributes :id, :name, :email

  typelize :string?
  attribute :avatar_url do |user|
    user.avatar.attached? ? rails_blob_path(user.avatar, only_path: true) : nil
  end
end
Page Resource (page-specific props)
# app/resources/users/index_resource.rb
# Naming convention: {Controller}{Action}Resource
class UsersIndexResource < ApplicationResource
  has_many :users, resource: UserResource

  typelize :string
  attribute :search do |obj, _|
    obj.params.dig(:filters, :search)
  end
end
Shared Props Resource

Requires Rails Current attributes (e.g., Current.user) to be configured — see CurrentAttributes.

# app/resources/shared_props_resource.rb
class SharedPropsResource < ApplicationResource
  one :auth, source: proc { Current }

  attribute :unread_messages_count, inertia: { always: true } do
    Current.user&.unread_count || 0
  end

  has_many :live_now, resource: LiveSessionsResource,
    inertia: { once: { expires_in: 5.minutes } }
end

Convention-Based Rendering

With Alba::Inertia::Controller, instance variables auto-serialize:

class UsersController < InertiaController
  def index
    @users = User.all        # auto-serialized via UserResource
    @filters = filter_params  # plain data passed through
    # Auto-detects UsersIndexResource
  end

  def show
    @user = User.find(params[:id])
    # Auto-detects UsersShowResource
  end
end

Typelizer + Type Generation

typelize_from tells Typelizer which model to infer column types from — needed when resource name doesn't match model. For computed attributes, declare types explicitly:

class AuthorResource < ApplicationResource
  typelize_from User

  attributes :id, :name, :email

  typelize :string?                                  # next attribute is string | undefined
  attribute :avatar_url do |user|
    rails_storage_proxy_path(user.avatar) if user.avatar.attached?
  end

  typelize filters: "{category: number}"            # inline TS type
end

Types auto-generate when Rails server runs. Manual: bin/rake typelizer:generate.

Inertia Prop Options in Alba

The inertia: option on attributes/associations maps to InertiaRails prop types:

attribute :stats, inertia: :defer           # InertiaRails.defer
has_many :users, inertia: :optional         # InertiaRails.optional
has_many :countries, inertia: :once         # InertiaRails.once
has_many :items, inertia: { merge: true }   # InertiaRails.merge
attribute :csrf, inertia: { always: true }  # InertiaRails.always

MANDATORY — READ ENTIRE FILE when using grouped defer, merge with match_on, scroll props, or combining multiple options: references/prop-options.md (~60 lines) — full syntax for all inertia: option variants and inertia_prop alternative syntax.

Do NOT load for basic inertia: :defer, inertia: :optional, or inertia: :once — the shorthand above is sufficient.

Troubleshooting

SymptomCauseFix
TypeScript type is all unknownMissing typelize_fromAdd typelize_from ModelName when resource name doesn't match model
inertia: option has no effectMissing helperEnsure helper Alba::Inertia::Resource is in ApplicationResource
Types not regeneratingServer not runningTypelizer watches files in dev only. Run bin/rake typelizer:generate manually
NoMethodError for typelizeMissing helperEnsure helper Typelizer::DSL is in ApplicationResource
Convention-based rendering picks wrong resourceNaming mismatchResource must be {Controller}{Action}Resource (e.g., UsersIndexResource for UsersController#index)
to_inertia undefinedMissing includeController needs include Alba::Inertia::Controller

Related Skills

  • Prop types → inertia-rails-controllers (defer, once, merge, scroll)
  • TypeScript config → inertia-rails-typescript (InertiaConfig in globals.d.ts)

Comments

Markdown supported