Skip to content

ApplicationController.render(component, layout: nil) ignores layout option in ActionCable broadcast context #2504

@thomaswitt

Description

@thomaswitt

tl;dr:

In ActionCable Context, don't use the class method ApplicationController.render(component, layout: nil). This triggers layout rendering in broadcast context and causes unexpected errors. Use the instance method instead: ApplicationController.renderer.new.render(component). This is unexpected for me

Steps to reproduce

  1. Create a ViewComponent to render in ActionCable broadcasts
  2. Use ApplicationController.render(component, layout: nil) inside a broadcast method
  3. Observe that the full application layout renders despite layout: nil

Code example:

# In a broadcast method (ActiveRecord callback, service, etc.)
def broadcast_notification(notification)
  Turbo::StreamsChannel.broadcast_prepend_to(
    stream_name,
    target: 'notification-list',
    content: ApplicationController.render(
      NotificationComponent.new(notification: notification),
      layout: nil  # ← This is ignored
    )
  )
end

Expected behavior

The component should render without the application layout, producing only the component HTML.

Actual behavior

The full layouts/application.html.erb renders around the component, causing:

  • Unexpected rendering of layout partials
  • Errors from unrelated components in the layout
  • Log output showing "Rendering layout layouts/application.html.erb"

Rails logs confirm layout rendering:
Rendering layout layouts/application.html.erb
Rendering NotificationComponent within layouts/application

Workaround

Using ApplicationController.renderer.new.render(component) works correctly:

def broadcast_notification(notification)
  Turbo::StreamsChannel.broadcast_prepend_to(
    stream_name,
    target: 'notification-list',
    content: ApplicationController.renderer.new.render(
      NotificationComponent.new(notification: notification)
    )
  )
end

This produces only component HTML without layout, as expected.

Analysis

The class method ApplicationController.render() appears to behave differently than the instance method chain ApplicationController.renderer.new.render() when called outside an HTTP request context (ActionCable broadcasts, background jobs, etc.). The layout: option isn't properly respected for ViewComponents in these contexts.

System configuration

  • Rails version: 8.1.1
  • Ruby version: 3.4.1
  • ViewComponent version: 4.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions