Skip to content

Document Turbo/Hotwire integration with auto-registration (#2342)#2345

Merged
justin808 merged 3 commits intomasterfrom
jg/fix-2342
Feb 4, 2026
Merged

Document Turbo/Hotwire integration with auto-registration (#2342)#2345
justin808 merged 3 commits intomasterfrom
jg/fix-2342

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Feb 4, 2026

Summary

  • Documents the content_for :body_content pattern needed when using auto_load_bundle with Turbo
  • Explains the ordering conflict between Turbo's head loading requirement and auto-registration's dynamic pack tag appending
  • Provides a working layout example with step-by-step comments
  • Links to related Shakapacker FOUC guide and Turbo documentation

Related Issue

Closes #2342

Test plan

  • Documentation renders correctly in GitHub
  • Code examples are syntactically correct
  • Links to external docs are valid

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added "Turbo with Auto-Bundling" subsection with guidance to resolve bundle ordering when using Turbo alongside auto-bundling tools
    • Provides a practical example and stepwise rationale to ensure correct head/body bundle ordering and address unusual template ordering
    • Updated additional resources: Shakapacker link now points to main branch and a Turbo/Hotwire integration entry was added
    • Turbo Streams and legacy content remain intact

Document the content_for :body_content pattern needed when using
auto_load_bundle: true with Turbo. This addresses the ordering
conflict between Turbo's head loading requirement and auto-registration's
dynamic pack tag appending during body rendering.

Closes #2342

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 4, 2026

Walkthrough

Adds documentation describing a Turbo + auto-bundling load-order conflict and documents the content_for :body_content workaround with a full ERB example, rationale, and resource links.

Changes

Cohort / File(s) Summary
Turbo Auto‑Bundling Docs
docs/building-features/turbolinks.md
Adds "Turbo with Auto-Bundling" subsection: describes ordering conflicts between Turbo (head), auto-appended pack tags (body), and Shakapacker; provides a complete content_for :body_content ERB example, step-by-step rationale, and links to resources.
Auto‑Bundling Resources
docs/core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md
Updates "Additional Resources": changes Shakapacker link branch from master to main and adds a Turbo/Hotwire integration resource entry.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • Romex91
  • alexeyr-ci2

Poem

🐰 I nudged the head and saved the night,
Captured the body, set bundles right.
Turbo hums quiet, scripts fall in line,
A rabbit’s small hop — load order divine. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: documenting Turbo/Hotwire integration with auto-registration, which matches the PR's primary objective of adding documentation for the content_for pattern.
Linked Issues check ✅ Passed The PR fully meets the primary objective from issue #2342: it documents the content_for :body_content pattern as a workaround for the ordering conflict between Turbo, React on Rails auto-registration, and Shakapacker, with a complete ERB example and step-by-step rationale.
Out of Scope Changes check ✅ Passed All changes are scoped to documentation files: adding a new subsection about Turbo integration in turbolinks.md and updating resource links in auto-bundling.md, both directly supporting the issue's documentation objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jg/fix-2342

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 4, 2026

Code Review for PR #2345

Summary

This PR adds excellent documentation for a common pain point when using Turbo/Hotwire with React on Rails' auto-registration feature. The documentation is clear, well-structured, and addresses issue #2342 effectively.

✅ Strengths

  1. Clear Problem Statement: The "The Challenge" section excellently explains the three-way conflict between Turbo's requirements, auto-registration behavior, and Shakapacker's ordering constraints.

  2. Well-Structured Solution: The step-by-step numbered comments in the ERB example make it easy to follow the execution flow.

  3. Consistent with Existing Docs: The pattern and explanation align perfectly with similar documentation in:

    • docs/core-concepts/auto-bundling-file-system-based-automated-bundle-generation.md
    • docs/deployment/troubleshooting.md
  4. Good External References: Links to Shakapacker's FOUC guide and Turbo Handbook provide additional context.

  5. Addresses Edge Case: The "Note" about unusual placement of content_for before <!DOCTYPE html> preemptively answers a common question.

📝 Suggestions for Improvement

1. Minor: Consistent Terminology

The document uses both "auto-registration" and "auto-bundling" to refer to the same feature. Consider being consistent:

  • Line 57: "auto-registration feature"
  • Linked doc uses: "auto-bundling"

Suggestion: Since the linked doc is titled "auto-bundling-file-system-based-automated-bundle-generation.md", consider using "auto-bundling" or "auto-loading" consistently, or define both terms once.

2. Enhancement: Add Cross-Reference

Consider adding a reciprocal link from the auto-bundling docs back to this Turbo section, since that doc also mentions the content_for pattern but in a different context (FOUC prevention).

3. Minor: ERB Example Completeness

The example shows explicit appends:

<%= append_stylesheet_pack_tag('stimulus-bundle') %>
<%= append_javascript_pack_tag('stimulus-bundle') %>
<%= append_javascript_pack_tag('stores-registration') %>

Question: Are these explicit appends necessary in the example, or would the auto-appends from react_component be sufficient? Consider clarifying why these are shown (e.g., "Optional: If you need to explicitly load Stimulus...").

4. Enhancement: Link Validation

The external links look correct but couldn't be validated in this environment:

Suggestion: Before merging, manually verify these links are accessible and point to the correct sections.

🔍 Technical Correctness

ERB Syntax: All code blocks use correct ERB syntax
Rails Patterns: The content_for usage is idiomatic Rails
React on Rails API: Correctly uses react_component, auto_load_bundle: true, prerender: true
Shakapacker Integration: Correctly uses javascript_pack_tag, append_javascript_pack_tag
Internal Links: Reference to auto-bundling doc is correct

🎯 Test Coverage

Per the PR description, the checklist items are:

  • Documentation renders correctly in GitHub ✅ (Markdown syntax looks good)
  • Code examples are syntactically correct ✅ (ERB syntax verified)
  • Links to external docs are valid ⚠️ (Unable to verify in this environment, requires manual check)

📋 Pre-Merge Checklist

Based on CLAUDE.md requirements:

  • Manually verify external links work
  • Run bundle exec rubocop (no Ruby files changed, so this should be clean)
  • Run pnpm run format.listDifferent to check Markdown formatting
  • Verify the documentation renders correctly when viewed on GitHub

🎉 Recommendation

LGTM with minor suggestions! This is high-quality documentation that will save users significant debugging time. The suggestions above are optional improvements - none are blockers.

The PR effectively addresses issue #2342 by documenting a non-obvious but necessary pattern for combining Turbo with auto-registration. This will be a valuable reference for the community.

Suggested next steps:

  1. Verify external links manually
  2. Run formatters to ensure no trailing issues
  3. Consider the terminology consistency suggestion
  4. Merge! 🚀

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Feb 4, 2026

Greptile Overview

Greptile Summary

This PR adds documentation for using Turbo/Hotwire with React on Rails' auto-registration feature, addressing issue #2342.

Key Changes:

  • Documents the content_for :body_content pattern needed when using auto_load_bundle: true with Turbo
  • Explains the ordering conflict: Turbo needs to load in <head>, but auto-registration appends pack tags during body rendering
  • Provides a complete layout example with step-by-step comments showing how to structure the template
  • Links to Shakapacker's FOUC prevention guide and Turbo documentation for additional context

Technical Accuracy:
The documentation correctly describes how Rails' content_for block evaluation works and how it solves the script loading order problem. The ERB syntax in the code examples is valid, and the explanation accurately reflects how append_javascript_pack_tag is called by the react_component helper when auto_load_bundle is enabled.

Confidence Score: 5/5

  • This PR is safe to merge with no risks - it only adds documentation
  • Score reflects that this is a documentation-only change with accurate technical content, valid code examples, and proper linking to related resources
  • No files require special attention

Important Files Changed

Filename Overview
docs/building-features/turbolinks.md Added comprehensive documentation for using Turbo with auto-registration, including the content_for :body_content pattern to solve script loading order issues

Sequence Diagram

sequenceDiagram
    participant Rails as Rails Template Engine
    participant CF as content_for Block
    participant RC as react_component Helper
    participant Pack as Pack Tag Accumulator
    participant Head as HTML Head
    participant Body as HTML Body

    Note over Rails,Body: Step 1: Process content_for block FIRST
    Rails->>CF: Evaluate content_for :body_content block
    CF->>RC: Call react_component with auto_load_bundle: true
    RC->>Pack: append_javascript_pack_tag("generated/ComponentName")
    Pack-->>RC: Bundle registered
    RC-->>CF: Return component HTML
    CF-->>Rails: Body content captured (not yet output)

    Note over Rails,Body: Step 2: Render HTML head
    Rails->>Head: Render <head> section
    Head->>Pack: javascript_pack_tag (retrieve all appended packs)
    Pack-->>Head: Return script tags for all accumulated bundles
    Head-->>Rails: Head rendered with all component bundles

    Note over Rails,Body: Step 3: Output body content
    Rails->>Body: yield :body_content
    Body-->>Rails: Output previously captured HTML

    Note over Rails,Body: Result: Correct loading order achieved
Loading

- Use "auto-bundling" terminology consistently (matching linked doc title)
- Clarify ERB example: explicit appends are for non-React packs
- Update Shakapacker link from master to main branch
- Add cross-reference from auto-bundling FOUC section back to Turbo docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 4, 2026

Code Review: Documentation for Turbo/Hotwire Integration with Auto-Registration

✅ Overall Assessment

This PR provides excellent documentation for a common integration challenge. The addition is well-written, technically accurate, and directly addresses issue #2342. Great work!


🎯 Strengths

  1. Clear Problem Statement: The "Challenge" section effectively explains the ordering conflict between Turbo's head loading requirement, auto-registration's dynamic pack tag appending, and Shakapacker's requirements.

  2. Practical Solution: The content_for :body_content pattern is clearly explained with a complete, working layout example that developers can directly adapt.

  3. Step-by-Step Explanation: The numbered comments in the ERB example (Step 1, 2, 3) make it easy to understand the execution flow.

  4. "Why This Works" Section: Excellent addition that explains the underlying Rails template processing behavior.

  5. Good Cross-References:

    • Links to Shakapacker FOUC prevention guide (correctly updated to main branch)
    • Links to official Turbo documentation
    • Bidirectional cross-reference with auto-bundling docs
  6. Addresses Confusion: The note about content_for appearing before <!DOCTYPE html> preemptively addresses a common source of confusion.


📝 Minor Suggestions

1. ERB Example - Minor Clarification

In the ERB example at lines 89-93, the comment says:

<%# Optional: Explicitly load non-React packs (Stimulus, shared stores, etc.) %>
<%# React component bundles are auto-appended by react_component calls above %>

Suggestion: This is already clear, but you could add one more line to emphasize the key point:

<%# Optional: Explicitly load non-React packs (Stimulus, shared stores, etc.) %>
<%# React component bundles are already auto-appended by react_component calls above %>
<%# Do NOT manually append component bundles here - they're already included %>

This extra emphasis might prevent users from redundantly adding component packs manually.

2. Consider Adding a Common Pitfall Section

You might consider adding a brief "Common Pitfalls" callout:

**Common Pitfalls:**
- ❌ Don't place `javascript_pack_tag` before `content_for` blocks that call `react_component`
- ❌ Don't manually append component bundles if using `auto_load_bundle: true`
- ✅ Do let `react_component` handle bundle appending automatically

3. Anchor Link Precision

The cross-reference link in the auto-bundling doc is:

[Using auto-bundling with Turbo](../building-features/turbolinks.md#turbo-with-auto-bundling)

This works great! Just verify the anchor #turbo-with-auto-bundling matches exactly (GitHub auto-generates anchors from headers, and "Turbo with Auto-Bundling" should become turbo-with-auto-bundling).


✅ Technical Accuracy

  • Rails template processing: ✅ Correctly explained
  • Shakapacker pack tag ordering: ✅ Accurate
  • Turbo head loading requirement: ✅ Correct
  • ERB syntax: ✅ Valid
  • External links: ✅ Appear valid (Shakapacker main branch, Turbo Handbook)

🔒 Security Considerations

  • No security concerns identified
  • Standard Rails CSRF and CSP meta tags are included in the example

📊 Test Coverage

Documentation Testing (from PR description):

  • Documentation renders correctly in GitHub
  • Code examples are syntactically correct ✅ (verified)
  • Links to external docs are valid ⚠️ (recommend manual verification)

Recommendation: Before merging, manually verify:

  1. The Shakapacker link: https://github.com/shakacode/shakapacker/blob/main/docs/preventing_fouc.md
  2. The Turbo Handbook link: https://turbo.hotwired.dev/handbook/building#working-with-script-elements

🎨 Style & Conventions

  • ✅ Follows existing documentation structure
  • ✅ Consistent with other feature docs in docs/building-features/
  • ✅ Proper markdown formatting
  • ✅ Code examples use ERB with helpful comments
  • ✅ Professional, clear tone

📚 Documentation Completeness

What's covered:

  • ✅ Problem explanation
  • ✅ Complete working solution
  • ✅ Why it works
  • ✅ External resources

Optional enhancements (not blocking):

  • Could add a "When NOT to use this pattern" section (e.g., if not using auto-bundling)
  • Could mention performance implications (none, but good to state explicitly)

🚀 Recommendation

Approve with minor optional suggestions. This PR is ready to merge as-is. The optional suggestions above are enhancements, not blockers.

The documentation will save developers significant debugging time and addresses a real pain point. Excellent contribution!


✅ Checklist for Merge

Great work on this documentation improvement! 🎉

- Add warning comment: "Do NOT manually append component bundles"
- Add Common Pitfalls section with clear dos and don'ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Feb 4, 2026

Code Review: PR #2345 - Document Turbo/Hotwire Integration with Auto-Registration

Overall Assessment

Excellent documentation addition that addresses a real pain point (#2342) for users combining Turbo with auto-bundling. The writing is clear, well-structured, and provides actionable guidance.

Strengths

  1. Clear Problem Statement: The "The Challenge" section effectively explains the three-way conflict between Turbo's requirements, auto-registration behavior, and Shakapacker's constraints.

  2. Concrete Solution: The ERB example is comprehensive and includes helpful step-by-step comments explaining the execution order.

  3. Educational Content: The "Why This Works" section helps users understand the Rails template evaluation model, not just copy-paste the solution.

  4. Common Pitfalls Section: Proactively addresses likely mistakes users will make.

  5. Cross-references: Good linking between related docs (auto-bundling guide and back).

  6. Link Update: Fixed the Shakapacker link from mastermain branch (good catch!).

Suggestions for Improvement

1. Anchor Link Verification (Minor)

The new content references:

[Shakapacker Preventing FOUC guide](https://github.com/shakacode/shakapacker/blob/main/docs/preventing_fouc.md#the-content_for-body_content-pattern)

The anchor #the-content_for-body_content-pattern should be verified to exist in the Shakapacker docs. If that section doesn't have that exact heading, the link will 404 on the anchor (though GitHub is forgiving about this).

Recommendation: Verify the anchor exists or remove it if uncertain.

2. Code Example Consistency (Minor)

Lines 92-94 show optional manual appends. Consider clarifying whether these are truly "optional" or just examples - when would users need these vs when they wouldn't?

3. Example Specificity (Minor)

The example uses specific component names (NavigationBarApp, Footer). Consider adding a note like:

(Replace NavigationBarApp and Footer with your actual component names)

4. Testing Consideration (Question)

Should there be a working example in the dummy app that demonstrates this pattern? This would:

  • Serve as a living example
  • Ensure the pattern actually works with Turbo enabled
  • Help catch regressions

However, I understand this might be beyond the scope of a documentation PR.

5. Changelog Entry (Important)

According to CLAUDE.md:

Update CHANGELOG.md for user-visible changes only (features, bug fixes, breaking changes, deprecations, performance improvements)

This is a documentation improvement that helps users solve a real problem. Consider adding a changelog entry:

#### Documentation
- [PR 2345](https://github.com/shakacode/react_on_rails/pull/2345) by [justin808](https://github.com/justin808): Document Turbo/Hotwire integration with auto-registration pattern

Technical Correctness

The solution is technically sound:

  • Rails does indeed process content_for blocks during template evaluation
  • The ordering explanation is accurate
  • The pattern correctly addresses the timing issue

Security & Performance

No security concerns: Documentation only, example code follows Rails security best practices
No performance concerns: Documentation only

Style & Conventions

Follows project conventions:

  • Markdown formatting is consistent
  • Emoji usage is appropriate (❌/✅ in Common Pitfalls)
  • Code examples use ERB syntax highlighting
  • Links use proper markdown format

Recommendations

Before merging:

  1. ✅ Verify all external links work (markdown-link-check passed)
  2. ⚠️ Add changelog entry (per CLAUDE.md guidelines)
  3. ⚠️ Consider verifying the Shakapacker anchor link or remove the fragment

Optional enhancements (could be follow-up PRs):

  1. Add working example to react_on_rails/spec/dummy with Turbo enabled
  2. Consider adding a generator template option for Turbo layouts
  3. Add integration test that verifies this pattern works

Final Verdict

APPROVE with minor suggestions

This PR significantly improves the documentation and will help many users struggling with this exact issue. The writing is clear, the solution is correct, and it addresses a real pain point.

The only required change is adding a changelog entry. The other suggestions are optional improvements.


Great work documenting this non-obvious pattern! This will save users hours of debugging. 🎉

@justin808 justin808 merged commit 9839667 into master Feb 4, 2026
3 checks passed
@justin808 justin808 deleted the jg/fix-2342 branch February 4, 2026 04:48
justin808 added a commit that referenced this pull request Feb 8, 2026
)

## Summary

- Documents the `content_for :body_content` pattern needed when using
auto_load_bundle with Turbo
- Explains the ordering conflict between Turbo's head loading
requirement and auto-registration's dynamic pack tag appending
- Provides a working layout example with step-by-step comments
- Links to related Shakapacker FOUC guide and Turbo documentation

## Related Issue

Closes #2342

## Test plan

- [ ] Documentation renders correctly in GitHub
- [ ] Code examples are syntactically correct
- [ ] Links to external docs are valid

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Added "Turbo with Auto-Bundling" subsection with guidance to resolve
bundle ordering when using Turbo alongside auto-bundling tools
* Provides a practical example and stepwise rationale to ensure correct
head/body bundle ordering and address unusual template ordering
* Updated additional resources: Shakapacker link now points to main
branch and a Turbo/Hotwire integration entry was added
  * Turbo Streams and legacy content remain intact
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhancement: Document Turbo/Hotwire integration with auto-registration

1 participant