--- id: inertia-rails/skills/alba-inertia version: "845e3ed7" license: MIT install: manual updated: 2026-02-13 --- # alba-inertia — Alba-Inertia pairs Alba serializers with Typelizer to generate TypeScript types automatically from your Rails models and resources. Define entity, page, and shared props resources once, then render them convention-based in controllers—no manual type declarations needed. Publisher: inertia-rails · Stars: 64 · Updated: 2026-02-13 Install (manual): `git clone https://github.com/inertia-rails/skills` ## SKILL.md # 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) ```ruby # 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 ```ruby # 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) ```ruby # 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) ```ruby # 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](https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html). ```ruby # 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: ```ruby 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: ```ruby 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: ```ruby 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`](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 | Symptom | Cause | Fix | |---------|-------|-----| | TypeScript type is all `unknown` | Missing `typelize_from` | Add `typelize_from ModelName` when resource name doesn't match model | | `inertia:` option has no effect | Missing helper | Ensure `helper Alba::Inertia::Resource` is in `ApplicationResource` | | Types not regenerating | Server not running | Typelizer watches files in dev only. Run `bin/rake typelizer:generate` manually | | `NoMethodError` for `typelize` | Missing helper | Ensure `helper Typelizer::DSL` is in `ApplicationResource` | | Convention-based rendering picks wrong resource | Naming mismatch | Resource must be `{Controller}{Action}Resource` (e.g., `UsersIndexResource` for `UsersController#index`) | | `to_inertia` undefined | Missing include | Controller 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) [View on SkillFed](https://skillfed.io/inertia-rails/skills/alba-inertia) · [View on GitHub](https://github.com/inertia-rails/skills)