Build an embedded app with Rails, React, and Shopify App Bridge

This tutorial shows you how to build an embedded Shopify app with Rails 6 using the Shopify App gem, React, and Shopify App Bridge authentication.

The app uses session tokens to authenticate requests from the app frontend to the app backend. When you've completed this tutorial, any requests made to the protected /graphql endpoint of the app will be authenticated with an Authorization: Bearer <session-token> header.

Requirements

You must meet the following requirements to complete this tutorial:

You can view the code for the sample app on GitHub.

Generate credentials from your Partner Dashboard

If you haven't done so already, then note the app's Shopify API key and secret found on your Shopify Partner Dashboard. These credentials are used to implement OAuth so that the app can access Shopify APIs.

Create a backend using Rails

  1. Run the following console command in your working directory:

  2. In your new app, create a .env file in the root directory of <your-app-name>:

  3. Open the app's Gemfile and add the following dependencies:

  4. Run the following command to install the gems:

  5. Run the following command to generate an embedded app using the Shopify App gem:

  6. Run the following installer to create a GraphQL backend:

  7. Run any outstanding database migrations:

Create a frontend using React

  1. In the root folder of the app, run the following commands to install React using webpacker:

  2. Add the following dependencies to your package.json file:

  3. Generate a default App.js component:

  4. Overwrite app/views/home/index.html.erb to match the following code:

Make authenticated requests using App Bridge

To make authenticated requests using App Bridge, you need to configure the backend and frontend of your app.

Configure the backend

  1. Update GraphqlController in /app/controllers/graphql_controller.rb to inherit AuthenticatedController:

  2. Add an expected message to the test_field method of app/grapqhl/types/query_type.rb:

  3. To handle changes in access scopes requested by your app, add the following configuration to /app/config/initializers/shopify_app.rb. For more information on handling changes in access scopes, refer to the Shopify App gem.

Configure the frontend

Your app's frontend uses authenticatedFetch to attach a session token as an authorization header when making requests to your app's backend.

The authenticatedFetch() method does the following:

  • Appends an Authorization: Bearer <session token> header to all the requests made by this Apollo Client. Tokens are automatically cached and updated as needed by this method.

  • Takes an App Bridge instance as an argument. An instance is provided to all embedded apps by app/javascript/shopify_app/shopify_app.js.

This header authenticates that the request was made by your app embedded in a shop.

  1. In app/javascript/components/App.js, import authenticatedFetch from @shopify/app-bridge-utils:

  2. In app/javascript/components/App.js, create an Apollo Client and provide authenticatedFetch as the fetch method:

  3. Create a TestData component to query the /graphql endpoint of the app:

  4. Import the TestData in the App component:

Embed the app in Shopify

During OAuth, Shopify redirects from the app authorization prompt back to the allow-listed redirect URL specified in your Shopify Partner Dashboard. The app needs an HTTPS address to be able to do this. Because your localhost:3000 isn't public, you need to use a tool like ngrok to create a secure tunnel from the public internet to your local machine.

  1. Download and install ngrok.

  2. Initialize ngrok to use port 3000 using the following console command:

  3. Start the app using the following console command:

  4. Visit https://<ngrok-id>.ngrok.io and specify the shop where you want to install your app.

  5. After the app is installed, you're redirected to the embedded app. The app displays the following message:

    "Congratulations! Your requests are now authorized using App Bridge Authentication."

Sample app

Sample app using Rails and React

Next steps