ViewComponent Installation
Install components using GitHub's ViewComponent library for encapsulated, testable UI.
Overview
ViewComponent is a framework for building reusable, testable, and encapsulated view components in Ruby on Rails. Components are Ruby classes with associated templates, providing better organization and type safety.
Benefits
- Encapsulation — Logic and presentation in one place
- Testability — Unit test components in isolation
- Type safety — Define explicit interfaces with typed parameters
- Performance — Built-in template caching and precompilation
Setup
If you haven't already, add the ViewComponent gem to your application:
gem "view_component"
Then install the gem:
bundle install
ViewComponent works out of the box with Rails 6.1+. For additional configuration options, see the official documentation.
Project Structure
ViewComponent components live in app/components/:
app/
├── components/
│ ├── dropdown_component.rb # Ruby class
│ ├── dropdown_component.html.erb # Template
│ ├── modal_component.rb
│ ├── modal_component.html.erb
│ └── ...
└── javascript/
└── controllers/
├── dropdown_controller.js # Stimulus controller
├── modal_controller.js
└── ...
Each component consists of a Ruby class (defining the interface) and an ERB template (the HTML structure). Stimulus controllers are still used for JavaScript interactivity.
Installing Components
Create the components directory
mkdir -p app/components
Copy the Ruby class
From the component page, copy the _component.rb file to
app/components/component_name_component.rb.
Copy the template
Copy the .html.erb template to
app/components/component_name_component.html.erb.
Copy the Stimulus controller
If the component has JavaScript behavior, copy the controller to
app/javascript/controllers/.
Usage Example
Render ViewComponents using the render helper with a component instance:
<%# Render the dropdown component %>
<%= render DropdownComponent.new(
label: "Options",
items: [
{ label: "Edit", href: edit_path(@item) },
{ label: "Delete", href: @item, method: :delete }
]
) %>
With Slots
Some components use ViewComponent slots for flexible content composition:
<%= render ModalComponent.new(title: "Confirm Action") do |modal| %>
<% modal.with_body do %>
<p>Are you sure you want to proceed?</p>
<% end %>
<% modal.with_footer do %>
<button class="btn-secondary">Cancel</button>
<button class="btn-primary">Confirm</button>
<% end %>
<% end %>
Check each component's documentation for the available parameters and slot options.