ViewComponents Best Practices

Guidelines for building reusable, tested, and maintainable UI components using ViewComponents in Rails.

Component Structure

Keep components small, focused, and reusable. Structure components logically and consistently:

  • Define the component class in app/components.
  • Place the corresponding template in app/components/[component_name].html.erb.
# app/components/button_component.rb
class ButtonComponent < ViewComponent::Base
  def initialize(label:, variant: :primary)
    @label = label
    @variant = variant
  end

  def button_classes
    "btn btn-#{variant}"
  end

  private

  attr_reader :label, :variant
end

Design Patterns

  • Prefer composition over inheritance. Build small, composable components.
  • Use slots for flexible layouts and reusable sections.
  • Use helper methods for encapsulated business logic.

Testing ViewComponents

Use RSpec and ViewComponent test helpers to ensure reliability and avoid regressions.

# Example ViewComponent Test
require "rails_helper"

RSpec.describe ButtonComponent, type: :component do
  it "renders the button with the correct label and style" do
    render_inline(ButtonComponent.new(label: "Submit", variant: :success))

    expect(rendered_component).to have_css("button.btn.btn-success", text: "Submit")
  end
end

Component Previews

Leverage ViewComponent::Preview for live previews of components in development.

# app/components/previews/button_component_preview.rb
class ButtonComponentPreview < ViewComponent::Preview
  def default
    render(ButtonComponent.new(label: "Default", variant: :primary))
  end

  def success_button
    render(ButtonComponent.new(label: "Success", variant: :success))
  end
end