Table Of ContentUnder Construction: The book you’re reading is still under
development. As part of our Beta book program, we’re releasing
ß this copy well before a normal book would be released. That
way you’re able to get this content a couple of months before
it’s available in finished form, and we’ll get feedback to make
the book even better. The idea is that everyone wins!
Be warned: The book has not had a full technical edit, so it will contain errors.
It has not been copyedited, so it will be full of typos, spelling mistakes, and the
occasional creative piece of grammar. And there’s been no effort spent doing
layout, so you’ll find bad page breaks, over-long code lines, incorrect hyphen-
ation, and all the other ugly things that you wouldn’t expect to see in a finished
book. It also doesn't have an index. We can’t be held liable if you use this book
to try to create a spiffy application and you somehow end up with a strangely
shaped farm implement instead. Despite all this, we think you’ll enjoy it!
Download Updates: Throughout this process you’ll be able to get updated
ebooks from your account at pragprog.com/my_account. When the book is com-
plete, you’ll get the final version (and subsequent updates) from the same ad-
dress.
Send us your feedback: In the meantime, we’d appreciate you sending us your
feedback on this book at pragprog.com/titles/nrclient/errata, or by using the links
at the bottom of each page.
Thank you for being part of the Pragmatic community!
The Pragmatic Bookshelf
Modern Front-End Development for Rails
Hotwire, Stimulus, Turbo, and React
Noel Rappin
The Pragmatic Bookshelf
Raleigh, North Carolina
Many of the designations used by manufacturers and sellers to distinguish their products
are claimed as trademarks. Where those designations appear in this book, and The Pragmatic
Programmers, LLC was aware of a trademark claim, the designations have been printed in
initial capital letters or in all capitals. The Pragmatic Starter Kit, The Pragmatic Programmer,
Pragmatic Programming, Pragmatic Bookshelf, PragProg and the linking g device are trade-
marks of The Pragmatic Programmers, LLC.
Every precaution was taken in the preparation of this book. However, the publisher assumes
no responsibility for errors or omissions, or for damages that may result from the use of
information (including program listings) contained herein.
For our complete catalog of hands-on, practical, and Pragmatic content for software devel-
opers, please visit https://pragprog.com.
For sales, volume licensing, and support, please contact support@pragprog.com.
For international rights, please contact rights@pragprog.com.
Copyright © 2021 The Pragmatic Programmers, LLC.
All rights reserved. No part of this publication may be reproduced, stored in a retrieval system,
or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording,
or otherwise, without the prior consent of the publisher.
ISBN-13: 978-1-68050-721-8
Encoded using the finest acid-free high-entropy binary digits.
Book version: B9.0—June 9, 2021
Contents
Change History . . . . . . . . . . . . vii
Acknowledgments . . . . . . . . . . . xi
So You Want to Write Some Client-Side Code . . . . xiii
Part I — Getting Started
1. Getting Started with Client-Side Rails . . . . . . . 3
Managing State and Front-End Development 4
Configuring Webpacker 9
Using Webpacker 15
What’s Next 17
2. Hotwire and Turbo . . . . . . . . . . . 19
The Hotwire Way 19
Installing Turbo 20
What Is Turbo Drive? 21
Adding Interactivity with Turbo Frames 22
Navigating Outside a Turbo Frame 26
Extending Our Page with Turbo Streams 30
Turbo Frames vs. Turbo Streams 33
Lazy Loading a Turbo Frame 34
What’s Next 36
3. Stimulus . . . . . . . . . . . . . 37
What Is Stimulus? 37
Installing Stimulus 39
Adding Our First Controller 41
Creating an Action 44
Adding a Target 46
Contents • iv
Using Values 48
Automating Value Changes 51
Stimulus Has Class 53
Going Generic 55
Stimulus Quick Reference 59
What’s Next 60
4. React . . . . . . . . . . . . . . 61
What Is React? 61
Installing React 62
Adding Our First Component 64
Composing Components 69
Connecting to the Page 72
Interactivity, State, and Hooks 75
Sharing State 78
What’s Next 87
5. Cascading Style Sheets . . . . . . . . . . 89
Building CSS in webpack 89
Adding CSS and Assets to webpack 92
Animating CSS 93
Adding CSS Transitions 96
Animating Turbo Streams with Animate.css 100
Using CSS and React Components 103
What’s Next 110
Part II — Going Deeper
6. TypeScript . . . . . . . . . . . . . 113
Using TypeScript 114
Understanding Basic TypeScript Types 114
Static vs. Dynamic Typing 116
Adding Type Annotations to Variables 118
Adding Type Annotations to Functions 119
Adding Type Annotations to Classes 123
Defining Interfaces 125
Type Checking Classes and Interfaces 126
Getting Type Knowledge to TypeScript 128
What’s Next 129
Contents • v
7. webpack . . . . . . . . . . . . . 131
Understanding Why webpack Exists 132
Managing Dependencies with Yarn 133
Understanding webpack Configuration 138
What’s Next 145
8. Webpacker . . . . . . . . . . . . . 147
Webpacker Basics 147
Writing Code Using Webpacker 148
Integrating Webpacker with Frameworks 150
Running webpack 152
Deploying Webpacker in Production 153
Customizing Webpacker 153
What’s Next 155
Part III — Managing Servers and State
9. Talking to the Server . . . . . . . . . . 159
Using Stimulus to Manage Forms 159
Stimulus and Ajax 167
Using Data in Stimulus 168
Acquiring Data in React with useState 172
What’s Next 184
10. Immediate Communication with ActionCable . . . . 185
Installing ActionCable 186
Turbo Streams and ActionCable 187
Stimulus and ActionCable 195
React and ActionCable 200
What’s Next 207
11. Managing State in Stimulus Code . . . . . . . 209
Using Data Values for Logic 209
Observing and Responding to DOM Changes 212
Rendering CSS with Data Attributes 218
What’s Next 224
12. Managing State in React . . . . . . . . . 225
Using Reducers 225
Using Context to Share State 227
Contents • vi
Adding Asynchronous Events to Contexts 245
What’s Next 249
13. Using Redux to Manage State . . . . . . . . 251
Installing and Using Redux 252
Adding Asynchronous Actions to Redux 257
What’s Next 264
Part IV — Validating Your Code
14. Validating Code with Advanced TypeScript . . . . . 267
Creating Union Types 267
Specifying Types with Literal Types 272
Using Enums and Literal Types 275
Building Mapped Types and Utility Types 278
TypeScript Configuration Options 279
Dealing with Strictness 281
What’s Next 285
15. Testing with Cypress . . . . . . . . . . 287
Why Cypress? 288
Installing Cypress 288
Configuring Cypress and Rails 292
Writing Our First Test 296
Understanding How Cypress Works 300
What’s Next 307
16. More Testing and Troubleshooting . . . . . . . 309
Writing More Cypress Tests 309
Testing the Schedule Filter 311
Cypress and React 314
Cypress Utilities and API 316
Troubleshooting 317
What’s Next 319
A1. Framework Swap . . . . . . . . . . . 321
The All-Hotwire App 323
The All-React App 336
Comparison 354
Index . . . . . . . . . . . . . . 357
Change History
The book you’re reading is in beta. This means we update it frequently. Here
is a list of the major changes that have been made at each beta release of the
book, with the most recent change first.
Beta 9—June 9, 2021
• Production is complete. Now it’s heading to layout and the printer.
Beta 8—April 27, 2021
The book is content-complete and heading to production.
Final changes here are based on issues raised by reviewers or early readers.
There are a couple of specific items worth calling out:
• The code now is based on Ruby 3.0 and says so in the text.
• Code samples have been moved to a chapter_xx/xx naming structure, which
should make the code easier to follow.
• All the code now uses Webpacker 6.0 beta 6, for real, and as a result all
the JavaScript code moved to app/packs rather than app/javascript.
• Due to a configuration error in earlier versions of the book, the beta 7
code wasn’t properly doing TypeScript type checking. It is now, which
resulted in some minor code changes and a significantly different discus-
sion of null types in Chapter 14, Validating Code with Advanced Type-
Script, on page 267.
• The code got a general polish. The biggest differences are in Chapter 2,
Hotwire and Turbo, on page 19, where there are some changes based on
updates and clarifications to Turbo, and in Chapter 12, Managing State
in React, on page 225, where we changed the code to use fetch rather than
HTML for the initial data load.
Beta 7—March 11, 2021
This is a big one. Sorry to have kept you waiting on this.
report erratum • discuss
Change History • viii
Since the last beta, the Rails team released Hotwire, which bundles Stimulus
with an expanded version of Turbolinks called Turbo. Turbo makes all kinds
of client-side interactions possible with much less JavaScript. We’ve been
waiting a long time for this release, and it has prompted a significant rewrite
of large sections of the book. Here’s the list:
• Chapter 1, Getting Started with Client-Side Rails, on page 3 now includes
turbo-rails, and also assumes that you’ve installed Webpacker as part of
your initial Rails setup.
• We’ve updated to Rails 6.1, React 17, Webpacker 6.0 beta, Typescript 4.2,
and Ruby 3.0, though I don’t think the Ruby version will break anything
for anybody.
• The CSS for all examples is now Tailwind 2.0.x, not Bulma.
• Chapter 2, Hotwire and Turbo, on page 19 is brand new, and explores a
lot of Turbo interactions that can be done with little or no JavaScript. The
framework-less toggle example from the previous version is gone.
• Chapter 3, Stimulus, on page 37 now reflects that the version of Stimulus
we were using has been released as Stimulus 2.0. The Stimulus examples
now better work with Turbo and HTML over the wire. The Stimulus
examples are now more elaborate.
• Chapter 5, Cascading Style Sheets, on page 89 now includes using Ani-
mate.css for animation effects.
• Chapter 7, webpack, on page 131 and Chapter 8, Webpacker, on page 147
have been updated to reflect some changes in Webpacker 6, particularly
how it integrates with other tools.
• The Stimulus examples in Chapter 9, Talking to the Server, on page 159
now do a much better job of focusing on Stimulus as an accessory to
Turbo and Hotwire, with much more HTML over the wire. The use of the
Gon gem is out of this example.
• The ActionCable section was expanded to an entire chapter (Chapter 10,
Immediate Communication with ActionCable, on page 185), and includes
the turbo-rails shortcuts for using ActionCable automatically when an
ActiveRecord changes state.
• Chapter 11, Managing State in Stimulus Code, on page 209 has been
changed to better reflect the use of HTML for state, and the discussion of
simple reducers has been moved to the following chapter. The examples
here are now more elaborate.
• Chapter 15, Testing with Cypress, on page 287 reflects changes in the
underlying pages, and now includes a section on setting up Rails data on
a per-test basis.
report erratum • discuss