ERB

Added in v1.8 · Updated March 13, 2026 · Modules
ruby stdlib erb templates

The ERB module provides a templating system that lets you embed Ruby code within text documents. It’s widely used in Rails views, configuration templates, and any scenario where you need to generate dynamic text from static content mixed with Ruby logic.

Overview

ERB stands for “Embedded Ruby”. It allows you to insert Ruby expressions and statements into plain text files, which are then processed to produce final output with the Ruby code executed:

  • <%= ... %> — Evaluates the expression and outputs the result
  • <% ... %> — Evaluates the expression without output
  • <%# ... %> — Comments (not included in output)

Loading ERB

require 'erb'

Basic Usage

Simple Interpolation

require 'erb'

template = "Hello, <%= name %>!"
result = ERB.new(template).result(binding)
# Assuming name = "World" => "Hello, World!"

Using a Hash

require 'erb'

template = "Welcome to <%= place[:name] %>!"
binding_data = template, { place: { name: "RubyLand" } }
result = ERB.new(template).result_with_hash(place: { name: "RubyLand" })
# => "Welcome to RubyLand!"

Template Files

require 'erb'

# Read from file
template = File.read('page.html.erb')
renderer = ERB.new(template)
output = renderer.result(binding)
File.write('page.html', output)

ERB Tags

Output Tag <%= %>

The equals tag evaluates Ruby and inserts the result into the output:

template = <<~ERB
  <h1><%= title %></h1>
  <p>You have <%= items.count %> items</p>
ERB

ERB.new(template).result_with_hash(title: "My Page", items: [1,2,3])
# => <h1>My Page</h1>
# => <p>You have 3 items</p>

Expression Tag <% %>

Without the equals sign, code runs but nothing is output:

template = <<~ERB
  <% items.each do |item| %>
    <li><%= item %></li>
  <% end %>
ERB

ERB.new(template).result_with_hash(items: ["apple", "banana"])
# => <li>apple</li>
# => <li>banana</li>

Comment Tag <%# %>

Comments are stripped from output:

template = "<%# This is ignored %><%= 1 + 1 %>"
ERB.new(template).result
# => "2"

Suppressing Newlines

Append - to close tags to trim surrounding whitespace:

template = <<~ERB
  <% items.each do |item| -%>
    <li><%= item %></li>
  <% end -%>
ERB

This prevents extra blank lines in the output.

ERB Methods

ERB.new(template, safe_level = nil, trim_mode = nil)

Creates a new ERB template object.

ParameterTypeDefaultDescription
templateStringRequiredThe ERB template string
safe_levelIntegernilSecurity level (deprecated in Ruby 3.0+)
trim_modeStringnilTrim mode configuration

Trim Modes

# Default: no trimming
ERB.new(template, trim_mode: nil)

# Remove leading whitespace before %> (common)
ERB.new(template, trim_mode: '-')

# Remove whitespace around ERB tags
ERB.new(template, trim_mode: '<>')

# Combine: trim before and around tags
ERB.new(template, trim_mode: '-<>')

Common trim mode behaviors:

  • '-' — Strips whitespace before -%> and newline after
  • '<>' — Strips whitespace between <% and %> tags
  • '-<>' — Combination of both

result(binding = nil)

Renders the template with the given binding:

erb = ERB.new("Value: <%= x * 2 %>")
erb.result(binding)  # Uses current binding
erb.result_with_hash(x: 5)  # Uses hash as local variables

result_with_hash(hash)

Renders template with a hash as local variables:

erb = ERB.new("Hello <%= name %>!")
erb.result_with_hash(name: "Alice")
# => "Hello Alice!"

def method(result = nil)

Creates a method from the template:

erb = ERB.new("Hello <%= @name %>!")
erb.def_method(@template, :greeting)

template = ERBTemplate.new
template.@name = "Bob"
template.greeting  # => "Hello Bob!"

Security Considerations

Safe Levels (Ruby 2.x and earlier)

Older Ruby versions had $SAFE taint checking. This is deprecated as of Ruby 2.7 and removed in Ruby 3.0.

HTML Escaping

By default, ERB does not escape HTML. Use CGI.escapeHTML or Rails’ html_escape:

# Manual escaping
template = "<%= CGI.escapeHTML(user_input) %>"

# In Rails (automatic)
template = "<%= user_input %>"  # Automatically escaped in Rails

Code Injection

Never pass untrusted input as template code. Only allow data interpolation:

# DANGEROUS: User controls Ruby code
template = "<% #{user_input} %>"  # NEVER DO THIS

# SAFE: User controls only data values
template = "<%= user_input %>"  # User input is treated as text

Practical Examples

HTML Generation

require 'erb'

template = <<~ERB
  <!DOCTYPE html>
  <html>
  <head><title><%= title %></title></head>
  <body>
    <h1><%= heading %></h1>
    <ul>
    <% items.each do |item| %>
      <li><%= item %></li>
    <% end %>
    </ul>
  </body>
  </html>
ERB

output = ERB.new(template, trim_mode: '-').result_with_hash(
  title: "My Page",
  heading: "Welcome",
  items: ["Feature 1", "Feature 2", "Feature 3"]
)

Configuration Files

require 'erb'

config_template = <<~CONF
  database:
    host: <%= db[:host] %>
    port: <%= db[:port] %>
    username: <%= db[:user] %>
    password: <%= db[:pass] %>
CONF

config = {
  db: {
    host: "localhost",
    port: 5432,
    user: "admin",
    pass: "secret"
  }
}

File.write("config.yml", ERB.new(config_template).result_with_hash(config))

Email Templates

require 'erb'

email_template = <<~EMAIL
  From: <%= from %>
  To: <%= to %>
  Subject: <%= subject %>
  
  Hello <%= name %>,
  
  <%= body %>
  
  Best regards
EMAIL

email = ERB.new(email_template).result_with_hash(
  from: "noreply@example.com",
  to: "user@example.com",
  subject: "Welcome!",
  name: "User",
  body: "Thank you for signing up."
)

Ruby Version History

  • Ruby 1.8: Introduced ERB as part of standard library
  • Ruby 1.9: Added encoding support for templates
  • Ruby 2.7: Deprecated $SAFE and taint checking
  • Ruby 3.0: Removed safe level functionality
  • Ruby 3.2: Added result_with_hash method

See Also