Bird
Raised Fist0
Ruby on Railsframework~10 mins

Stimulus and Turbo (Hotwire) in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Stimulus and Turbo (Hotwire)
User interacts with page
↓
Turbo intercepts link/form
↓
Turbo fetches HTML via AJAX
↓
Turbo updates page content
↓
Stimulus controller detects changes
↓
Stimulus runs JS behavior
↓
Page updated dynamically without reload
User actions trigger Turbo to fetch and update HTML dynamically, then Stimulus runs JavaScript behaviors on the updated content.
Execution Sample
Ruby on Rails
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    console.log("Hello from Stimulus!")
  }
}
This Stimulus controller logs a message when connected to the page element.
Execution Table
StepActionTurbo BehaviorStimulus BehaviorPage State
1User clicks a link with data-turboIntercepts click, prevents full reloadNo action yetPage stays, no reload
2Turbo fetches new HTML via AJAXLoads new HTML fragmentNo action yetPage content ready to update
3Turbo replaces target element with new HTMLUpdates DOM dynamicallyDetects new elementsPage content updated without reload
4Stimulus controller connects to new elementsNo actionRuns connect() method, logs messageJS behavior active on new content
5User submits form with data-turboIntercepts submit, sends AJAX requestNo action yetForm submission handled dynamically
6Turbo updates page with server responseReplaces part of page with new HTMLStimulus reconnects controllersPage updated, JS behaviors active
7User interacts with Stimulus-controlled elementNo Turbo actionStimulus handles event, runs methodsDynamic interaction without reload
8End of interactionNo further Turbo actionsStimulus remains activePage fully interactive dynamically
💡 User stops interacting or navigates away; Turbo and Stimulus keep page dynamic without full reloads.
Variable Tracker
VariableStartAfter Step 3After Step 4After Step 6Final
Page HTMLInitial full pageUpdated with Turbo HTML fragmentSame as Step 3Updated again with Turbo responseFinal updated page
Stimulus ControllersConnected to initial elementsDisconnected from replaced elementsConnected to new elementsReconnected after Turbo updateActive and ready
Console LogsEmptyEmpty"Hello from Stimulus!""Hello from Stimulus!" (again if reconnected)Logs show Stimulus connect calls
Key Moments - 3 Insights
Why does the page not fully reload when clicking a link with data-turbo?
Because Turbo intercepts the link click (see execution_table step 1) and fetches only the needed HTML via AJAX, updating the page dynamically without a full reload.
How does Stimulus know when to run JavaScript on new content?
Stimulus detects when new elements are added to the page by Turbo (step 4 and 6) and automatically connects controllers to those elements, running their connect() methods.
What happens to Stimulus controllers when Turbo replaces part of the page?
Stimulus disconnects controllers from removed elements and reconnects to new elements after Turbo updates the DOM (see variable_tracker and execution_table steps 3-6).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what happens at step 3?
AUser submits a form
BStimulus disconnects all controllers
CTurbo updates the page content dynamically without reload
DPage fully reloads
💡 Hint
Check the 'Turbo Behavior' and 'Page State' columns at step 3 in the execution_table.
At which step does Stimulus run its connect() method and log a message?
AStep 4
BStep 2
CStep 6
DStep 1
💡 Hint
Look at the 'Stimulus Behavior' column in the execution_table for when connect() runs.
If Turbo did not intercept the form submission at step 5, what would happen?
AStimulus would run connect() again
BThe page would reload fully on form submit
CTurbo would update the page dynamically
DNothing would happen
💡 Hint
Refer to the 'Turbo Behavior' column at step 5 and think about what happens without Turbo interception.
Concept Snapshot
Stimulus and Turbo (Hotwire) work together to make Rails pages dynamic.
Turbo intercepts links and forms to fetch and update HTML without full reloads.
Stimulus runs JavaScript controllers on page elements, connecting automatically after Turbo updates.
This combo creates fast, interactive pages with minimal JavaScript.
Use data-turbo attributes for Turbo and data-controller for Stimulus.
Stimulus connect() runs when elements appear in the DOM.
Full Transcript
This visual execution shows how Stimulus and Turbo (Hotwire) work together in Rails. When a user clicks a link or submits a form with data-turbo, Turbo intercepts the action and fetches new HTML via AJAX instead of reloading the whole page. Turbo then updates the page content dynamically. Stimulus detects these changes and connects its controllers to the new elements, running JavaScript behaviors like logging messages. The execution table traces each step from user interaction to page update and JavaScript activation. Variables like page HTML and Stimulus controllers change state as Turbo updates the DOM and Stimulus reconnects. Key moments clarify why the page does not reload fully, how Stimulus knows to run, and what happens to controllers during updates. The quiz tests understanding of Turbo's interception, Stimulus connection timing, and consequences of missing Turbo interception. The snapshot summarizes the synergy of Turbo and Stimulus for dynamic Rails pages with minimal reloads and JavaScript.

Practice

(1/5)
1. What is the main purpose of Stimulus in a Rails application using Hotwire?
easy
A. To add simple JavaScript behavior to HTML elements using controllers and data attributes
B. To replace the entire page content on every user action
C. To handle database queries efficiently
D. To style HTML elements with CSS

