Releases: ViewComponent/view_component
Release list
4.15.0
-
Add experimental caching support, opt-in per component via
include ViewComponent::ExperimentallyCacheable.Components have never participated in Rails' template digests, so a
<% cache %>block wrappingrender MyComponent.newwas never invalidated when the component changed (#234, open since 2020).Including the module registers the component with Rails' own
ActionView::Digestor, so fragment caches are invalidated when the component's template, Ruby class, sidecar files, superclasses, child components, or rendered partials change. This includes components and partials rendered from inline templates and#callmethods. Addingcache_oncaches the component's own rendered output, optionally guarded byif:/unless:, and.cache_digestexposes the digest for use outside a request.class MessageComponent < ViewComponent::Base include ViewComponent::ExperimentallyCacheable cache_on :message, unless: -> { message.draft? } def initialize(message:) @message = message end end
This API is experimental and may change or be removed in a non-major release. It's shipping opt-in and per-component precisely so we can iterate on it in response to real-world use. Please try it and tell us what breaks, what's missing, and what feels wrong in #234. We're especially interested in feedback on: whether
cache_onis the right shape for declaring cache keys, how the feature behaves with slots and content blocks, and whether the# Template Dependency:escape hatch is sufficient for dynamic renders. See the caching guide for details and known caveats.This work builds directly on prior art from the community. The
cache_onAPI and the case for component-local caching come from #2126 by Reegan Viljoen. The approach of integrating with Rails' digest tree rather than reimplementing it comes fromview_component-cache_digestby Godfrey Chan. The invalidation cases it's tested against were contributed by JWShuff and timburgan, drawing onview_component-fragment_cachingby Patrick Arnett. The issue was opened and researched by ozzyaaron, pinzonjulian, and Derek Kniffin, and the digest workaround that surfaced the superclass gap came from cannikin and rnestler. Cache-key correctness issues (formats sharing an entry, positionalnilcollisions, conditional caching, and ignoredcache_onblocks) were found and reported by Reegan Viljoen.Reegan Viljoen, Godfrey Chan, JWShuff, timburgan, Patrick Arnett, ozzyaaron, pinzonjulian, Derek Kniffin, cannikin, rnestler, Joel Hawksley
4.14.0
-
Freeze
ReusedInstanceError::MESSAGEand updatetest_renders_component_with_asset_urlto build a freshAssetComponentper render, fixing CI regressions introduced by the GHSA-8qw7-6phv-7q6p remediation.Joel Hawksley
-
[Security] Fix incomplete remediation for CVE-2026-54497 (GHSA-8qw7-6phv-7q6p): reused ViewComponent instances could still leak
with_contentandrenders_one/renders_manyslot content from an earlier render into a later render because slot state and content set viawith_contentare populated by the caller beforerender_inruns and were not cleared by the previous per-render reset. Reinstate theViewComponent::ReusedInstanceErrorguard that raises when a component instance is rendered more than once. Rebuild collection child components per render and dup collection spacer components before each render so that legitimate re-rendering ofCollection/spacer objects continues to work.Yazan Balawneh, Cystack.ps
-
Update GitHub Actions workflows to use
actions/checkoutv7.Richard Macklin
4.13.0
-
Add support for Turbo-streaming ViewComponents.
Ben Sheldon, Joel Hawksley
-
Reduce allocations and avoid redundant compiler work when rendering components and collections.
Joel Hawksley
-
Stabilize rendering allocation tests with explicit warmups and exact expectations by Rails and Ruby.
Joel Hawksley
-
Replace the custom memory allocation test helper with
minitest-memory, preserving Ruby-version-specific allocation thresholds while improving failure diagnostics.Joel Hawksley
-
Add zizmor security analysis for GitHub Actions workflows to CI.
Joel Hawksley
-
Remove the
$PROGRAM_NAMEversion-printing line fromversion.rbso the file no longer reads a global variable (unshareable across Ractors). The version is still available viaViewComponent::VERSION::STRING.Joel Hawksley
-
Fix intermittent template compilation failures where line-number offsets and annotation stripping were decided when a template object was created instead of when it was compiled, so later changes to coverage or annotation settings produced off-by-one backtraces or blank output.
Joel Hawksley
-
Freeze
ViewComponent::VERSION::STRINGso the version constant is immutable and Ractor-shareable.Joel Hawksley
-
Add audition Ractor-readiness checks to CI. Applied safe
.freezeauto-fixes to string constants inViewComponent::Errorsand baselined existing findings so the gate fails only on new Ractor-isolation violations.Joel Hawksley
-
Update link to GOV.UK Components library in resources list to govuk-components.x-govuk.org
Peter Yates
-
Fix
NoMethodError: undefined method 'template_handler_extensions'when gathering sidecar templates on Rails main. Action View removed theActionView::Template.template_handler_extensionsmethod in newer versions; the compiler now reads the registered extensions throughActionView::Template::Handlers.extensions, which is the supported read-path API across all supported Rails versions (7.1+).Luiz Kowalski
4.12.0
-
Fix stale render context on reused component instances. A
ViewComponent::Baseinstance memoized its controller, helpers, request, view context, lookup context, view flow, and requested format details on first render via||=. Rendering the same instance a second time (intentionally or via aliasing) reused that stale context, which could leak data across requests, sessions, or users.#render_innow resets these ivars on every call so each render derives its context from the current view.Joel Hawksley
-
Fix HTML-safety bypass in
around_render.ViewComponent::Base#around_rendercould return HTML-unsafe strings that bypassed the escaping applied to normal#callreturn values, creating an XSS risk. The vulnerability was amplified inViewComponent::Collection#render_in, which joined per-item results and unconditionally marked the outputhtml_safe. HTML-unsafe strings returned fromaround_renderare now escaped (with a warning) andCollection#render_innow usessafe_joinso unsafe per-item output is escaped instead of laundered into aSafeBuffer.
Joel Hawksley
3.25.0
-
Support Rails
render_inoptions signature. Rails #50623 changed therender_insignature fromrender_in(view_context, &block)torender_in(view_context, **options, &block).ViewComponent::Base#render_in,ViewComponent::Collection#render_in, andViewComponent::Instrumentation#render_innow accept**options, restoring compatibility with Rails main and silencing the deprecation warning.Joel Hawksley
-
Fix stale render context on reused component instances. A
ViewComponent::Baseinstance memoized its controller, helpers, request, view context, lookup context, view flow, and requested format/variant on first render via||=. Rendering the same instance a second time (intentionally or via aliasing) reused that stale context, which could leak data across requests, sessions, or users.#render_innow resets these ivars on every call so each render derives its context from the current view.Joel Hawksley
-
Fix path traversal vulnerability in
ViewComponentsSystemTestControllerwhere sibling directories sharing a string prefix with the allowed temp directory could bypass the path containment check. Thestart_with?check has been replaced with a separator-aware prefix check, and nefarious path errors now return a 404 instead of an unhandled exception.Joel Hawksley
-
Fix preview route vulnerability where inherited methods on
ViewComponent::Preview(such asrender_with_template) could be invoked via the preview URL, allowing arbitrary internal Rails templates to be rendered with attacker-controlled locals and request parameters.render_argsnow raisesAbstractController::ActionNotFoundfor any example not explicitly declared on the preview subclass.Joel Hawksley
4.11.0
-
Update
render_insignature to accept**_for compatibility with Rails #50623.Joel Hawksley
-
Fix translation scope resolution in nested lambda-backed slots. Relative
t(".key")calls inside lambda-backed slots were resolving against an intermediate component's scope instead of the original partial's scope where the block was defined.Artin Boghosian
4.10.0
-
Fix
NameError: uninitialized constant ViewComponent::SystemTestControllerNefariousPathErrorwhen booting in the test environment witheager_load = true.Joel Hawksley
-
Fix yielded content rendered at wrong location when using form helpers.
Joel Hawksley, Markus
4.9.0
-
Fix path traversal vulnerability in
ViewComponentsSystemTestControllerwhere sibling directories sharing a string prefix with the allowed temp directory could bypass the path containment check. Thestart_with?check has been replaced with a separator-aware prefix check, and nefarious path errors now return a 404 instead of an unhandled exception.Joel Hawksley
-
Fix preview route vulnerability where inherited methods on
ViewComponent::Preview(such asrender_with_template) could be invoked via the preview URL, allowing arbitrary internal Rails templates to be rendered with attacker-controlled locals and request parameters.render_argsnow raisesAbstractController::ActionNotFoundfor any example not explicitly declared on the preview subclass.Joel Hawksley
-
Add
yard-lintto CI.Joel Hawksley
4.8.0
-
Add
compile.view_componentActiveSupport::Notifications event for eager compilation at boot time.Joel Hawksley, GitHub Copilot
4.7.0
-
Fix stale content cache when slots are accessed before
render_in.Jared Armstrong
-
Add rubocop-view_component to resources.
Andy Waite
-
Fix bug where inheritance of components with formatless templates improperly raised a NoMethodError.
GitHub Copilot, Joel Hawksley, Cameron Dutro