When to Use call, erb_template, or html.erb in Rails ViewComponents?

ViewComponent has multiple methods to render ERB (or Slim) and HTML. Initially, when ViewComponent was released, there were two options, a:

  • separate html.erb file, and;
  • call method.

But since v3.0 there is another strategy you can use: erb_template. It essentially works the same as the call method, but also allows ERB or plain HTML. The goal for both call and erb_template is to eliminate an extra file. Keeping your component to one file only. Tidy and neat!

The three different rendering strategies

Let’s go over how each one works and then I give some guidelines to help you choose.

erb.html

This is the default way where the template is defined in a separate .html.erb file located in the same directory as the component class. In this file you can write any ERB or HTML you need.

# app/components/example_component.html.erb
<h1>Hello, <%= @name %>!</h1>

call

The call method can be used to write the rendering logic directly in Ruby component file. It’s the option that can render HTML using Rails’ ActionView content_tag or tag helpers or any other Ruby code.

# app/components/example_component.rb
class ExampleComponent < BaseComponent
  def initialize(name:)
    @name = name
  end

  def call
    content_tag(:h1, "Hello, #{@name}")
  end
end

erb_template

You can view the erb_template strategy as a merge of the above two strategies. You can write the same HTML + ERB as with html.erb file.

# app/components/example_component.rb
class ExampleComponent < BaseComponent
  def initialize(name:)
    @name = name
  end

  erb_template <<~ERB
    <h1>Hello, <%= @name %>!</h1>
  ERB
end

See that weird-looking <<~ERB? In Ruby it is called a “squiggly heredoc” and it allows for writing multi-line strings with automatic indentation removal.

You can of course also use other templating engines, Slim for example. That would look like this:

  # …
  slim_template <<~SLIM
    <h1>Hello, <%= @name %>!</h1>
  SLIM
  # …

Which strategy to use?

So which strategy to use when? Over the few years of writing ViewComponent and building a UI Components library with it, I’ve build up some best practices when to use which strategy.

I use this as a guideline (as always with guidelines, change when it makes sense based on the context).

  1. one line of content, eg. content_tag(:h1, "Hello, #{@name}") use call;
  2. between 2 and 11 lines; use erb_template;
  3. more than 12 lines; use html.erb.

Where do I get these numbers from? Besides number 1, pretty much out of thin air. The rationale is that anything beyond 10 lines makes the component file feel more cluttered. Tucking it away in another file helps here (if you can’t see it, it isn’t there!). The reality is that I nowadays (since the introduction of erb_template) mostly use that strategy.

Your mileage may vary. Maybe you choose a range between 2 and 19. Fine by me! Agree on a number between yourself/your team and use that as a guideline. But having a guideline give you something to reason about.

Anything I overlooked? Something different you use? Let me know.

Get UI & Product Engineering Insights for Rails Apps (and product updates!)

Published at . Last updated at . Have suggestions or improvements on this content? Do reach out.

UI components for Ruby on Rails apps

$ 129 one-time
payment

Get Access
  • One-time Payment

  • Access to the Entire Library

  • Built using ViewComponent

  • Designed with Tailwind CSS

  • Enhanced with Hotwire