Skip to content

Commit 209c856

Browse files
justin808claude
andcommitted
Update documentation for Shakapacker 9.0+ private_output_path integration
Documents the recommended approach of using Shakapacker 9.0+ private_output_path for server bundle configuration, providing a single source of truth. **Documentation Updates:** **1. Configuration API Reference (docs/api-reference/configuration.md)** - Added prominent recommendation for Shakapacker 9.0+ approach - Documents shakapacker.yml private_output_path configuration - Explains auto-detection behavior - Preserves documentation for older versions **2. Webpack Configuration Guide (docs/core-concepts/webpack-configuration.md)** - New section: "Server Bundle Configuration (Shakapacker 9.0+)" - Complete example with shakapacker.yml and webpack config - Lists benefits of the new approach: - Single source of truth - Automatic synchronization - No configuration duplication - Better maintainability - Notes compatibility with older versions **Key Points:** - Shakapacker 9.0+ users get automatic configuration - Backward compatible with manual configuration - Generator templates already show both approaches - Doctor command guides users to upgrade **Related Changes:** - Generator templates already updated in previous commit - Auto-detection implemented in configuration.rb - Doctor provides version-aware recommendations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 925e485 commit 209c856

File tree

2 files changed

+260
-0
lines changed

2 files changed

+260
-0
lines changed

