Skip to content

[Turbo] Add <turbo-mercure-stream-source> custom element#3505

Open
seb-jean wants to merge 1 commit intosymfony:3.xfrom
seb-jean:improving-turbo-stream-sources-listeners
Open

[Turbo] Add <turbo-mercure-stream-source> custom element#3505
seb-jean wants to merge 1 commit intosymfony:3.xfrom
seb-jean:improving-turbo-stream-sources-listeners

Conversation

@seb-jean
Copy link
Copy Markdown
Contributor

Q A
Bug fix? no
New feature? yes
Deprecations? yes
Documentation? yes
Issues Fix #2460
License MIT

Summary

This PR introduces a native HTML custom element <turbo-mercure-stream-source> to replace the mercure-turbo-stream Stimulus controller for subscribing to Mercure topics and receiving Turbo Stream updates.

What's new

  • <turbo-mercure-stream-source> custom element (mercure_stream_source_element.js): manages the EventSource lifecycle (connect, disconnect, reconnect on attribute change) and sets a connected attribute when the SSE connection is established
  • StreamSourceUrlGenerator interface: decouples URL generation from rendering, making custom transports easier to implement
  • MercureStreamSourceUrlGenerator: Mercure implementation, delegates authorization cookie handling to the Mercure Bundle for private topics
  • turbo_stream_from() Twig function and <twig:Turbo:Stream:From> Twig component: the new way to subscribe to Mercure topics in templates
{# Before #}
<div id="books" {{ turbo_stream_listen('App\\Entity\\Book') }}></div>
{# After - Twig component #}
<twig:Turbo:Stream:From topics="App\\Entity\\Book" />
<div id="books"></div>
{# After - Twig function #}
{{ turbo_stream_from('App\\Entity\\Book') }}
<div id="books"></div>
{# Private topic #}
<twig:Turbo:Stream:From topics="App\\Entity\\Book" private />
{{ turbo_stream_from('App\\Entity\\Book', private=true) }}
{# Specific transport #}
<twig:Turbo:Stream:From topics="App\\Entity\\Book" transport="hub2" />
{{ turbo_stream_from('App\\Entity\\Book', transport='hub2') }}
{# Multiple topics #}
<twig:Turbo:Stream:From :topics="['topic_a', 'topic_b']" />
{{ turbo_stream_from(['topic_a', 'topic_b']) }}

Deprecations

  • turbo_stream_listen() Twig function → use turbo_stream_from() or <twig:Turbo:Stream:From>
  • TurboStreamListenRendererInterface → implement StreamSourceUrlGenerator instead
  • TurboStreamListenRenderer → use MercureStreamSourceUrlGenerator
  • TopicSet
  • mercure-turbo-stream Stimulus controller → replaced by the <turbo-mercure-stream-source> custom element, auto-imported via turbo-core

Thanks to @smnandre for opening issue #2460, which inspired this PR. 🙏

@carsonbot carsonbot added Deprecation Documentation Improvements or additions to documentation Feature New Feature Turbo Status: Needs Review Needs to be reviewed labels Apr 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 26, 2026

📊 Packages dist files size difference

Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.
Please review the changes and make sure they are expected.

FileBefore (Size / Gzip)After (Size / Gzip)
Turbo
mercure_stream_source_element.d.ts Added 11 B / 66 B
mercure_stream_source_element.js Added 963 B / 427 B
turbo_stream_controller.js 1.11 kB / 545 B 1.47 kB+32% 📈 / 721 B+32% 📈

@seb-jean seb-jean force-pushed the improving-turbo-stream-sources-listeners branch 4 times, most recently from 7a0d85f to eb0b865 Compare April 26, 2026 13:03
Comment thread apps/e2e/templates/ux_turbo/broadcast/artist.html.twig
Copy link
Copy Markdown
Member

@Kocal Kocal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few (and maybe stupid) comments, I don't have such experience with UX Turbo, I trust you here 🤞🏻

Comment thread bin/build_package.ts Outdated
Comment thread src/Turbo/assets/dist/turbo_stream_controller.js Outdated
Comment thread src/Turbo/doc/index.rst
Comment thread src/Turbo/src/StreamSourceUrlGenerator.php Outdated
Comment thread src/Turbo/src/Twig/TurboRuntime.php Outdated
Comment thread src/Turbo/doc/index.rst
Comment thread src/Turbo/src/Bridge/Mercure/MercureStreamSourceUrlGenerator.php Outdated
Comment thread src/Turbo/src/Bridge/Mercure/MercureStreamSourceUrlGenerator.php Outdated
Comment thread src/Turbo/src/Bridge/Mercure/TopicSet.php Outdated
Comment thread src/Turbo/src/DependencyInjection/TurboExtension.php Outdated
Comment thread src/Turbo/src/Twig/TurboRuntime.php Outdated
*/
public function renderTurboStreamListen(Environment $env, $topic, ?string $transport = null, array $options = []): string
{
trigger_deprecation('symfony/ux-turbo', '3.0', 'The "%s()" method is deprecated since Symfony UX 3.0, use "%s()" or the <twig:Turbo:Stream:From> Twig component instead. It will be removed in 4.0.', __METHOD__, __CLASS__.'::renderTurboStreamFrom');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK there is no need to add both @deprecated and trigger_deprecation(), you must only use @deprecated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Symfony conventions require both @deprecated and trigger_deprecation(): https://symfony.com/doc/current/contributing/code/conventions.html#deprecating-code

Copy link
Copy Markdown
Member

@Kocal Kocal May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where it requires to have both @deprecated and trigger_deprecation() on the same method, it only show an example about deprecating a whole class 🤔

But it looks like you're right, I found one example on current Symfony version: https://github.com/symfony/symfony/blob/8e8f87c6fa5f47a431fc2f49bdbe601f6769e19d/src/Symfony/Component/Serializer/Exception/PartialDenormalizationException.php#L47-L52

Maybe our documentation could be improved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, the documentation refers to both classes and methods. But as you pointed out, the documentation isn't very clear.
I think that with the example you cited, we can be sure we can include both.

Comment thread src/Turbo/doc/index.rst Outdated
Comment thread src/Turbo/doc/index.rst Outdated
Comment thread src/Turbo/src/Bridge/Mercure/TurboStreamListenRenderer.php Outdated
@seb-jean seb-jean force-pushed the improving-turbo-stream-sources-listeners branch 4 times, most recently from f3fdefa to 6d0c62e Compare May 3, 2026 14:12
@seb-jean
Copy link
Copy Markdown
Contributor Author

seb-jean commented May 3, 2026

I'm getting an error related to the .doctor-rst.yaml file.

src/Turbo/doc/index.rst ✘

722: You are not allowed to use version "3.1". Only major version "2" is allowed.

-> .. deprecated:: 3.1

Should I modify src/Turbo/doc/index.rst to remove .. deprecated:: 3.1, or should I modify the .doctor-rst.yaml file?

@Kocal
Copy link
Copy Markdown
Member

Kocal commented May 3, 2026

Following @MrYamous's work in #3493, I think we must update the following rules:

    deprecated_directive_major_version:
        major_version: 3
    deprecated_directive_min_version:
        min_version: '3.0'

Kocal added a commit that referenced this pull request May 5, 2026
This PR was merged into the 3.x branch.

Discussion
----------

 Remove old "deprecated: 2.x" directives

| Q              | A
| -------------- | ---
| Bug fix?       | no
| New feature?   | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations?  | yes <!-- if yes, also update UPGRADE-*.md and src/**/CHANGELOG.md -->
| Documentation? | yes <!-- required for new features, or documentation updates -->
| Issues         |
| License        | MIT

Update doctor rst config and documentation for 3.x

Related to #3505 (comment)

Commits
-------

58d8b5e Remove old "deprecated: 2.x" directives
@Kocal
Copy link
Copy Markdown
Member

Kocal commented May 5, 2026

I just merged #3515, you can rebase this one 🙏🏻

@seb-jean seb-jean force-pushed the improving-turbo-stream-sources-listeners branch from 6d0c62e to 11c3b95 Compare May 5, 2026 08:45
@seb-jean
Copy link
Copy Markdown
Contributor Author

seb-jean commented May 5, 2026

I just rebased

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Deprecation Documentation Improvements or additions to documentation Feature New Feature Status: Needs Review Needs to be reviewed Turbo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Turbo] Improving Turbo Stream Sources and Listeners (proposal)

3 participants