Sitelet https://github.com/viewcomponent/view_component/releases
Skip to content

Releases: ViewComponent/view_component

4.15.0

Choose a tag to compare

@github-actions github-actions released this 25 Aug 21:17
e0f40c5
  • Add experimental caching support, opt-in per component via include ViewComponent::ExperimentallyCacheable.

    Components have never participated in Rails' template digests, so a <% cache %> block wrapping render MyComponent.new was 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 #call methods. Adding cache_on caches the component's own rendered output, optionally guarded by if:/unless:, and .cache_digest exposes 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_on is 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_on API 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 from view_component-cache_digest by Godfrey Chan. The invalidation cases it's tested against were contributed by JWShuff and timburgan, drawing on view_component-fragment_caching by 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, positional nil collisions, conditional caching, and ignored cache_on blocks) 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

Choose a tag to compare

@github-actions github-actions released this 24 Aug 20:01
efc3085
  • Freeze ReusedInstanceError::MESSAGE and update test_renders_component_with_asset_url to build a fresh AssetComponent per 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_content and renders_one/renders_many slot content from an earlier render into a later render because slot state and content set via with_content are populated by the caller before render_in runs and were not cleared by the previous per-render reset. Reinstate the ViewComponent::ReusedInstanceError guard 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 of Collection/spacer objects continues to work.

    Yazan Balawneh, Cystack.ps

  • Update GitHub Actions workflows to use actions/checkout v7.

    Richard Macklin

4.13.0

Choose a tag to compare

@joelhawksley joelhawksley released this 20 Aug 16:18
3dd767c
  • 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_NAME version-printing line from version.rb so the file no longer reads a global variable (unshareable across Ractors). The version is still available via ViewComponent::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::STRING so the version constant is immutable and Ractor-shareable.

    Joel Hawksley

  • Add audition Ractor-readiness checks to CI. Applied safe .freeze auto-fixes to string constants in ViewComponent::Errors and 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 the ActionView::Template.template_handler_extensions method in newer versions; the compiler now reads the registered extensions through ActionView::Template::Handlers.extensions, which is the supported read-path API across all supported Rails versions (7.1+).

    Luiz Kowalski

4.12.0

Choose a tag to compare

@joelhawksley joelhawksley released this 04 Jun 21:02
4cbdbaa
  • Fix stale render context on reused component instances. A ViewComponent::Base instance 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_in now 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_render could return HTML-unsafe strings that bypassed the escaping applied to normal #call return values, creating an XSS risk. The vulnerability was amplified in ViewComponent::Collection#render_in, which joined per-item results and unconditionally marked the output html_safe. HTML-unsafe strings returned from around_render are now escaped (with a warning) and Collection#render_in now uses safe_join so unsafe per-item output is escaped instead of laundered into a SafeBuffer.
    Joel Hawksley

3.25.0

Choose a tag to compare

@joelhawksley joelhawksley released this 05 Jun 19:47
4cbdbaa
  • Support Rails render_in options signature. Rails #50623 changed the render_in signature from render_in(view_context, &block) to render_in(view_context, **options, &block). ViewComponent::Base#render_in, ViewComponent::Collection#render_in, and ViewComponent::Instrumentation#render_in now accept **options, restoring compatibility with Rails main and silencing the deprecation warning.

    Joel Hawksley

  • Fix stale render context on reused component instances. A ViewComponent::Base instance 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_in now resets these ivars on every call so each render derives its context from the current view.

    Joel Hawksley

  • Fix path traversal vulnerability in ViewComponentsSystemTestController where sibling directories sharing a string prefix with the allowed temp directory could bypass the path containment check. The start_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 as render_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_args now raises AbstractController::ActionNotFound for any example not explicitly declared on the preview subclass.

    Joel Hawksley

4.11.0

Choose a tag to compare

@joelhawksley joelhawksley released this 18 May 16:33
b1f6917
  • Update render_in signature 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

Choose a tag to compare

@joelhawksley joelhawksley released this 11 May 20:15
e799229
  • Fix NameError: uninitialized constant ViewComponent::SystemTestControllerNefariousPathError when booting in the test environment with eager_load = true.

    Joel Hawksley

  • Fix yielded content rendered at wrong location when using form helpers.

    Joel Hawksley, Markus

4.9.0

Choose a tag to compare

@joelhawksley joelhawksley released this 05 May 20:32
458281b
  • Fix path traversal vulnerability in ViewComponentsSystemTestController where sibling directories sharing a string prefix with the allowed temp directory could bypass the path containment check. The start_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 as render_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_args now raises AbstractController::ActionNotFound for any example not explicitly declared on the preview subclass.

    Joel Hawksley

  • Add yard-lint to CI.

    Joel Hawksley

4.8.0

Choose a tag to compare

@joelhawksley joelhawksley released this 22 Apr 15:37
d7e8cb4
  • Add compile.view_component ActiveSupport::Notifications event for eager compilation at boot time.

    Joel Hawksley, GitHub Copilot

4.7.0

Choose a tag to compare

@joelhawksley joelhawksley released this 17 Apr 20:26
b89ff4f
  • 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