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
Document content_for pattern to prevent FOUC with SSR and auto_load_bundle
Fixes#1864
When using auto_load_bundle = true with server-side rendering, there's a
chicken-and-egg problem: stylesheets must load in the <head>, but
react_component calls in <body> trigger auto-appends after the head has
rendered, causing FOUC (Flash of Unstyled Content).
This commit documents the content_for workaround pattern that ensures all
react_component calls happen before the head renders, preventing FOUC.
Key improvements:
- Explains the root cause of FOUC with SSR + auto_load_bundle
- Documents the content_for :body_content pattern with full example
- Provides alternative solutions (disable auto_load_bundle, manual packs)
- Clarifies that HMR FOUC is separate from this SSR issue
- References working example in react-webpack-rails-tutorial PR #686
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Copy file name to clipboardExpand all lines: docs/core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md
+63-10Lines changed: 63 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -522,23 +522,76 @@ As of version 13.3.4, bundles inside directories that match `config.components_s
522
522
523
523
#### 2. CSS not loading (FOUC - Flash of Unstyled Content)
524
524
525
-
**Problem**: Components load but CSS styles are missing or delayed.
525
+
**Problem**: Components load but CSS styles are missing or delayed, particularly with server-side rendering and `auto_load_bundle = true`.
526
526
527
-
**Important**: FOUC (Flash of Unstyled Content) **only occurs with HMR (Hot Module Replacement)**. Static and production modes work perfectly without FOUC.
527
+
**Root Cause with SSR + auto_load_bundle**: Shakapacker requires `append_stylesheet_pack_tag` to be called before `stylesheet_pack_tag` renders. However, with SSR and `auto_load_bundle = true`, `react_component` calls in the `<body>` automatically call `append_stylesheet_pack_tag`, but this happens AFTER the `<head>` (which contains `stylesheet_pack_tag`) has already been rendered. This creates a chicken-and-egg problem causing FOUC.
528
528
529
529
**Solutions**:
530
530
531
-
- **Development with HMR** (`./bin/dev`): FOUC is expected behavior due to dynamic CSS injection - **not a bug**
532
-
- **Development static** (`./bin/dev static`): No FOUC - CSS is extracted to separate files like production
531
+
**Option 1: Use content_for pattern (Recommended for SSR + auto_load_bundle)**
532
+
533
+
Render your body content BEFORE the head using Rails `content_for` blocks. This ensures all `react_component` calls (and their auto-appends) happen before the head renders:
<!-- All auto-appended stylesheets will be included here -->
552
+
<%= stylesheet_pack_tag(media: 'all') %>
553
+
<%= javascript_pack_tag(defer: true) %>
554
+
</head>
555
+
<body>
556
+
<%= yield :body_content %>
557
+
</body>
558
+
</html>
559
+
```
560
+
561
+
**Note**: While this pattern may seem counter-intuitive (body content before `<!DOCTYPE html>`), it ensures proper stylesheet loading order and prevents FOUC.
562
+
563
+
**Option 2: Disable auto_load_bundle and manually manage packs**
564
+
565
+
If the `content_for` pattern doesn't fit your architecture, set `auto_load_bundle = false` and manually manage pack loading:
0 commit comments