Skip to content

Webpacker + Turbolinks + ReactRailsUJS = 😞 #899

Closed
@mendelk

Description

@mendelk

Steps to reproduce

Create a new Rails app that uses Webpacker for assets, and imports Turbolinks (as opposed to using Sprockets for Turbolinks as seems to be the case for this repo's tests).

Run ReactRailsUJS.detectEvents() to set up Turbolinks' events.

Expected behavior

ReactRailsUJS should mount and unmount React components on the corresponding Turbolinks events.

Actual behavior

Those events don't get fired.

System configuration

Webpacker: 3.2.0
React-Rails version: 2.4.4
React_UJS version: 2.4.4

The reason this happens is because React-Rails expects Turbolinks to be a global object. If you're using Webpacker, by default everything is local, causing React-Rails to think that Turbolinks is not installed.

(My attempt to solve this via using a webpack.ProvidePlugin to turn Turbolinks into a global did not work, because Turbolinks.start() needs to be called before React-Rails, else Turbolinks.controller is undefined.)

I'm not sure this can be considered a bug, so instead I'll just share how I solved this. If this is intended, perhaps it can be added to README / Wiki? (I can create a PR if desired!)

My solution:

import Turbolinks from "turbolinks";
import ReactRailsUJS from "react_ujs";

// This needs to be in this particular order:
Turbolinks.start();
// Add Turbolinks to the global namespace
window.Turbolinks = Turbolinks;
// Remove previous (native) events, and add Turbolinks'
ReactRailsUJS.detectEvents();
// (Optional) Clean up global namespace
delete window.Turbolinks;

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions