Ruact.configure
Configure ruact via Ruact.configure in an initializer.
The install generator creates config/initializers/ruact.rb:
Ruact.configure do |config| # config.manifest_path = Rails.root.join("public", "react-client-manifest.json") # config.strict_serialization = true # config.suspense_timeout = 5.0 # config.vite_dev_server = "http://localhost:5173"endAll settings have sensible defaults. You only need to set the ones you want to override.
Configuration Options
Section titled “Configuration Options”manifest_path
Section titled “manifest_path”Type: String, Pathname, or nil
Default: Rails.root.join("public/react-client-manifest.json")
Path to the react-client-manifest.json generated by the Vite plugin. Override this if you move the manifest to a non-default location.
config.manifest_path = Rails.root.join("public", "rsc-manifest.json")The manifest is loaded once at boot time (via Rails’ to_prepare hook) and cached for the lifetime of the process. It is not re-read on every request.
strict_serialization
Section titled “strict_serialization”Type: Boolean
Default: false in development/test, true in production
When true, objects without an explicit ruact_props declaration raise Ruact::SerializationError instead of falling back to as_json. This prevents accidental attribute exposure in production.
# Explicitly opt in to strict mode in all environmentsconfig.strict_serialization = trueRecommended: enable strict mode in production. Disable in development for faster prototyping.
suspense_timeout
Section titled “suspense_timeout”Type: Float
Default: 5.0 (seconds)
Maximum time (in seconds) ruact waits for a deferred Suspense chunk to resolve before timing out. After a timeout, the Suspense boundary emits an error row.
config.suspense_timeout = 10.0This setting only applies when streaming is enabled (ActionController::Live included).
vite_dev_server
Section titled “vite_dev_server”Type: String
Default: "http://localhost:5173"
Base URL of the Vite dev server. ruact uses this to inject the correct <script> tags into the HTML shell during development.
config.vite_dev_server = "http://localhost:3036"In production, Vite is not used — production assets are served from public/assets/.
signed_global_id_default_purpose
Section titled “signed_global_id_default_purpose”Type: Symbol | String | nil
Default: nil
App-wide default for: purpose used by Ruact.signed_global_id /
Ruact.locate_signed
when a call omits for:. A purpose scopes a signed reference to one use-site. Left
nil, ruact requires an explicit for: per call and raises rather than sign an
unscoped token.
config.signed_global_id_default_purpose = :ruact_refsigned_global_id_default_expires_in
Section titled “signed_global_id_default_expires_in”Type: ActiveSupport::Duration | nil
Default: nil
App-wide default token lifetime used when a call omits expires_in:. Must be an
ActiveSupport::Duration (e.g. 15.minutes). Left nil, ruact requires an
explicit expires_in: per call and raises rather than mint a non-expiring token;
pass an explicit expires_in: nil at the call site to deliberately opt into a
non-expiring token.
config.signed_global_id_default_expires_in = 15.minutesAccessing configuration at runtime
Section titled “Accessing configuration at runtime”# Read the current configRuact.config.manifest_pathRuact.config.strict_serialization
# Access the loaded manifest (post-boot)Ruact.manifest # => Ruact::ClientManifest instanceFull example
Section titled “Full example”Ruact.configure do |config| # Custom manifest location config.manifest_path = Rails.root.join("public", "react-client-manifest.json")
# Strict mode in production — prevents accidental data leaks config.strict_serialization = Rails.env.production?
# 10-second timeout for slow data fetches config.suspense_timeout = 10.0
# Custom Vite port (if you changed it in vite.config.js) config.vite_dev_server = "http://localhost:5173"end