1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
---
layout: default
title: Getting started
parent: How-to guide
nav_order: 1
---
# Getting started
## Conventions
- Components are subclasses of `ViewComponent::Base` and live in `app/components`. It's common practice to create and inherit from an `ApplicationComponent` that's a subclass of `ViewComponent::Base`.
- Component names end in -`Component`.
- Component module names are plural, as for controllers and jobs: `Users::AvatarComponent`
- Name components for what they render, not what they accept. (`AvatarComponent` instead of `UserComponent`)
## Installation
In `Gemfile`, add:
```ruby
gem "view_component"
```
## Quick start
Use the component generator to create a new ViewComponent.
The generator accepts a component name and a list of arguments:
```console
bin/rails generate component Example title
invoke test_unit
create test/components/example_component_test.rb
create app/components/example_component.rb
create app/components/example_component.html.erb
```
Available options to customize the generator are documented on the [Generators](/guide/generators.html) page.
## Implementation
A ViewComponent is a Ruby file and corresponding template file with the same base name:
```ruby
# app/components/example_component.rb
class ExampleComponent < ViewComponent::Base
def initialize(title:)
@title = title
end
end
```
```erb
<%# app/components/example_component.html.erb %>
<span title="<%= @title %>"><%= content %></span>
```
Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor.
Rendered in a view as:
```erb
<%# app/views/home/index.html.erb %>
<%= render(ExampleComponent.new(title: "my title")) do %>
Hello, World!
<% end %>
```
Returning:
```html
<span title="my title">Hello, World!</span>
```
## `#with_content`
Since 2.31.0
{: .label }
String content can also be passed to a ViewComponent by calling `#with_content`:
```erb
<%# app/views/home/index.html.erb %>
<%= render(ExampleComponent.new(title: "my title").with_content("Hello, World!")) %>
```
## Rendering from controllers
It's also possible to render ViewComponents in controllers:
```ruby
# app/controllers/home_controller.rb
def show
render(ExampleComponent.new(title: "My Title"))
end
```
_Note: Content can't be passed to a component via a block in controllers. Instead, use `with_content`. In versions of Rails < 6.1, rendering a ViewComponent from a controller doesn't include the layout._
When using turbo frames with [turbo-rails](https://github.com/hotwired/turbo-rails), set `content_type` as `text/html`:
```ruby
# app/controllers/home_controller.rb
def create
render(ExampleComponent.new, content_type: "text/html")
end
```
### Rendering ViewComponents to strings inside controller actions
When rendering the same component multiple times for later reuse, use `render_in`:
```rb
class PagesController < ApplicationController
def index
# Doesn't work: triggers a `AbstractController::DoubleRenderError`
# @reusable_icon = render IconComponent.new('close')
# Doesn't work: renders the whole index view as a string
# @reusable_icon = render_to_string IconComponent.new('close')
# Works: renders the component as a string
@reusable_icon = IconComponent.new('close').render_in(view_context)
end
```
|