Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions docs/contributor-info/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,32 +165,12 @@ You must be logged in and have publish permissions:
npm login
```

**For private packages (GitHub Packages):**

- Get a GitHub personal access token with `write:packages` scope
- Add to `~/.npmrc`:
```ini
//npm.pkg.github.com/:_authToken=<TOKEN>
always-auth=true
```
- Set environment variable:
```bash
export GITHUB_TOKEN=<TOKEN>
```

### RubyGems Publishing

**For public gem (rubygems.org):**

- Standard RubyGems credentials via `gem push`

**For private gem (GitHub Packages):**

- Add to `~/.gem/credentials`:
```
:github: Bearer <GITHUB_TOKEN>
```

### Ruby Version Management

The script automatically detects and switches Ruby versions when needed:
Expand Down
159 changes: 159 additions & 0 deletions docs/getting-started/pro-quick-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# React on Rails Pro: Quick Start from Scratch

This guide walks you through creating a complete React on Rails Pro application with server-side rendering via the Node Renderer, from an empty directory to a running app.

**Time:** ~5 minutes

**Prerequisites:** Ruby 3.0+, Rails 7.0+, Node.js 18+, npm/yarn/pnpm

## Step 1: Create a new Rails app

```bash
rails new my-pro-app --skip-javascript --skip-docker
cd my-pro-app
```

`--skip-javascript` is required because Shakapacker handles JavaScript bundling.

## Step 2: Add gems

```ruby
# Append to Gemfile
gem "shakapacker", "~> 9.5"
gem "react_on_rails", "~> 16.3"
gem "react_on_rails_pro", "~> 16.3"
```

Then install:

```bash
bundle install
```

## Step 3: Install Shakapacker

```bash
rails shakapacker:install
```

## Step 4: Commit (required by generator)

The React on Rails generator requires a clean git working tree:

```bash
git add -A && git commit -m "Rails app with Shakapacker"
```

## Step 5: Install React on Rails with Pro

This single command sets up everything — base React on Rails, Pro configuration, Node Renderer, webpack configs, and npm packages:

```bash
rails generate react_on_rails:install --pro
```

The `--pro` flag creates:

| File | Purpose |
|------|---------|
| `config/initializers/react_on_rails.rb` | Base React on Rails config |
| `config/initializers/react_on_rails_pro.rb` | Pro config with NodeRenderer settings |
| `client/node-renderer.js` | Fastify-based Node.js SSR server entry |
| `config/webpack/serverWebpackConfig.js` | Server webpack config with `target: 'node'` and `libraryTarget: 'commonjs2'` |
| `app/javascript/src/HelloWorld/` | Example React component with SSR |
| `app/controllers/hello_world_controller.rb` | Rails controller |
| `app/views/hello_world/index.html.erb` | View using `react_component` helper |
| `Procfile.dev` | All dev processes including Node Renderer |

Commit:

```bash
git add -A && git commit -m "react_on_rails:install --pro"
```

## Step 6: Start the app

```bash
./bin/dev
```

This starts four processes:
- **Rails server** on port 3000
- **Webpack dev server** (HMR) on port 3035
- **Webpack SSR watcher** for server bundle
- **Node Renderer** on port 3800

## Step 7: Visit the app

Open [http://localhost:3000/hello_world](http://localhost:3000/hello_world)

You should see the HelloWorld component rendered with SSR. View the page source to confirm pre-rendered HTML. The input field is interactive (client-side hydration).

## What the generator configured

### Rails-side (config/initializers/react_on_rails_pro.rb)

```ruby
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")
config.prerender_caching = true
end
```
Comment on lines +92 to +103
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section title "What the generator configured" sets the expectation of accuracy, but the snippet is significantly simplified compared to the actual generated file. The real generator template also includes ssr_timeout, renderer_request_retry_limit, renderer_use_fallback_exec_js, tracing, etc. A developer who looks at their generated file will find it doesn't match.

Consider either:

  1. Renaming this to "Minimal configuration example" and noting the generator produces a fuller version
  2. Showing the complete output that matches the actual template

Otherwise developers opening their generated initializer will be confused by options not shown here.


### Node-side (client/node-renderer.js)

```js
const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generator places node-renderer.js at client/node-renderer.js (as shown in the table above), so __dirname resolves to client/. The correct path to put the cache at the project root (matching the actual template) is '../.node-renderer-bundles', not './.node-renderer-bundles'.

Suggested change
const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');
serverBundleCachePath: path.resolve(__dirname, '../.node-renderer-bundles'),


reactOnRailsProNodeRenderer({
serverBundleCachePath: path.resolve(__dirname, './.node-renderer-bundles'),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong relative path. Since the generator places this file at client/node-renderer.js, __dirname is the client/ directory. Using './.node-renderer-bundles' puts the cache inside client/, not the project root. The actual generator template uses '../.node-renderer-bundles' to resolve to the project root.

Also missing the const path = require('path'); import at the top of this snippet.

Suggested change
serverBundleCachePath: path.resolve(__dirname, './.node-renderer-bundles'),
serverBundleCachePath: path.resolve(__dirname, '../.node-renderer-bundles'),

port: Number(process.env.RENDERER_PORT) || 3800,
supportModules: true,
workersCount: Number(process.env.NODE_RENDERER_CONCURRENCY || 3),
});
Comment on lines +107 to +115
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Node-side snippet: missing require('path') and mismatched env variable name

Two issues in the generated node-renderer.js example:

  1. path.resolve(...) is called on line 111 but const path = require('path') is never imported — the snippet as written will throw ReferenceError: path is not defined.
  2. The env variable for worker count is NODE_RENDERER_CONCURRENCY here, but the react-on-rails-pro-node-renderer README (and configuration table) document it as RENDERER_WORKERS_COUNT. These need to be consistent.
