# ViewComponents not rendering with Rails stream helper?

**URL:** <https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813>\
**Category:** General\
**Created:** [December 31, 2020, 12:32pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813 "2020-12-31T12:32:47Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxveldink](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/maxveldink/32/1310_2.png) [@maxveldink](https://discuss.hotwired.dev/u/maxveldink)\
**Post date:** [December 31, 2020, 12:32pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/1 "2020-12-31T12:32:47Z")

</div>

Greetings!

I had a quick question about rendering a ViewComponent (or something that responds to `render_in`) using the `Turbo::Streams::TagBuilder` helper. From what I can tell, this should be valid code:

```
respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.prepend(:add_new_user, template: NotificationComponent.new(type: :warning, content: "Email in use"))
    end
end

```

From my understanding, this should return the NotificationComponent’s markup from `render_in` as the the content of `<template>`. Instead I’m seeing the class inspect output when this is prepended: `<notificationcomponent:0x00007fe5eca77d60></notificationcomponent:0x00007fe5eca77d60>`.

I’ve tried different keywords and for now have settled on creating a partial that renders this Component and using that. My question is am I missing something obvious here that allows you to render a component directly, or is there room to add a new `component` rendering keyword that can support this behavior in `turbo-rails`?

Thanks for any feedback or ideas!

---

<div class="post-metadata">

**Author:** ![SimonBo](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/simonbo/32/1420_2.png) [@SimonBo](https://discuss.hotwired.dev/u/SimonBo)\
**Post date:** [January 12, 2021, 1:20pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/2 "2021-01-12T13:20:08Z")

</div>

This works for ViewComponents:

`<%= turbo_stream.update "frame" do %> <%= render Component.new %> <% end %>`

---

<div class="post-metadata">

**Author:** ![maxveldink](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/maxveldink/32/1310_2.png) [@maxveldink](https://discuss.hotwired.dev/u/maxveldink)\
**Post date:** [January 12, 2021, 1:40pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/3 "2021-01-12T13:40:15Z")

</div>

That was the solution that I ended up going with for now. I might dabble and see if I can get a more direct way to render it without having to use a template file.

---

<div class="post-metadata">

**Author:** ![rguiscard](https://avatars.discourse-cdn.com/v4/letter/r/ce7236/32.png) [@rguiscard](https://discuss.hotwired.dev/u/rguiscard)\
**Post date:** [January 13, 2021, 1:12am UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/4 "2021-01-13T01:12:59Z")

</div>

I use this way to render ViewComponent in controller without the partial.:

```
s = turbo_stream.replace dom_id do
  view_context.render(MessageComponent.new(message: @message))
end
render turbo_stream: s
```

---

<div class="post-metadata">

**Author:** ![jonathanbruno](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/jonathanbruno/32/1215_2.png) [@jonathanbruno](https://discuss.hotwired.dev/u/jonathanbruno)\
**Post date:** [January 13, 2021, 3:58pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/5 "2021-01-13T15:58:15Z")

</div>

Interesting, I think the template file is a better and ‘correct’ solution

---

<div class="post-metadata">

**Author:** ![maxveldink](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/maxveldink/32/1310_2.png) [@maxveldink](https://discuss.hotwired.dev/u/maxveldink)\
**Post date:** [January 13, 2021, 4:17pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/6 "2021-01-13T16:17:33Z")

</div>

Probably so, I’m new to both ViewComponents and Turbo ( obviously 🙂 ). I was thinking that, since frames lend themselves to partial content by design, it might be cool to have a more streamlined API for rendering a component. I’m using the inline approach now and it’s working for my purposes.

---

<div class="post-metadata">

**Author:** ![CiTroNaK](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/citronak/32/1569_2.png) [@CiTroNaK](https://discuss.hotwired.dev/u/CiTroNaK)\
**Post date:** [January 31, 2021, 7:34pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/7 "2021-01-31T19:34:32Z")

</div>

you can use `render_to_string`

```auto
respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.prepend(:add_new_user, render_to_string(NotificationComponent.new(type: :warning, content: "Email in use")))
    end
end

```

---

<div class="post-metadata">

**Author:** ![kudapara](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/kudapara/32/1955_2.png) [@kudapara](https://discuss.hotwired.dev/u/kudapara)\
**Post date:** [May 10, 2021, 6:23pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/9 "2021-05-10T18:23:25Z")

</div>

I wrote an article explaining how I made View Components and Hotwire play nicely together.

> **[Making Hotwire play nice with ViewComponent](https://blog.kuda.dev/making-hotwire-play-nice-with-viewcomponent-ckoilssb40msdv9s10v139kgs?guid=none&deviceId=31ac46f2-e1ba-4ea9-a7b3-1e1c6ee0fecc)**
>
> Have you ever wondered if you could use hotwire with view\_component instead of partials. If you have, maybe tried and failed, welcome here.
> By default hotwire is made to work with partials, which is the built in way to extract 'components' in the...

---

<div class="post-metadata">

**Author:** ![pacMakaveli](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/pacmakaveli/32/2298_2.png) [@pacMakaveli](https://discuss.hotwired.dev/u/pacMakaveli)\
**Post date:** [October 19, 2021, 11:40am UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/10 "2021-10-19T11:40:07Z")

</div>

Sorry to post on an old thread, but struggling with a similar issue, google directed me here.  
Thought I’d post my solution:

```auto
render(turbo_stream: turbo_stream.replace(dom_id(@activity_feed), Provider::TrophyComponent.new(trophy: @activity_feed).render_in(view_context)))

```

---

<div class="post-metadata">

**Author:** ![yshmarov](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/yshmarov/32/2296_2.png) [@yshmarov](https://discuss.hotwired.dev/u/yshmarov)\
**Post date:** [October 26, 2021, 8:44pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/11 "2021-10-26T20:44:40Z")

</div>

Indeed, both solutions work for me:

```auto
turbo_stream.update('top-pagination', render_to_string(PaginationComponent.new(results: @results)))
turbo_stream.update('top-pagination', PaginationComponent.new(results: @results).render_in(view_context))

```

The `render_in(view_context)` feels more “correct”.

---

<div class="post-metadata">

**Author:** ![cman77](https://avatars.discourse-cdn.com/v4/letter/c/59ef9b/32.png) [@cman77](https://discuss.hotwired.dev/u/cman77)\
**Post date:** [March 23, 2023, 1:46pm UTC](https://discuss.hotwired.dev/t/viewcomponents-not-rendering-with-rails-stream-helper/1813/12 "2023-03-23T13:46:49Z")

</div>

What is the best practice for broadcasting a turbo update from inside a model using a ViewComponent? I’ve tried a few different ways but can’t seem to get it to work.