docs/api-reference/configuration.md

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,234 @@ ReactOnRails.configure do |config|
9494
# This controls what command is run to build assets during tests
9595
################################################################################
9696
config.build_test_command = "RAILS_ENV=test bin/shakapacker"
97+
98+
#
99+
# React Server Components and Streaming SSR are React on Rails Pro features.
100+
# For detailed configuration of RSC and streaming features, see:
101+
# https://github.com/shakacode/react_on_rails/blob/master/react_on_rails_pro/docs/configuration.md
102+
#
103+
# Key Pro configurations (configured in ReactOnRailsPro.configure block):
104+
# - rsc_bundle_js_file: Path to RSC bundle
105+
# - react_client_manifest_file: Client component manifest for RSC
106+
# - react_server_client_manifest_file: Server manifest for RSC
107+
# - enable_rsc_support: Enable React Server Components
108+
#
109+
# See Pro documentation for complete setup instructions.
110+
111+
################################################################################
112+
# SERVER BUNDLE SECURITY AND ORGANIZATION
113+
################################################################################
114+
115+
# ⚠️ RECOMMENDED: Use Shakapacker 9.0+ for Automatic Configuration
116+
#
117+
# For Shakapacker 9.0+, add to config/shakapacker.yml:
118+
# private_output_path: ssr-generated
119+
#
120+
# React on Rails will automatically detect and use this value, eliminating the need
121+
# to configure server_bundle_output_path here. This provides a single source of truth.
122+
#
123+
# For older Shakapacker versions or custom setups, manually configure:
124+
# This configures the directory (relative to the Rails root) where the server bundle will be output.
125+
# By default, this is "ssr-generated". If set to nil, the server bundle will be loaded from the same
126+
# public directory as client bundles. For enhanced security, use this option in conjunction with
127+
# `enforce_private_server_bundles` to ensure server bundles are only loaded from private directories
128+
# config.server_bundle_output_path = "ssr-generated"
129+
130+
# When set to true, React on Rails will only load server bundles from private, explicitly configured directories (such as `ssr-generated`), and will raise an error if a server bundle is found in a public or untrusted location. This helps prevent accidental or malicious execution of untrusted JavaScript on the server, and is strongly recommended for production environments. And prevent leakage of server-side code to the client (Especially in the case of RSC).
131+
# Default is false for backward compatibility, but enabling this option is a best practice for security.
132+
config.enforce_private_server_bundles = false
133+
134+
################################################################################
135+
# BUNDLE ORGANIZATION EXAMPLES
136+
################################################################################
137+
#
138+
# This configuration creates a clear separation between client and server assets:
139+
#
140+
# CLIENT BUNDLES (Public, Web-Accessible):
141+
# Location: public/webpack/[environment]/ or public/packs/ (According to your shakapacker.yml configuration)
142+
# Files: application.js, manifest.json, CSS files
143+
# Served by: Web server directly
144+
# Access: ReactOnRails::Utils.public_bundles_full_path
145+
#
146+
# SERVER BUNDLES (Private, Server-Only):
147+
# Location: ssr-generated/ (when server_bundle_output_path configured)
148+
# Files: server-bundle.js, rsc-bundle.js
149+
# Served by: Never served to browsers
150+
# Access: ReactOnRails::Utils.server_bundle_js_file_path
151+
#
152+
# Example directory structure with recommended configuration:
153+
# app/
154+
# ├── ssr-generated/ # Private server bundles
155+
# │ ├── server-bundle.js
156+
# │ └── rsc-bundle.js
157+
# └── public/
158+
# └── webpack/development/ # Public client bundles
159+
# ├── application.js
160+
# ├── manifest.json
161+
# └── styles.css
162+
#
163+
################################################################################
164+
165+
# `prerender` means server-side rendering
166+
# default is false. This is an option for view helpers `render_component` and `render_component_hash`.
167+
# Set to true to change the default value to true.
168+
config.prerender = false
169+
170+
# THE BELOW OPTIONS FOR SERVER-SIDE RENDERING RARELY NEED CHANGING
171+
#
172+
# This value only affects server-side rendering when using the webpack-dev-server
173+
# If you are hashing the server bundle and you want to use the same bundle for client and server,
174+
# you'd set this to `true` so that React on Rails reads the server bundle from the webpack-dev-server.
175+
# Normally, you have different bundles for client and server, thus, the default is false.
176+
# Furthermore, if you are not hashing the server bundle (not in the manifest.json), then React on Rails
177+
# will only look for the server bundle to be created in the typical file location, typically by
178+
# a `shakapacker --watch` process.
179+
# If true, ensure that in config/shakapacker.yml that you have both dev_server.hmr and
180+
# dev_server.inline set to false.
181+
config.same_bundle_for_client_and_server = false
182+
183+
# If set to true, this forces Rails to reload the server bundle if it is modified
184+
# Default value is Rails.env.development?
185+
# You probably will never change this.
186+
config.development_mode = Rails.env.development?
187+
188+
# For server rendering so that the server-side console replays in the browser console.
189+
# This can be set to false so that server side messages are not displayed in the browser.
190+
# Default is true. Be cautious about turning this off, as it can make debugging difficult.
191+
# Default value is true
192+
config.replay_console = true
193+
194+
# Default is true. Logs server rendering messages to Rails.logger.info. If false, you'll only
195+
# see the server rendering messages in the browser console.
196+
config.logging_on_server = true
197+
198+
# Default is true only for development? to raise exception on server if the JS code throws for
199+
# server rendering. The reason is that the server logs will show the error and force you to fix
200+
# any server rendering issues immediately during development.
201+
config.raise_on_prerender_error = Rails.env.development?
202+
203+
# This configuration allows logic to be applied to client rendered props, such as stripping props that are only used during server rendering.
204+
# Add a module with an adjust_props_for_client_side_hydration method that expects the component's name & props hash
205+
# See below for an example definition of RenderingPropsExtension
206+
config.rendering_props_extension = RenderingPropsExtension
207+
208+
################################################################################
209+
# Server Renderer Configuration for ExecJS
210+
################################################################################
211+
# The default server rendering is ExecJS, by default using Node.js runtime
212+
# If you wish to use an alternative Node server rendering for higher performance,
213+
# contact justin@shakacode.com for details.
214+
#
215+
# For ExecJS:
216+
# You can configure your pool of JS virtual machines and specify where it should load code:
217+
# On MRI, use `node.js` runtime for the best performance
218+
# (see https://github.com/shakacode/react_on_rails/issues/1438)
219+
# Also see https://github.com/shakacode/react_on_rails/issues/1457#issuecomment-1165026717 if using `mini_racer`
220+
# On MRI, you'll get a deadlock with `pool_size` > 1
221+
# If you're using JRuby, you can increase `pool_size` to have real multi-threaded rendering.
222+
config.server_renderer_pool_size = 1 # increase if you're on JRuby
223+
config.server_renderer_timeout = 20 # seconds
224+
225+
################################################################################
226+
################################################################################
227+
# FILE SYSTEM BASED COMPONENT REGISTRY
228+
# `render_component` and `render_component_hash` view helper methods can
229+
# auto-load the bundle for the generated component, to avoid having to specify the
230+
# bundle manually for each view with the component.
231+
#
232+
# SHAKAPACKER VERSION REQUIREMENTS:
233+
# - Basic pack generation: Shakapacker 6.5.1+
234+
# - Advanced auto-registration with nested entries: Shakapacker 7.0.0+
235+
# - Async loading support: Shakapacker 8.2.0+
236+
#
237+
# Feature Compatibility Matrix:
238+
# | Shakapacker Version | Basic Pack Generation | Auto-Registration | Nested Entries | Async Loading |
239+
# |-------------------|----------------------|-------------------|----------------|---------------|
240+
# | 6.5.1 - 6.9.x | ✅ Yes | ❌ No | ❌ No | ❌ No |
241+
# | 7.0.0 - 8.1.x | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
242+
# | 8.2.0+ | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
243+
#
244+
################################################################################
245+
# components_subdirectory is the name of the subdirectory matched to detect and register components automatically
246+
# The default is nil. You can enable the feature by updating it in the next line.
247+
config.components_subdirectory = nil
248+
# Change to a value like this example to enable this feature
249+
# config.components_subdirectory = "ror_components"
250+
251+
# Default is false.
252+
# The default can be overridden as an option in calls to view helpers
253+
# `render_component` and `render_component_hash`. You may set to true to change the default to auto loading.
254+
# NOTE: Requires Shakapacker 6.5.1+ for basic functionality, 7.0.0+ for full auto-registration features.
255+
# See version requirements matrix above for complete feature compatibility.
256+
config.auto_load_bundle = false
257+
258+
# Default is false
259+
# Set this to true & instead of trying to import the generated server components into your existing
260+
# server bundle entrypoint, the PacksGenerator will create a server bundle entrypoint using
261+
# config.server_bundle_js_file for the filename.
262+
config.make_generated_server_bundle_the_entrypoint = false
263+
264+
# Configuration for how generated component packs are loaded.
265+
# Options: :sync, :async, :defer
266+
# - :sync (default for Shakapacker < 8.2.0): Loads scripts synchronously
267+
# - :async (default for Shakapacker ≥ 8.2.0): Loads scripts asynchronously for better performance
268+
# - :defer: Defers script execution until after page load
269+
config.generated_component_packs_loading_strategy = :async
270+
271+
# DEPRECATED: Use `generated_component_packs_loading_strategy` instead.
272+
# Migration: `defer_generated_component_packs: true` → `generated_component_packs_loading_strategy: :defer`
273+
# Migration: `defer_generated_component_packs: false` → `generated_component_packs_loading_strategy: :sync`
274+
# See [16.0.0 Release Notes](docs/release-notes/16.0.0.md) for more details.
275+
# config.defer_generated_component_packs = false
276+
277+
# Default is false
278+
# React on Rails Pro (licensed) feature: When true, components hydrate immediately as soon as
279+
# their server-rendered HTML reaches the client, without waiting for the full page load.
280+
# This improves time-to-interactive performance.
281+
config.immediate_hydration = false
282+
283+
################################################################################
284+
# I18N OPTIONS
285+
################################################################################
286+
# Replace the following line to the location where you keep translation.js & default.js for use
287+
# by the npm packages react-intl. Be sure this directory exists!
288+
# config.i18n_dir = Rails.root.join("client", "app", "libs", "i18n")
289+
#
290+
# If not using the i18n feature, then leave this section commented out or set the value
291+
# of config.i18n_dir to nil.
292+
#
293+
# Replace the following line to the location where you keep your client i18n yml files
294+
# that will source for automatic generation on translations.js & default.js
295+
# By default(without this option) all yaml files from Rails.root.join("config", "locales")
296+
# and installed gems are loaded
297+
config.i18n_yml_dir = Rails.root.join("config", "locales")
298+
299+
# Possible output formats are js and json
300+
# The default format is json
301+
config.i18n_output_format = 'json'
302+
303+
# Possible YAML.safe_load options pass-through for locales
304+
# config.i18n_yml_safe_load_options = { permitted_classes: [Symbol] }
305+
306+
################################################################################
307+
################################################################################
308+
# TEST CONFIGURATION OPTIONS
309+
# Below options are used with the use of this test helper:
310+
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
311+
#
312+
# NOTE:
313+
# Instead of using this test helper, you may ensure fresh test files using Shakapacker via:
314+
# 1. Have `config/webpack/test.js` exporting an array of objects to configure both client and server bundles.
315+
# 2. Set the compile option to true in config/shakapacker.yml for env test
316+
################################################################################
317+
318+
# If you are using this in your spec_helper.rb (or rails_helper.rb):
319+
#
320+
# ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
321+
#
322+
# with rspec then this controls what yarn command is run
323+
# to automatically refresh your Webpack assets on every test run.
324+
#
97325
end
98326
```
99327

docs/core-concepts/webpack-configuration.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,38 @@ default: &default
7878
7979
The `bin/switch-bundler` script automatically updates this configuration when switching bundlers.
8080

81+
### Server Bundle Configuration (Shakapacker 9.0+)
82+
83+
**Recommended**: For Shakapacker 9.0+, use `private_output_path` in `shakapacker.yml` for server bundles:
84+
85+
```yaml
86+
default: &default # ... other config ...
87+
private_output_path: ssr-generated
88+
```
89+
90+
This provides a single source of truth for server bundle location. React on Rails automatically detects this configuration, eliminating the need to set `server_bundle_output_path` in your React on Rails initializer.
91+
92+
In your `config/webpack/serverWebpackConfig.js`:
93+
94+
```javascript
95+
const { config } = require('shakapacker');
96+
97+
serverWebpackConfig.output = {
98+
filename: 'server-bundle.js',
99+
globalObject: 'this',
100+
path: config.privateOutputPath, // Automatically uses shakapacker.yml value
101+
};
102+
```
103+
104+
**Benefits:**
105+
106+
- Single source of truth in `shakapacker.yml`
107+
- Automatic synchronization between webpack and React on Rails
108+
- No configuration duplication
109+
- Better maintainability
110+
111+
**For older Shakapacker versions:** Use hardcoded paths and manual configuration as shown in the generator templates.
112+
81113
Per the example repo [shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr),
82114
you should consider keeping your codebase mostly consistent with the defaults for [Shakapacker](https://github.com/shakacode/shakapacker).
83115

0 commit comments

Comments
 (0)