You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Modernize generator and project structure documentation
This commit updates documentation that was 9.5 years outdated, removing
references to directory structures and patterns that haven't existed since
2016 and replacing them with accurate modern (2025) guidance.
## Changes to docs/api-reference/generator-details.md
- Replace outdated structure description with accurate modern organization
- Document both non-Redux and Redux generator structures separately
- Add visual directory trees showing actual generated code locations
- Document previously undocumented --typescript option
- Remove references to non-existent app/lib folder (removed Apr 2016)
- Remove incorrect path app/javascript/app/bundles (never existed - was docs typo)
- Add auto-bundling explanation with cross-reference
- Show real component structure: src/ComponentName/ror_components/
## Changes to docs/building-features/react-router.md
- Update path reference from legacy client/app/bundles to modern src/ structure
- Clarify this example applies to --redux generator option
- Make path reference generic rather than specific to outdated structure
## Changes to docs/getting-started/project-structure.md
Complete rewrite to reflect modern React on Rails:
### Removed outdated content:
- Old bundles/ structure presented as current (was 2015-2016 pattern)
- "Moving node_modules to /client" section (tested and proven broken with Shakapacker)
- References to /client/app/assets directory (generator stopped creating in Apr 2016)
- Outdated CSS/assets management discussion
### Added modern content:
- Modern auto-bundling structure as recommended approach
- Traditional manual structure as legacy option with clear use cases
- Decision guide for choosing between approaches
- CSS Modules documentation (default in generator since modern versions)
- Real code examples from actual generator templates
- Rails Asset Pipeline as alternative approach
- Advanced global styles pattern
## Historical Context
Research revealed:
- Oct 2015: Generator created client/app/lib/middlewares/ and client/app/bundles/
- Apr 5, 2016: Docs added describing app/lib folder
- Apr 23, 2016: Generator removed these directories (18 days later!)
- Apr 2016 - Oct 2025: Docs never updated - outdated for 9.5 years
## Testing Performed
Created test app at /home/ihab/ihab/work/shakacode/test/default-structure-test/:
- Verified default generator creates src/ structure, not bundles/
- Verified CSS modules co-located with components
- Tested /client conversion: works perfectly (just move + config change)
- Tested moving node_modules to /client: FAILS with Shakapacker
- Confirmed SHAKAPACKER_CONFIG env var doesn't solve the issue
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/api-reference/generator-details.md
+69-9Lines changed: 69 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,18 +41,78 @@ Another good option is to create a simple test app per the [Tutorial](../getting
41
41
42
42
## Understanding the Organization of the Generated Client Code
43
43
44
-
The generated client code follows our organization scheme. Each unique set of functionality is given its own folder inside of `app/javascript/app/bundles`. This encourages modularity of _domains_.
44
+
The React on Rails generator creates different directory structures depending on whether you use the `--redux` option.
45
45
46
-
Inside the generated "HelloWorld" domain you will find the following folders:
46
+
### Default Structure (Without Redux)
47
47
48
-
-`startup`: contains the entry point files for webpack. It defaults to a single file that is used for both server and client compilation. But if these need to be different, then you can create two Webpack configurations with separate endpoints. Since RoR v14.2 this is strongly recommended because the client can import `react-on-rails/client` instead of `react-on-rails` for decreased bundle size.
49
-
-`containers`: contains "smart components" (components that have functionality and logic that is passed to child "dumb components").
50
-
-`components`: contains "dumb components", or components that simply render their properties and call functions given to them as properties by a parent component. Ultimately, at least one of these dumb components will have a parent container component.
48
+
The basic generator creates a simple, flat structure optimized for auto-bundling:
51
49
52
-
You may also notice the `app/lib` folder. This is for any code that is common between bundles and therefore needs to be shared (for example, middleware).
50
+
```
51
+
app/javascript/
52
+
└── src/
53
+
└── HelloWorld/
54
+
└── ror_components/ # Components auto-registered by React on Rails
55
+
├── HelloWorld.jsx # Your React component
56
+
├── HelloWorld.module.css
57
+
└── HelloWorld.server.js # Optional: separate server rendering logic
58
+
```
59
+
60
+
-**`src/`**: Source directory for all React components
61
+
-**`ror_components/`**: Directory name is configurable via `config.components_subdirectory` in `config/initializers/react_on_rails.rb`
62
+
-**Auto-registration**: Components in `ror_components/` directories are automatically discovered and registered when using `auto_load_bundle: true`
63
+
64
+
For components that need different client vs. server implementations, use `.client.jsx` and `.server.jsx` suffixes (e.g., `HelloWorld.client.jsx` and `HelloWorld.server.jsx`).
65
+
66
+
### Redux Structure (With `--redux` Option)
67
+
68
+
The Redux generator creates a more structured organization with familiar Redux patterns:
This creates `.tsx` files instead of `.jsx` and adds TypeScript configuration.
108
+
109
+
### Auto-Bundling and Component Registration
53
110
54
-
### Redux
111
+
Modern React on Rails uses auto-bundling to eliminate manual webpack configuration. Components placed in the configured `components_subdirectory` (default: `ror_components`) are automatically:
55
112
56
-
If you have used the `--redux` generator option, you will notice the familiar additional redux folders in addition to the aforementioned folders. The Hello World example has also been modified to use Redux.
113
+
1. Discovered by the generator
114
+
2. Bundled into separate webpack entry points
115
+
3. Registered for use with `react_component` helper
116
+
4. Loaded on-demand when used in views
57
117
58
-
Note the organizational paradigm of "bundles". These are like application domains and are used for grouping your code into webpack bundles, in case you decide to create different bundles for deployment. This is also useful for separating out logical parts of your application. The concept is that each bundle will have it's own Redux store. If you have code that you want to reuse across bundles, including components and reducers, place them under `/client/app/lib`.
118
+
For detailed information on auto-bundling, see the [Auto-Bundling Guide](../core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md).
Copy file name to clipboardExpand all lines: docs/building-features/react-router.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ _This article needs updating for the latest version of React Router_
4
4
5
5
React on Rails supports the use of React Router. Client-side code doesn't need any special configuration for the React on Rails gem. Implement React Router how you normally would. Note, you might want to avoid using Turbolinks as both Turbolinks and React Router will be trying to handle the back and forward buttons. If you get this figured out, please do share with the community! Otherwise, you might have to tweak the basic settings for Turbolinks, and this may or may not be worth the effort.
6
6
7
-
If you are working with the HelloWorldApp created by the react_on_rails generator, then the code below corresponds to the module in `client/app/bundles/HelloWorld/startup/HelloWorldApp.jsx`.
7
+
If you are working with the HelloWorldApp created by the react_on_rails generator (with `--redux` option), the code below corresponds to your Redux entry point component (typically in `src/HelloWorldApp/ror_components/`).
└── server-bundle.js # Server rendering entry point
13
26
```
14
27
15
-
Per the example repo [shakacode/react_on_rails_demo_ssr_hmr](https://github.com/shakacode/react_on_rails_demo_ssr_hmr),
16
-
you should consider keeping your codebase mostly consistent with the defaults for [Shakapacker](https://github.com/shakacode/shakapacker).
28
+
**Key features:**
29
+
30
+
- Components in `ror_components/` directories are automatically discovered and registered
31
+
- Each component gets its own webpack bundle for optimal code splitting
32
+
- No manual `ReactOnRails.register()` calls needed
33
+
- Supports separate `.client.jsx` and `.server.jsx` files for different rendering logic
34
+
35
+
For details, see [Auto-Bundling Guide](../core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md) and [Generator Details](../api-reference/generator-details.md).
36
+
37
+
## Traditional Manual Structure (Legacy)
38
+
39
+
For projects requiring explicit control over webpack entry points:
This approach requires manual component registration and webpack configuration but offers complete control over bundling strategy.
54
+
55
+
## Choosing Your Structure
56
+
57
+
**Use modern auto-bundling if:**
58
+
59
+
- Starting a new project
60
+
- Want automatic code splitting per component
61
+
- Prefer convention over configuration
62
+
- Want to minimize boilerplate
63
+
64
+
**Use traditional manual structure if:**
65
+
66
+
- Have complex custom webpack requirements
67
+
- Need fine-grained control over bundle composition
68
+
- Migrating from older React on Rails versions
69
+
70
+
For most projects, we recommend the modern auto-bundling approach.
17
71
18
72
## Steps to convert from the generator defaults to use a `/client` directory for source code
19
73
@@ -29,47 +83,71 @@ mv app/javascript client
29
83
source_path: client
30
84
```
31
85
32
-
## Moving node_modules from `/` to `/client` with a custom Webpack setup
86
+
## Styling Your Components
33
87
34
-
Shakapacker probably doesn't support having your main `node_modules` directory under `/client`, so only follow these steps if you want to use your own Webpack configuration.
88
+
React on Rails supports multiple approaches for styling your components. The modern recommended approach uses **CSS Modules** with co-located stylesheets.
35
89
36
-
1. Move the `/package.json` to `/client/package.json`
37
-
2. Create a `/package.json` that delegates to `/client/package.json`.
38
-
```json
39
-
"scripts": {
40
-
"heroku-postbuild": "cd ./client && yarn"
41
-
},
42
-
```
43
-
3. If your `node_modules` directory is not at the top level of the Rails project, then you will need to set the
44
-
ENV value of `SHAKAPACKER_CONFIG` to the location of the `config/shakapacker.yml` file per [rails/webpacker PR 2561](https://github.com/rails/webpacker/pull/2561). (Notice the change of spelling from Webpacker to Shakapacker)
90
+
### Modern Approach: CSS Modules (Recommended)
45
91
46
-
## CSS, Sass, Fonts, and Images
92
+
The generator creates components with CSS Module support out of the box:
47
93
48
-
Should you move your styling assets to Webpack, or stick with the plain Rails asset pipeline? It depends!
94
+
```text
95
+
app/javascript/src/HelloWorld/
96
+
├── ror_components/
97
+
│ ├── HelloWorld.client.jsx
98
+
│ └── HelloWorld.module.css # Co-located with component
99
+
```
49
100
50
-
Here's a good discussion of this option: [Why does Rails 6 include both Webpacker and Sprockets?](https://rossta.net/blog/why-does-rails-install-both-webpacker-and-sprockets.html).
This isn't really a technique, as you keep handling all your styling assets using Rails standard tools, such as using the [sass-rails gem](https://rubygems.org/gems/sass-rails/versions/5.0.4). Basically, Webpack doesn't get involved with styling. Your Rails layouts just continue doing the styling the standard Rails way.
110
+
**Benefits:**
57
111
58
-
#### Advantages to the Simple Rails Way
112
+
-**Scoped styles**: Class names are automatically scoped to prevent conflicts
113
+
-**Co-location**: Styles live next to their components for better organization
114
+
-**Type safety**: Works seamlessly with TypeScript
115
+
-**Hot reloading**: Style changes reload instantly without page refresh
116
+
-**Zero configuration**: Works out of the box with the generator
59
117
60
-
1. Much simpler! There's no change from your current processes.
118
+
### Alternative: Rails Asset Pipeline
61
119
62
-
### Using Webpack to Manage Styling Assets
120
+
You can continue using Rails' traditional asset pipeline with [sass-rails](https://rubygems.org/gems/sass-rails) or similar gems:
63
121
64
-
This technique involves customization of the Webpack config files to generate CSS, image, and font assets.
1. `/client/app/assets`: Assets for CSS for client app.
69
-
1. `/client/app/assets/fonts` and `/client/app/assets/styles`: Globally shared assets for styling. Note, most Sass and image assets will be stored next to the JavaScript files.
129
+
- You have existing Rails stylesheets you want to keep
130
+
- You prefer keeping styles completely separate from JavaScript
131
+
- You don't need component-scoped styling
70
132
71
-
#### Advantages to having Webpack Manage Styles
133
+
###Advanced: Global Styles with Webpack
72
134
73
-
1. You can use [CSS modules](https://github.com/css-modules/css-modules), which is super compelling once you see the benefits.
74
-
1. You can use CSS in JS.
75
-
1. You can do hot reloading of your assets. Thus, you do not have to refresh your web page to see asset change, including changing styles.
135
+
For global styles (fonts, resets, variables), you can create additional webpack entry points:
0 commit comments