Skip to content

Ruact.configure

Configure ruact via Ruact.configure in an initializer.


Setup

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

ruby
# 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.


Configuration Options

manifest_path

Type: String, Pathname, or nilDefault: 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.

ruby
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

Type: BooleanDefault: 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.

ruby
# 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.


suspense_timeout

Type: FloatDefault: 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.

ruby
config.suspense_timeout = 10.0

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


vite_dev_server

Type: StringDefault: "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.

ruby
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

Type: Symbol | String | nilDefault: 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.

ruby
config.signed_global_id_default_purpose = :ruact_ref

signed_global_id_default_expires_in

Type: ActiveSupport::Duration | nilDefault: 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.

ruby
config.signed_global_id_default_expires_in = 15.minutes

Accessing configuration at runtime

ruby
# Read the current config
Ruact.config.manifest_path
Ruact.config.strict_serialization

# Access the loaded manifest (post-boot)
Ruact.manifest   # => Ruact::ClientManifest instance

Full example

ruby
# 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

Released under the MIT License.