Skip to content

Ruact.configure

Configure ruact via Ruact.configure in an initializer.


The install generator creates config/initializers/ruact.rb:

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"
end

All settings have sensible defaults. You only need to set the ones you want to override.


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.


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 environments
config.strict_serialization = true

Recommended: enable strict mode in production. Disable in development for faster prototyping.


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.0

This setting only applies when streaming is enabled (ActionController::Live included).


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/.


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_ref

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.minutes

# Read the current config
Ruact.config.manifest_path
Ruact.config.strict_serialization
# Access the loaded manifest (post-boot)
Ruact.manifest # => Ruact::ClientManifest instance

config/initializers/ruact.rb
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