🐛 Proposed fix
-```js
+```js
+const path = require('path');
 const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');

 reactOnRailsProNodeRenderer({
   serverBundleCachePath: path.resolve(__dirname, './.node-renderer-bundles'),
   port: Number(process.env.RENDERER_PORT) || 3800,
   supportModules: true,
-  workersCount: Number(process.env.NODE_RENDERER_CONCURRENCY || 3),
+  workersCount: Number(process.env.RENDERER_WORKERS_COUNT) || 3,
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/getting-started/pro-quick-start.md` around lines 107 - 115, The example
calling reactOnRailsProNodeRenderer uses path.resolve but never imports path and
uses the wrong env var name for workersCount; add a require('path') at top so
path is defined, and change the workersCount expression from reading
process.env.NODE_RENDERER_CONCURRENCY to process.env.RENDERER_WORKERS_COUNT
(fallback to 3 unchanged) so serverBundleCachePath and workersCount are correct
and consistent with the README.

```

### Key configuration options

| Rails Config | Node Config | Purpose |
|-------------|-------------|---------|
| `config.renderer_url` | `port` | Must point to the same host:port |
| `config.renderer_password` | `password` | Shared authentication secret |
| `config.prerender_caching` || Cache SSR results in Rails cache |
| `config.server_renderer` || Must be `"NodeRenderer"` to use the Node process |

## Adding React Server Components

To add RSC support to your Pro app:

```bash
rails generate react_on_rails:rsc
```

Or for a fresh app with RSC from the start:

```bash
rails generate react_on_rails:install --rsc
```

See the [RSC tutorial](https://www.shakacode.com/react-on-rails-pro/docs/react-server-components/tutorial/) for details.

## Next Steps

- [Configuration Reference](https://www.shakacode.com/react-on-rails-pro/docs/configuration/) — All Pro config options
- [Node Renderer Configuration](https://www.shakacode.com/react-on-rails-pro/docs/node-renderer/js-configuration/) — All Node Renderer options
- [Caching Guide](https://www.shakacode.com/react-on-rails-pro/docs/caching/) — Fragment and prerender caching
- [Streaming SSR](https://www.shakacode.com/react-on-rails-pro/docs/streaming-server-rendering/) — Progressive rendering
- [Code Splitting](https://www.shakacode.com/react-on-rails-pro/docs/code-splitting/) — Loadable components with SSR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Broken link — 404 confirmed by CI

The link https://www.shakacode.com/react-on-rails-pro/docs/code-splitting/ returns 404 (flagged by the GitHub Actions "Check Markdown Links" pipeline). Update it to the correct URL or remove it until the page exists.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/getting-started/pro-quick-start.md` at line 149, The markdown entry for
the Code Splitting link currently points to a 404 URL; locate the line
containing the link text "[Code
Splitting](https://www.shakacode.com/react-on-rails-pro/docs/code-splitting/)"
in pro-quick-start.md and either replace the broken URL with the correct working
URL for the Code Splitting docs or remove the entire bullet (the "[Code
Splitting](...)" link) until the target page is restored, ensuring the
surrounding list formatting remains valid.


## Troubleshooting

**"uninitialized constant ReactOnRailsPro"**: The `react_on_rails_pro` gem is not in your Gemfile. Run `bundle add react_on_rails_pro`.

**"You have the Pro gem installed but are using the base 'react-on-rails' package"**: Uninstall `react-on-rails` and install `react-on-rails-pro` instead. The `--pro` generator handles this automatically.

**Node Renderer not connecting**: Ensure the `renderer_url` in `react_on_rails_pro.rb` matches the `port` in `node-renderer.js` (default: 3800).

**Server bundle errors**: Ensure `serverWebpackConfig.js` has `target: 'node'` and `libraryTarget: 'commonjs2'` set. The `--pro` generator configures this automatically.
111 changes: 111 additions & 0 deletions llms.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# React on Rails

> React on Rails integrates React with Ruby on Rails, providing server-side rendering (SSR), component registration, and seamless Rails view integration. React on Rails Pro adds advanced features: a high-performance Node.js rendering server, fragment caching, prerender caching, React Server Components (RSC), and streaming SSR.

## Package Relationships

React on Rails consists of Ruby gems and npm packages that must be paired correctly:

### Open-Source (base):
- Ruby gem: `react_on_rails`
- npm package: `react-on-rails`

### Pro (commercial, extends base):
- Ruby gem: `react_on_rails_pro` (depends on `react_on_rails`)
- npm package: `react-on-rails-pro` (REPLACES `react-on-rails`, do NOT use both)
- npm package: `react-on-rails-pro-node-renderer` (standalone Fastify SSR server, optional)

IMPORTANT: When using the `react_on_rails_pro` gem, you MUST use the `react-on-rails-pro` npm package. The base `react-on-rails` npm package will be rejected at runtime.

## Quick Setup

### Base (open-source):
```bash
rails generate react_on_rails:install
```

### Pro with Node Renderer:
```bash
bundle add react_on_rails_pro
rails generate react_on_rails:install --pro
```

### Pro with React Server Components:
```bash
bundle add react_on_rails_pro
rails generate react_on_rails:install --rsc
```

## Node Renderer API

The Node Renderer is a Fastify-based Node.js server for high-performance SSR.

### Correct usage:
```js
const { reactOnRailsProNodeRenderer } = require('react-on-rails-pro-node-renderer');

reactOnRailsProNodeRenderer({
serverBundleCachePath: path.resolve(__dirname, '.node-renderer-bundles'),
port: 3800,
supportModules: true,
password: process.env.RENDERER_PASSWORD,
workersCount: 3,
logLevel: 'info',
});
```

The function name is `reactOnRailsProNodeRenderer` (NOT `createServer` or `startRenderer`).
The config key for the bundle cache directory is `serverBundleCachePath` (NOT `bundlePath`, which is deprecated).

### Rails-side configuration:
```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")
config.prerender_caching = true
end
```

Key attributes: `server_renderer`, `renderer_url`, `renderer_password`, `prerender_caching`, `ssr_timeout`, `renderer_use_fallback_exec_js`, `throw_js_errors`, `tracing`, `dependency_globs`.

### Webpack server config requirements (for Pro Node Renderer):
```js
// serverWebpackConfig.js output section
libraryTarget: 'commonjs2',

// after output section
serverWebpackConfig.target = 'node';
```

## Client-Side Component Registration

```js
// With base package
import ReactOnRails from 'react-on-rails';
ReactOnRails.register({ MyComponent });

// With Pro package (use this when react_on_rails_pro gem is installed)
import ReactOnRails from 'react-on-rails-pro';
ReactOnRails.register({ MyComponent });
```

## Pro-Exclusive Imports

```js
import { RSCRoute } from 'react-on-rails-pro/RSCRoute';
import registerServerComponent from 'react-on-rails-pro/registerServerComponent/client';
import { wrapServerComponentRenderer } from 'react-on-rails-pro/wrapServerComponentRenderer/client';
```

## Documentation Links

- Docs: https://www.shakacode.com/react-on-rails/docs/
- Pro Docs: https://www.shakacode.com/react-on-rails-pro/docs/
- Pro Installation: https://www.shakacode.com/react-on-rails-pro/docs/installation/
- Pro Configuration: https://www.shakacode.com/react-on-rails-pro/docs/configuration/
- Node Renderer Basics: https://www.shakacode.com/react-on-rails-pro/docs/node-renderer/basics/
- Node Renderer JS Config: https://www.shakacode.com/react-on-rails-pro/docs/node-renderer/js-configuration/
- RSC Tutorial: https://www.shakacode.com/react-on-rails-pro/docs/react-server-components/tutorial/
- GitHub: https://github.com/shakacode/react_on_rails
Loading
Loading