May 20, 2025
As Rails applications grow in size and complexity, maintaining views can become challenging. Traditional partials and helpers often lead to scattered logic, reduced testability, and hard-to-maintain code. This is where ViewComponent—a gem developed by GitHub—comes in to bring structure and object-oriented design to your views.
Need help with your Ruby on Rails project? Let’s get in touch
What is ViewComponent?
ViewComponent is a framework for creating reusable, testable, and encapsulated view components in Ruby on Rails. It encourages writing views as Ruby objects with templates, separating presentation logic from controllers and views.
Instead of this:
<%= render "shared/alert", type: "warning", message: "Be careful!" %>
You write:
<%= render(AlertComponent.new(type: "warning")) do %>
Be careful!
<% end %>
Component Structure
A ViewComponent typically consists of two files:
- A Ruby class for logic: app/components/alert_component.rb
- An HTML/ERB template : app/components/alert_component.html.erb
Example: Alert Component
Let’s create a simple AlertComponent.
app/components/alert_component.rb
class AlertComponent < ViewComponent::Base
def initialize(type:)
@type = type
end
end
app/components/alert_component.html.erb
<div class="alert alert-<%= @type %>">
<%= content %>
</div>
Usage in a view
<%= render(AlertComponent.new(type: "success")) do %>
Your changes have been saved successfully!
<% end %>
This renders:
<%= render(AlertComponent.new(type: "success")) do %>
Your changes have been saved successfully!
<% end %>
Benefits of Using ViewComponent
- Encapsulation : Keeps logic and markup together.
- Reusability : Components can be used across multiple views or even gems.
- Testability : Easily test components in isolation.
- Performance : Uses compiled templates and avoids repeated partial parsing.
- Design System Friendly : Perfect for building reusable UI systems.
Testing Components
You can use RSpec or Minitest to write tests for components.
# spec/components/alert_component_spec.rb
require "rails_helper"
RSpec.describe AlertComponent, type: :component do
it "renders the alert message" do
render_inline(AlertComponent.new(type: "danger")) { "This is dangerous!" }
expect(rendered_content).to include("alert-danger")
expect(rendered_content).to include("This is dangerous!")
end
end
Advanced: Slots
Slots allow you to define named content areas.
class CardComponent < ViewComponent::Base
renders_one :header
renders_one :footer
end
<%= render(CardComponent.new) do |c| %>
<% c.header { "Title" } %>
This is the card content.
<% c.footer { "Footer info" } %>
<% end %>
Setup in Rails
To install:
bundle add view_component
Then add to config/application.rb:
config.view_component.generate_sidecar = true
Or run:
rails generate component Alert type
Great for Design Systems
If you’re working on a design system, ViewComponent is a powerful ally. It encourages small, focused components that follow the single-responsibility principle and can be styled consistently.
Conclusion
ViewComponent offers a modern, component-based approach to building Rails views. It’s ideal for teams looking for better structure, testability, and maintainability in their front-end code.
Top comments (0)