github shakacode/react_on_rails v17.0.0.rc.2

pre-release5 hours ago

Added

  • [Pro] Route-loader RSC payload helper: react-on-rails-pro/rscPayloadNode now exports createRscPayloadNode(...) so client routers and loaders can consume the Pro RSC payload route as React route data without reaching into private RSCRoute internals. The helper defaults to same-origin credentials, exposes a narrow set of fetch controls (credentials, headers, and signal), and keeps console replay metadata out of inline scripts for CSP-friendly loader usage. RSC payload fetches now URL-encode component names before requesting /rsc_payload/:componentName, which preserves standard Rails path-segment decoding while avoiding invalid path characters in the browser request URL. Fixes Issue 3493. PR 3783 by justin808.
  • [Pro] RSC registration entry path override: Generated RSC precompile hooks, discovery builds, and client-reference stale checks now honor REACT_ON_RAILS_RSC_REGISTRATION_ENTRY_PATH so apps that write server-component-registration-entry.js outside the default generated path can point React on Rails Pro at the exact entry while retaining the existing fallback scan and stale-manifest cleanup. Fixes Issue 3621. PR 3712 by justin808.
  • [Pro] RSC unstable_cache with Redis L2 and tiered caching: Added unstable_cache for RSC rendering with deterministic cache-key serialization (React flight protocol encoding with sorted object keys), a RedisCacheHandler for cross-worker L2 caching, a TieredCacheHandler for L1/L2 composition with configurable L1 TTL caps, and per-worker single-flight render coalescing. Resolves Issue 3702. PR 3705.
  • [Pro] RSC manifest client reference discovery during precompile: Generated RSC Webpack configs now run RSCReferenceDiscoveryPlugin through the Shakapacker precompile hook to emit rsc-client-references.json, use that manifest for RSC client-reference bundling, and warn when the selected manifest is stale. The generator now pins react-on-rails-rsc to 19.0.5-rc.6, the prerelease containing the discovery plugin export and RSC manifest CSS fixes, and the Pro peer range explicitly accepts that prerelease. PR 3556 by ihabadham.

Changed

  • [Pro] <RSCRoute> client-control refetch failures are recoverable in production: ref and useCurrentRSCRoute() refetch failures now keep the last successful route content mounted in production, expose refetchError, retry(), and clearRefetchError() on RSCRouteHandle, and call the optional onRefetchError prop for parent/sibling reporting. Development still fails loudly through ServerComponentFetchError so component context and the original refetch error stay visible. Fixes Issue 3565. PR 3786 by justin808.
  • [Pro] Updated the RSC rollout pin to react-on-rails-rsc@19.0.5-rc.7: The generator default, package manifests, lockfile, and Pro RSC install docs now point at 19.0.5-rc.7, which fixes the Webpack client manifest CSS collection to exclude runtime-chunk CSS (so shared runtime CSS no longer leaks into every client component's Flight stylesheet hints, while the server manifest still retains runtime-chunk CSS for SSR coverage) and to skip .hot-update.css HMR files. The temporary exact prerelease pin policy is unchanged until stable 19.0.5 ships. PR 3857 by justin808.
  • [Pro] Updated the RSC rollout pin to react-on-rails-rsc@19.0.5-rc.6: Pro RSC install docs, generator defaults, package metadata, and example guidance now point at 19.0.5-rc.6 while keeping React on the supported 19.0.x range and documenting the temporary exact prerelease pin. 19.0.5-rc.6 ships the client-manifest CSS collection fix (record .css siblings, .mjs chunk support, href normalization) upstream, so the temporary local pnpm patch (patches/react-on-rails-rsc@19.0.5-rc.5.patch) has been removed. PR 3577 by justin808.
  • Generator scaffolds the native RSCRspackPlugin for Rspack RSC projects: rails generate react_on_rails:install --rsc on an Rspack app now wires up react-on-rails-rsc/RspackPlugin (RSCRspackPlugin) instead of the Webpack-compat RSCWebpackPlugin, which produced valid-looking manifests that still broke under Rspack. Re-running the generator on a legacy Rspack config migrates the old RSCWebpackPlugin import and invocation to the native plugin. The pinned react-on-rails-rsc dependency was bumped to 19.0.5-rc.6 (which still exports WebpackPlugin, so Webpack projects are unaffected). Resolves Issue 3488. PR 3590 by justin808.
  • [Pro] Widened the react-on-rails-rsc peer-dependency range to the full React 19 line: react-on-rails-pro now declares react-on-rails-rsc as >= 19.0.2 < 20.0.0 (previously >= 19.0.2 <= 19.2.3), so future react-on-rails-rsc patch and minor releases on the React 19 line no longer trigger a peer-dependency warning. The react / react-dom peers stay at >= 16: React 18 support is retained, and the React-19-only RSC path is gated through the optional react-on-rails-rsc peer rather than by raising the React baseline. Resolves Issue 3486. PR 3580 by justin808.

Improved

  • [Pro] Embedded RSC payloads no longer repeat full serialized props in the page HTML: The embedded RSC payload cache key now uses a compact hash of the component props instead of the full JSON.stringify(componentProps), so server-rendered pages with RSC components stop repeating large props JSON once per Flight chunk in render-blocking inline scripts (a 1KB props object across 10 chunks previously added ~12KB of repeated JSON; now ~120 bytes). The client-side RSCProvider in-memory promise cache still keys on full props, so payload deduplication behavior is unchanged. Fixes Issue 3796. PR 3800 by AbanoubGhadban.
  • Server-bundle load failures are now classified separately from renderer-connection failures: Bundle read/fetch failures raise the new ReactOnRails::ServerBundleLoadError instead of being grouped with renderer-connectivity errors, keeping the renderer-connection classification (see PR 3614) focused on render-origin connection failures, including wrapped connect(2) errors found through the exception cause chain. Fixes Issue 3628. PR 3724 by justin808.
  • Renderer connection failures are no longer misreported as webpack/bundle errors: When server rendering fails because Rails cannot reach the renderer process (for example a Pro Node renderer behind REACT_RENDERER_URL that refuses the connection — ECONNREFUSED, EHOSTUNREACH, ETIMEDOUT, or a sandboxed Errno::EPERM / connect(2) failure), React on Rails now raises a renderer-connectivity error that names the host/port it tried to reach and points at REACT_RENDERER_URL and renderer liveness, instead of the misleading "Error evaluating server bundle. Check your webpack configuration." The existing webpack/server-bundle troubleshooting is retained for genuine bundle evaluation errors. Fixes Issue 3604. PR 3614 by justin808.

Fixed

  • [Pro] RSC unstable_cache no longer caches failed Flight renders: React Flight render errors reported by renderToPipeableStream now skip the cache write, so later requests retry the render instead of replaying a failed RSC payload from cache. React's default error logging behavior is preserved. Fixes Issue 3774. PR 3775 by ihabadham.
  • [Pro] Prerender cache no longer misses when only the random domNodeId changes: Pro prerender cache digest normalization now strips domNodeId values emitted in JSON/double-quote form as well as the older single-quote form, so cached prerender results are reused across requests that differ only by the randomly generated DOM node id, while changed props still produce distinct digests. Fixes Issue 3706. PR 3707 by ihabadham.
  • Auto-bundled snake_case component names now load their generated packs consistently: Auto-bundled component pack loading is normalized through the same name resolution used for DOM/SSR lookup, so react_component("component_name") loads the generated/ComponentName pack, and public component names generated for files under the configured auto-bundling components subdirectory are camelized (server-bundle and store filename behavior is preserved, as is generated-pack conflict protection for names differing only by case). Fixes Issue 3809. PR 3818 by justin808.
  • [Pro] A throwing React root unmount no longer aborts client teardown: The Pro client renderer now guards the modern React root unmount() path, logging failures at console.error and always clearing the tracked root, so one failing root unmount cannot stop other components from unmounting or block later renders on the same DOM node. Fixes Issue 3618. PR 3716 by justin808.
  • [Pro] Plain-object component registrations keep their type in the Pro ComponentRegistry: Pro registry entries are now typed to cover plain object modules used by server_render_js (matching the core package types from PR 3606), getOrWaitForComponent aligns with the widened entry type, and the Pro client renderer now guards against invoking non-callable renderer entries. Fixes Issue 3677. PR 3719 by justin808.
  • Server-component wrapper types reject non-component render functions at compile time: The new ReactComponentRenderFunction type models render functions that must return a React component, and the Pro wrapServerComponentRenderer client/server inputs are narrowed to it, so registering a teardown-returning renderer function there is now a TypeScript compile-time error instead of relying only on the existing runtime guards (which are unchanged for JavaScript callers). Fixes Issue 3589. PR 3720 by justin808.
  • [Pro] Incompatible react-on-rails-rsc / React versions now fail loudly instead of silently misbehaving: the Pro node renderer checks the installed react-on-rails-rsc, react, and react-dom versions at boot and throws a clear error when react-on-rails-rsc is outside the supported 19.x major or React/React DOM are outside the supported 19.0.x patch range on the RSC path (and warns when react-on-rails-rsc is older than the recommended minimum). Because the peer dependency is declared * (so coordinated prereleases install cleanly, see PR 3616), this runtime check — not the peer range — is the real compatibility gate. Set REACT_ON_RAILS_PRO_DISABLE_VERSION_CHECK=1 to downgrade the hard error to a warning. PR 3831 by justin808.
  • [Pro] RSC React.cache() request dedupe now works in generated configs: Generated RSC webpack configs now canonicalize react, react/jsx-runtime, and react/jsx-dev-runtime resolution to one React server package instance, keeping React's RSC cache dispatcher shared between the renderer and app Server Components. This restores request-local React.cache() memoization for direct Server Component data loaders in generated RoRP RSC apps. Fixes Issue 3812. PR 3813 by ihabadham.
  • [Pro] Preloaded RSC hydration errors preserve bundle diagnostics: RSC payload injection now threads the server-side renderingError metadata to the browser so preloaded hydration failures can report the original RSC bundle error message and module path, matching the fetch path while avoiding unrelated stream metadata such as serialized props. Addresses the preloaded hydration portion of Issue 3475. PR 3766 by justin808.
  • Auto-bundled component name conflicts now fail loudly: React on Rails now raises an error when multiple auto-bundled component files resolve to the same public component name, listing the conflicting files instead of silently keeping whichever path overwrote the earlier mapping. Fixes Issue 3708. PR 3709 by ihabadham.
  • [Pro] RSC CSS no longer flashes unstyled (FOUC) behind 'use client' boundaries: CSS imported by a 'use client' boundary in a true React Server Component tree is now preloaded instead of loading only as a side effect of the JS chunk evaluating. The published react-on-rails-rsc@19.0.5-rc.6 package now records each client reference's .css siblings in the RSC client manifest, and the Pro RSC renderer emits <link rel="stylesheet" precedence="ror-rsc"> for them inside the RSC payload so React 19 hoists the stylesheets into <head> and blocks paint until they load — on both server render and client-side navigation. Fixes Issue 3211. PR 3587 by justin808.
  • [Pro] react-on-rails-rsc prerelease (RC) versions no longer mark the dependency tree invalid: The react-on-rails-pro peer dependency on the optional react-on-rails-rsc is now *, so installing any coordinated react-on-rails-rsc build — including prereleases such as react-on-rails-rsc@19.0.5-rc.6 — no longer makes npm ls react-on-rails-rsc fail with ELSPROBLEMS. npm's strict semver only lets a prerelease satisfy a comparator that shares its exact major.minor.patch tuple, so no bounded range — including the >= 19.0.2 < 20.0.0 range introduced in PR 3580 — can admit prereleases across the React 19 line (e.g. 19.0.5-rc.6, 19.2.x-rc.*) without enumerating every patch tuple. react-on-rails-rsc stays an optional peer that Pro resolves only on the React Server Components path; the supported pairing is React on Rails RSC on the React 19 line (currently >= 19.0.2), and a mismatched build is caught by the Pro node renderer's runtime version check rather than relying on the peer-range warning. Fixes Issue 3609. PR 3616 by justin808.
  • TypeScript source server bundles work with auto-generated packs: React on Rails now resolves the configured server bundle source entrypoint by extension, so apps can keep config.server_bundle_js_file = "server-bundle.js" as the compiled/runtime bundle name while using a TypeScript source entrypoint such as packs/server-bundle.ts. Public registration types also now cover plain object modules used by server_render_js, matching existing runtime behavior. Resolves Issue 1583. PR 3606 by ihabadham.
  • [Pro] Client teardown failures are no longer hidden at console.info: when ComponentRenderer.unmount() catches an error from unmountComponentAtNode (the React 16/17 legacy unmount path), it now logs at console.error instead of console.info. A caught error there means the component tree did not unmount cleanly — a teardown failure — and most log collectors and default browser-console filters drop info, so the failure was effectively silent. Addresses item 2 of Issue 3592. PR 3610 by justin808.
  • Renderer functions no longer leak their mount on navigation/unmount: Renderer functions (the 3-argument (props, railsContext, domNodeId) => … registration form) own their own React root, but React on Rails never tracked any cleanup state for them, so every renderer-function mount leaked on Turbo/Turbolinks navigation. Renderer functions may now optionally return a teardown wrapper ({ teardown: () => void | Promise<void> }, sync or async); returning nothing keeps the previous behavior, so existing renderers are unaffected. Both the core and Pro client renderers invoke the teardown on page unload and on same-id node replacement, and cleanup failures on same-id replacement are now logged to console.error instead of only being visible when tracing is enabled. The renderers differ only in the async race: if a navigation unmounts the mount while an async renderer is still resolving its teardown, Pro still runs the teardown once it resolves, whereas the core renderer is best-effort and may drop a still-pending async teardown while the renderer is awaiting dynamic imports, fetches, or other I/O on a fast navigation; active async renderer failures are logged and then untracked so a later load call can retry. The framework-shipped Pro wrapServerComponentRenderer now returns such a teardown wrapper, closing the leak automatically for every registerServerComponent user. TypeScript note: the exported RendererFunction type covers 3-argument renderers that return nothing or an optional teardown wrapper; RenderFunction keeps its existing component/server-result return contract, including legacy 3-argument renderers that returned a component only to satisfy the old type. Fixes Issue 3209. PR 3576 by justin808.

Removed

  • [Pro] Removed the legacy license key-file migration warning: The elapsed migration notices for the legacy config/react_on_rails_pro_license.key file path (the cleanup notice shown alongside a valid configured license, and the missing-license migration notice) are no longer emitted. The legacy file itself was already unread. Fixes Issue 3624. PR 3715 by justin808.

Don't miss a new react_on_rails release

NewReleases is sending notifications on new releases.