Loading...
Loading...
Alba serializers + Typelizer for type-safe Inertia Rails props with auto-generated TypeScript types. Use when serializing models for Inertia responses, setting up Alba resources, generating TypeScript types from Ruby, or using Inertia prop options (defer, once, merge, scroll) with Alba attributes. Replaces as_json with structured, auto-typed ApplicationResource, page resources, and shared props resources. When active, OVERRIDES the `render inertia: { ... }` pattern from other skills — use convention-based instance variable rendering instead.
npx skill4agent add inertia-rails/skills alba-inertiaalbatypelizeralba-inertiaas_json(only: [...])UserResourceUsersIndexResourceSharedPropsResourceas_jsontypelize_fromunknowndeclare moduleserializers/index.tsserializers/index.tsglobals.d.ts# 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# app/controllers/inertia_controller.rb
class InertiaController < ApplicationController
include Alba::Inertia::Controller
inertia_share { SharedPropsResource.new(self).to_inertia }
end# 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# 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# 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 } }
endAlba::Inertia::Controllerclass 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
endtypelize_fromclass 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
endbin/rake typelizer:generateinertia:InertiaRailsattribute :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.alwaysmatch_onreferences/prop-options.mdinertia:inertia_propinertia: :deferinertia: :optionalinertia: :once| Symptom | Cause | Fix |
|---|---|---|
TypeScript type is all | Missing | Add |
| Missing helper | Ensure |
| Types not regenerating | Server not running | Typelizer watches files in dev only. Run |
| Missing helper | Ensure |
| Convention-based rendering picks wrong resource | Naming mismatch | Resource must be |
| Missing include | Controller needs |
inertia-rails-controllersinertia-rails-typescript