Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -522,23 +522,58 @@ As of version 13.3.4, bundles inside directories that match `config.components_s

#### 2. CSS not loading (FOUC - Flash of Unstyled Content)

**Problem**: Components load but CSS styles are missing or delayed.
**Problem**: Components load but CSS styles are missing or delayed, particularly with server-side rendering and `auto_load_bundle = true`.

**Important**: FOUC (Flash of Unstyled Content) **only occurs with HMR (Hot Module Replacement)**. Static and production modes work perfectly without FOUC.
**Root Cause**: When using `auto_load_bundle = true`, `react_component` calls automatically invoke `append_stylesheet_pack_tag` during rendering. However, Shakapacker requires these appends to execute BEFORE the main `stylesheet_pack_tag` in your layout's `<head>`. Since Rails renders the layout's `<head>` before the `<body>` (where `react_component` calls typically occur), the appends happen too late, causing FOUC.

**Solutions**:
**Solution**: Use the `content_for :body_content` pattern documented in Shakapacker's [Preventing FOUC guide](https://github.com/shakacode/shakapacker/blob/master/docs/preventing_fouc.md#the-content_for-body_content-pattern).

This pattern renders your body content first, ensuring all `react_component` auto-appends execute before the `<head>` renders:

```erb
<%# Step 1: This block executes first, capturing content AND triggering auto-appends %>
<% content_for :body_content do %>
<%= react_component "NavigationBarApp", prerender: true %>

<div class="container">
<%= yield %>
</div>

<%= react_component "Footer", prerender: true %>
<% end %>
<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%# Step 2: Head renders with all accumulated stylesheet/JS appends %>
<%= stylesheet_pack_tag(media: 'all') %>
<%= javascript_pack_tag(defer: true) %>
</head>
<body>
<%# Step 3: Finally, the captured body_content is rendered here %>
<%= yield :body_content %>
</body>
</html>
```

**Note**: While defining body content before `<!DOCTYPE html>` may seem counter-intuitive, Rails processes the `content_for` block first (capturing content and triggering appends), then renders the HTML in proper document order.

**Alternative**: If the `content_for` pattern doesn't fit your needs, disable auto-loading and manually specify packs:

```ruby
# config/initializers/react_on_rails.rb
config.auto_load_bundle = false
```

- **Development with HMR** (`./bin/dev`): FOUC is expected behavior due to dynamic CSS injection - **not a bug**
- **Development static** (`./bin/dev static`): No FOUC - CSS is extracted to separate files like production
- **Production** (`./bin/dev prod`): No FOUC - CSS is extracted and optimized
- **Layout**: Verify your layout includes empty `<%= stylesheet_pack_tag %>` placeholder for CSS injection
- **Component imports**: Check that CSS files are properly imported: `import styles from './Component.module.css';`
**Additional Resources**:

**Key insight**: Choose your development mode based on your current needs:
- **Complete FOUC prevention guide**: [Shakapacker Preventing FOUC documentation](https://github.com/shakacode/shakapacker/blob/master/docs/preventing_fouc.md)
- **Working example**: [react-webpack-rails-tutorial PR #686](https://github.com/shakacode/react-webpack-rails-tutorial/pull/686)
- **Related issue**: [Shakapacker #720](https://github.com/shakacode/shakapacker/issues/720)

- Use HMR for fastest development (accept FOUC)
- Use static mode when testing styling without FOUC
- Use production mode for final testing
**Note**: HMR-related FOUC in development mode (dynamic CSS injection) is separate from this SSR auto-loading issue. See Shakapacker docs for details.

#### 3. "document is not defined" errors during SSR

Expand Down
42 changes: 35 additions & 7 deletions docs/deployment/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ Having issues with React on Rails? This guide covers the most common problems an

### Is your issue with...?

| Problem Area | Quick Check | Go to Section |
| -------------------- | ------------------------------------------- | -------------------------------------------- |
| **Installation** | Generator fails or components don't appear | [Installation Issues](#-installation-issues) |
| **Compilation** | Webpack errors, build failures | [Build Issues](#-build-issues) |
| **Runtime** | Components not rendering, JavaScript errors | [Runtime Issues](#-runtime-issues) |
| **Server Rendering** | SSR not working, hydration mismatches | [SSR Issues](#-server-side-rendering-issues) |
| **Performance** | Slow builds, large bundles, memory issues | [Performance Issues](#-performance-issues) |
| Problem Area | Quick Check | Go to Section |
| -------------------- | ------------------------------------------- | ------------------------------------------------------------ |
| **Installation** | Generator fails or components don't appear | [Installation Issues](#-installation-issues) |
| **Compilation** | Webpack errors, build failures | [Build Issues](#-build-issues) |
| **Runtime** | Components not rendering, JavaScript errors | [Runtime Issues](#-runtime-issues) |
| **Styling (FOUC)** | Unstyled content flash with SSR | [Flash of Unstyled Content](#flash-of-unstyled-content-fouc) |
| **Server Rendering** | SSR not working, hydration mismatches | [SSR Issues](#-server-side-rendering-issues) |
| **Performance** | Slow builds, large bundles, memory issues | [Performance Issues](#-performance-issues) |

## 🚨 Installation Issues

Expand Down Expand Up @@ -164,6 +165,33 @@ useEffect(() => {
<% end %>
```

### "Flash of Unstyled Content (FOUC)"

**Symptoms:** Page briefly shows unstyled content before CSS loads, particularly with SSR and `auto_load_bundle`

**Root Cause:** When using `auto_load_bundle = true` with server-side rendering, `react_component` calls trigger `append_stylesheet_pack_tag` during body rendering, but these appends must execute BEFORE the `stylesheet_pack_tag` in the `<head>`.

**Solution:** Use the `content_for :body_content` pattern to ensure appends happen before the head renders.

**See:** [FOUC Prevention Guide](../core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md#2-css-not-loading-fouc---flash-of-unstyled-content) for detailed solutions and examples.

**Quick fix:**

```erb
<% content_for :body_content do %>
<%= react_component "MyComponent", prerender: true %>
<% end %>
<!DOCTYPE html>
<html>
<head>
<%= stylesheet_pack_tag(media: 'all') %>
</head>
<body>
<%= yield :body_content %>
</body>
</html>
```

## 🖥️ Server-Side Rendering Issues

### "Server rendering not working"
Expand Down
Loading