Solution

  1. Step 1: Understand Stimulus role

    Stimulus is designed to add JavaScript behavior to HTML by connecting controllers to elements via data attributes.
  2. Step 2: Compare other options

    Replacing entire page content is Turbo's job, not Stimulus. Database queries and styling are unrelated.
  3. Final Answer:

    To add simple JavaScript behavior to HTML elements using controllers and data attributes -> Option A
  4. Quick Check:

    Stimulus = JavaScript behavior via controllers [OK]
Hint: Stimulus controls behavior, Turbo controls page updates [OK]
Common Mistakes:
  • Confusing Turbo's page update role with Stimulus
  • Thinking Stimulus handles styling or database
  • Assuming Stimulus reloads full pages
2. Which of the following is the correct way to connect a Stimulus controller named hello to a button element?
easy
A. Click me
B. Click me
C. Click me
D. Click me

Solution

  1. Step 1: Recall Stimulus controller connection syntax

    Stimulus controllers are connected using the data-controller attribute with the controller name.
  2. Step 2: Verify other attributes

    data-action defines event handlers, data-target defines targets inside controllers, data-connect is invalid.
  3. Final Answer:

    <button data-controller="hello">Click me</button> -> Option B
  4. Quick Check:

    Controller connection uses data-controller [OK]
Hint: Use data-controller to link Stimulus controllers [OK]
Common Mistakes:
  • Using data-action instead of data-controller to connect controller
  • Confusing data-target with controller connection
  • Using non-existent data-connect attribute
3. Given this Stimulus controller code:
export default class extends Controller {
  static targets = ["output"]
  greet() {
    this.outputTarget.textContent = "Hello, Stimulus!"
  }
}
and this HTML:
<div data-controller="greeting">
  <button data-action="click->greeting#greet">Say Hello</button>
  <span data-greeting-target="output"></span>
</div>
What happens when the button is clicked?
medium
A. The span text changes to 'Hello, Stimulus!'
B. Nothing happens because the controller name is wrong
C. The page reloads
D. An error is thrown because outputTarget is undefined

Solution

  1. Step 1: Match controller and targets

    The controller is named 'greeting' and defines an output target. The HTML uses data-controller="greeting" and data-greeting-target="output" correctly.
  2. Step 2: Understand the greet method and action

    The button triggers greet on click, which sets the outputTarget's textContent to 'Hello, Stimulus!'.
  3. Final Answer:

    The span text changes to 'Hello, Stimulus!' -> Option A
  4. Quick Check:

    Correct controller and target update text [OK]
Hint: Check controller name matches data-controller and targets [OK]
Common Mistakes:
  • Mismatching controller name and data-controller attribute
  • Forgetting to define static targets array
  • Expecting page reload instead of DOM update
4. Identify the error in this Turbo Frame usage:
<turbo-frame id="messages">
  <%= render @messages %>
</turbo-frame>
When a new message is created, the frame does not update automatically. What is the likely cause?
medium
A. The frame id should be messages_frame instead of messages
B. Turbo Frames cannot render collections
C. The render call is missing a partial
D. The server response does not include a turbo-frame with matching id

Solution

  1. Step 1: Understand Turbo Frame update mechanism

    Turbo Frames update only if the server response includes a turbo-frame element with the same id as the frame on the page.
  2. Step 2: Identify the problem

    If the server response lacks a matching turbo-frame wrapper, Turbo cannot replace the frame content automatically.
  3. Final Answer:

    The server response does not include a <turbo-frame> with matching id -> Option D
  4. Quick Check:

    Matching turbo-frame id in response is required [OK]
Hint: Ensure server response wraps content in matching turbo-frame id [OK]
Common Mistakes:
  • Changing frame id arbitrarily
  • Assuming Turbo Frames can't render collections
  • Forgetting to wrap response in turbo-frame tag
5. You want to create a live search feature using Turbo and Stimulus. Which approach correctly combines both to update search results as the user types without full page reload?
hard
A. Use Stimulus to reload the whole page manually on input change
B. Use Turbo Frames alone to reload the entire page on every keystroke
C. Use a Stimulus controller to listen for input events, send fetch requests to the server, and update a Turbo Frame with the results
D. Use Turbo Streams to replace the entire page content on input

Solution

  1. Step 1: Understand live search requirements

    Live search updates results dynamically as the user types without full reload.
  2. Step 2: Combine Stimulus and Turbo correctly

    Stimulus listens to input events and sends fetch requests. Turbo Frame updates only the results part of the page.
  3. Step 3: Evaluate other options

    Reloading entire page on every keystroke is inefficient. Turbo Streams replace parts but need server push. Stimulus alone can't reload page efficiently.
  4. Final Answer:

    Use a Stimulus controller to listen for input events, send fetch requests to the server, and update a Turbo Frame with the results -> Option C
  5. Quick Check:

    Stimulus + Turbo Frame = dynamic partial updates [OK]
Hint: Stimulus handles events, Turbo Frame updates partial content [OK]
Common Mistakes:
  • Reloading full page on every input
  • Using Turbo Frames without Stimulus for input events
  • Misusing Turbo Streams for full page replacement
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard