Back to React On Rails

react-on-rails-pro-node-renderer

packages/react-on-rails-pro-node-renderer/README.md

16.6.07.9 KB
Original Source

react-on-rails-pro-node-renderer

A high-performance standalone Node.js server for server-side rendering (SSR) of React components in React on Rails Pro applications. Built on Fastify with worker pool management.

Installation

bash
npm install react-on-rails-pro-node-renderer
# or
yarn add react-on-rails-pro-node-renderer
# or
pnpm add react-on-rails-pro-node-renderer

Prerequisites: This package is used with the react_on_rails_pro Ruby gem and the react-on-rails-pro npm package. See the full installation guide.

Quick Start

1. Create the Node Renderer entry file

Create node-renderer.js in your project root:

js
const path = require('path');
const { reactOnRailsProNodeRenderer, parseWorkersCount } = require('react-on-rails-pro-node-renderer');

reactOnRailsProNodeRenderer({
  // Directory where the renderer caches uploaded server bundles
  serverBundleCachePath: path.resolve(__dirname, '.node-renderer-bundles'),

  // Port the renderer listens on (must match Rails config)
  port: Number(process.env.RENDERER_PORT) || 3800,

  // Enable Node.js globals in the rendering VM context
  supportModules: true,

  // Log level: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'
  logLevel: process.env.RENDERER_LOG_LEVEL || 'info',

  // Password for Rails <-> Node renderer authentication (must match Rails config)
  password: process.env.RENDERER_PASSWORD,

  // Number of worker processes (defaults to CPU count - 1)
  // Set to 0 for single-process mode (useful for debugging)
  workersCount: parseWorkersCount(process.env.RENDERER_WORKERS_COUNT) ?? 3,
});

2. Configure Rails

ruby
# config/initializers/react_on_rails_pro.rb
ReactOnRailsPro.configure do |config|
  config.server_renderer = "NodeRenderer"
  config.renderer_url = ENV.fetch("REACT_RENDERER_URL", "http://localhost:3800")
  config.renderer_password = ENV.fetch("RENDERER_PASSWORD", "devPassword")
end

3. Configure Webpack

Set your server bundle webpack configuration to target Node.js:

js
// In serverWebpackConfig.js
serverWebpackConfig.target = 'node';

// In output config
libraryTarget: 'commonjs2',

4. Start the renderer

bash
node node-renderer.js

Or add to your Procfile.dev:

text
node-renderer: node node-renderer.js

The react_on_rails:install --pro generator automates all of the above setup:

bash
bundle add react_on_rails_pro
rails generate react_on_rails:install --pro

Configuration Options

All options can be set via the config object or environment variables. Config object values take precedence over environment variables.

OptionEnv VariableDefaultDescription
portRENDERER_PORT3800Port the renderer listens on
logLevelRENDERER_LOG_LEVEL'info'Log level (fatal, error, warn, info, debug, trace, silent)
logHttpLevelRENDERER_LOG_HTTP_LEVEL'error'HTTP server log level
serverBundleCachePathRENDERER_SERVER_BUNDLE_CACHE_PATHAuto-detected or /tmp/...Directory for cached server bundles
supportModulesRENDERER_SUPPORT_MODULESfalseEnable Node.js globals in VM context (Buffer, process, setTimeout, etc.)
workersCountRENDERER_WORKERS_COUNTCPU count - 1Number of worker processes. Legacy NODE_RENDERER_CONCURRENCY is still supported in generated templates.
passwordRENDERER_PASSWORD(none)Shared secret for Rails authentication
stubTimersRENDERER_STUB_TIMERStrueStub timer functions during SSR
allWorkersRestartIntervalRENDERER_ALL_WORKERS_RESTART_INTERVAL(disabled)Minutes between restarting all workers
delayBetweenIndividualWorkerRestartsRENDERER_DELAY_BETWEEN_INDIVIDUAL_WORKER_RESTARTS(disabled)Minutes between each worker restart
fastifyServerOptions{}Additional Fastify server options

Advanced: Custom Fastify Configuration

For custom routes (e.g., health checks) or plugins, import the master/worker modules directly. The example below uses ES Modules — use a .mjs extension, add "type": "module" to your package.json, or convert to require() calls:

js
import masterRun from 'react-on-rails-pro-node-renderer/master';
import run, { configureFastify } from 'react-on-rails-pro-node-renderer/worker';
import cluster from 'cluster';

const config = {
  /* your config */
};

configureFastify((app) => {
  app.get('/health', (request, reply) => {
    reply.send({ status: 'ok' });
  });
});

if (cluster.isPrimary) {
  masterRun(config);
} else {
  run(config);
}

Error Reporting

Integrate with Sentry or Honeybadger:

js
import { addNotifier } from 'react-on-rails-pro-node-renderer/integrations/api';

addNotifier((error) => {
  Sentry.captureException(error);
});

See Error Reporting and Tracing docs.

Documentation

Package Relationships

text
Rails App
├── react_on_rails gem (base Rails integration)
├── react_on_rails_pro gem (Pro server rendering features)
├── react-on-rails-pro npm (client JS - replaces react-on-rails)
└── react-on-rails-pro-node-renderer npm (this package - standalone SSR server)

Important: When using react_on_rails_pro gem, you must use react-on-rails-pro npm package (not react-on-rails).

License

Commercial software. No license required for evaluation, development, testing, or CI/CD. A paid license is required for production deployments. Contact [email protected] for licensing.