Skip to content

Replacing React frontend with Stimulus

Matteo Depalo edited this page Oct 29, 2024 · 4 revisions

The template comes set up by default to use a React frontend that runs on a separate process to the Rails server in development mode.

However, for some apps it might make more sense to use Rails views with Stimulus. This page covers changing this template to run that way.

Note

Please note this guide assumes the app is running on Rails 7 and already has importmaps set up.

1. Detach React frontend

All of the React frontend is contained in the web/frontend folder, so you can remove it completely:

rm -rf web/frontend

In web/app/controllers/home_controller.rb, stop rendering the React frontend in HomeController#index:

  • Replace React paths with layout:

    -DEV_INDEX_PATH = Rails.root.join("frontend")
    -PROD_INDEX_PATH = Rails.public_path.join("dist")
    +layout 'embedded_app'
  • Remove else branch in index action:

    def index
      if ShopifyAPI::Context.embedded? && (!params[:embedded].present? || params[:embedded] != "1")
        redirect_to(ShopifyAPI::Auth.embedded_app_url(params[:host]), allow_other_host: true)
    - else
    -   contents = File.read(File.join(Rails.env.production? ? PROD_INDEX_PATH : DEV_INDEX_PATH, "index.html"))
    -   contents.sub!("%VITE_SHOPIFY_API_KEY%", ShopifyApp.configuration.api_key)
    -
    -   render(plain: contents, content_type: "text/html", layout: false)
      end
    end
  • Create a new home view in web/app/views/home/index.html.erb:

    <div>
      Hello world!
    </div>

2. Load Stimulus Javascript

Note

The template already includes most of these changes, but older apps might not have them. You may not need to make all of these changes.

In web/config/importmap.rb, make sure you're loading the JS controllers and Stimulus scripts:

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
+pin "@hotwired/stimulus", to: "stimulus.min.js"
+pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
+pin_all_from "app/javascript/controllers", under: "controllers"

In web/app/javascript/application.js, load the controllers script:

import "@hotwired/turbo-rails"
+import "controllers"

In web/app/javascript/controllers/application.js, set up the Stimulus Application:

import { Application } from "@hotwired/stimulus"

const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application

export { application }

Regenerate the Stimulus manifest:

cd web && ./bin/rails stimulus:manifest:update

3. Update the embedded app template

In web/app/views/layouts/embedded_app.html.erb (see example), make sure you are:

  • Loading the App Bridge script:

    + <%= javascript_include_tag 'https://cdn.shopify.com/shopifycloud/app-bridge.js', data: {
    +   'api-key': ShopifyApp.configuration.api_key,
    + } %>
    </head>
  • Calling <%= yield %> in the <body> of the page

4. Shopify CLI

If you're using the Shopify CLI you need to change the role in the shopify.web.toml from backend to frontend, like so:

- roles = ["backend"]
+ roles = ["frontend"]

[commands]
dev = "bin/rails server"

5. Next steps

This will make it possible to create Stimulus controllers as in other Rails apps, for instance following their getting started guide.