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 128 129 130
|
---
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 view_component: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 class that inherits from `ViewComponent::Base`:
```ruby
class ExampleComponent < ViewComponent::Base
erb_template <<-ERB
<span title="<%= @title %>"><%= content %></span>
ERB
def initialize(title:)
@title = title
end
end
```
Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor.
Rendered in a view as:
```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
<%= render(ExampleComponent.new(title: "my title").with_content("Hello, World!")) %>
```
## Rendering from controllers
It's also possible to render ViewComponents in controllers:
```ruby
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`._
When using turbo frames with [turbo-rails](https://github.com/hotwired/turbo-rails), set `content_type` as `text/html`:
```ruby
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
end
```
### Rendering ViewComponents outside of the view context
To render ViewComponents outside of the view context (such as in a background job, markdown processor, etc), instantiate a Rails controller:
```ruby
ApplicationController.new.view_context.render(MyComponent.new)
```
|