ViewComponent/view_component · error · ViewComponent::ContentSlotNameError
COMPONENT declares a slot named content, which is a reserved
Error message
COMPONENT declares a slot named content, which is a reserved word in ViewComponent. Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor without having to create an explicit slot. To fix this issue, either use the `content` accessor directly or choose a different slot name.
What it means
Raised when a singular slot name is exactly :content (lib/view_component/slotable.rb:318-320). ViewComponent captures any block passed at the call site into the built-in content accessor, so a slot named content would collide with that accessor and make the intent ambiguous. The error tells the developer to use the content accessor directly or to pick another name.
Source
Thrown at lib/view_component/slotable.rb:319
end
slot
end
def __vc_validate_plural_slot_name(slot_name)
if RESERVED_NAMES[:plural].include?(slot_name.to_sym)
raise ReservedPluralSlotNameError.new(name, slot_name)
end
__vc_raise_if_slot_name_uncountable(slot_name)
__vc_raise_if_slot_conflicts_with_call(slot_name)
__vc_raise_if_slot_ends_with_question_mark(slot_name)
__vc_raise_if_slot_registered(slot_name)
end
def __vc_validate_singular_slot_name(slot_name)
if slot_name.to_sym == :content
raise ContentSlotNameError.new(name)
end
if RESERVED_NAMES[:singular].include?(slot_name.to_sym)
raise ReservedSingularSlotNameError.new(name, slot_name)
end
__vc_raise_if_slot_conflicts_with_call(slot_name)
__vc_raise_if_slot_ends_with_question_mark(slot_name)
__vc_raise_if_slot_registered(slot_name)
end
def __vc_raise_if_slot_registered(slot_name)
if registered_slots.key?(slot_name)
raise RedefinedSlotError.new(name, slot_name)
end
end
def __vc_raise_if_slot_ends_with_question_mark(slot_name)View on GitHub (pinned to 9f22c36fa7)
Solutions
- Rename the slot to describe what it holds, for example :body, :summary or :description
- Drop the slot and rely on the built-in content accessor: pass a block at the call site and read content in the template
- Use content.present? in the template when the component needs optional content with a fallback
Example fix
# before class PanelComponent < ViewComponent::Base renders_one :content # raises ContentSlotNameError end # after class PanelComponent < ViewComponent::Base renders_one :body end # template reads body, or the built-in content accessor
Defensive patterns
Strategy: validation
Validate before calling
def slot_name_available?(name) name.to_sym != :content end slot_name_available?(:content) # => false
Try / catch
# config-driven registration only begin renders_one(dynamic_name.to_sym) rescue ViewComponent::ContentSlotNameError dynamic_name = :body retry end
Prevention
- Treat content as taken: block content already arrives through the content accessor
- Prefer concrete names such as :body or :summary for optional content areas
- Remember that renders_many :content also fails here because its singular form is content
When it happens
Trigger: renders_one :content, and renders_many :content, whose singularized form is also :content and is validated at lib/view_component/slotable.rb:151. renders_many :contents instead hits the plural reserved list first and raises ReservedPluralSlotNameError.
Common situations: An optional rich text area named content; components migrated from partials that had a content local; developers combining a content slot with the with_content helper, which is exactly the overlap the framework prevents.
Related errors
- COMPONENT declares a slot named SLOT_NAME, which is a reserv
- A method called 'SETTER_METHOD_NAME' already exists and woul
- COMPONENT declares the SLOT_NAME slot multiple times. To fi
- COMPONENT declares a slot named SLOT_NAME, which ends with a
- Slot cannot start with 'call_'. Please rename #{slot_name}
AI-assisted analysis of ViewComponent/view_component@9f22c36fa7 (2026-08-23).
Data as JSON: /api/errors/a012a6fabc2951f7.
Report an issue: GitHub.