Building a React Store with the Shopify Storefront API: Setting up and Authenticating Your App
Set Up Your React App
In this tutorial we are going to create-react-app
to build our base react application. You can find the code base here. This will get us up and running quickly without having to invest a lot in configuration.
To get started open a terminal window and run
npx create-react-app your-app-name
cd into the directory for your app and run
yarn start
This will run the app in development mode and serve it on http://localhost:3000. Navigate to your app in the browser and you will see a page that looks like this:
Setting Up Your Shopify Store For API Access
Now we are going to set up our stores so that our React application can authenticate with the Store Front API. In your store dashboard navigate to Apps. At the bottom of the app page there is a link to Manage private apps, click there. Click the button to Create a new private app. Give your private app a name and make sure to check the box to Allow this app to access your storefront data using the Storefront API, this will be essential for interacting with the API.
Setting up ApolloClient
The Shopify Storefront API is a GraphQL API. If you're new to GraphQl you can learn more about the query language here.
The great thing about GraphQl is it lets us pull in data from multiple different resources in one request. If you think about this in the concept of your Shopify store, this could mean pulling in information about a product and the collection it belongs to and data for other related products all in one request💥!
We are going to use Apollo to help with quering the GraphQl API.
Back in our React app let's start by installing GraphQl.
In the root directoty run
npm install graphql --save
npm install graphql-tag --save
Next we'll install Apollo
npm install react-apollo --save
Next, in the index.js file we will set up the connection to the Shopify API.
Start by importing all necessary modules at the top for graphl and apollo. Then we'll specify the graphql endpoint we want to hit and set up the headers to send with the request.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import ApolloClient from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink, concat } from 'apollo-link';
import { ApolloProvider } from 'react-apollo';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
// Create ApolloClient Instance and point to your Shopify store's GraphQl server.
const httpLink = new HttpLink({ uri: 'https://[your-store].myshopify.com/api/graphql' });
// Add authentication headers
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
operation.setContext({
headers: {
'X-Shopify-Storefront-Access-Token': '[your-store-front-access-token]'
}
});
return forward(operation);
})
const client = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache().restore(window.__APOLLO_STATE__),
});
ReactDOM.render((
),
document.getElementById('root')
);
registerServiceWorker();
Let's break down some of what is going on in the code snippet above. After we've imported all the required modules we start by creating an Apollo client. This will specify the GraphQl endpoint of your Shopify store. It will also include the required headers to authenticate your app against your Shopify store. We have yet to generate the storefront-access-token, but will do so in the next step.
Finally, we create a provider to connect the ApolloClient to your react component tree. The provider component should be hierarchichally above any component in your app that will need to access the GraphQl data.
Generating the Storefront Access Token
Time to fill in the blank in the ApolloClient creation. Back in your store dashboard navigate to Apps and then at the bottom of the screen click to Manage Private Apps. Here create a new private app.
You can name your private app whatever you like, I like to name it storefront api, so I know this is the app used for the storefront api. The most important thing when creating your app is to check the Allow this app to access your storefront data using the Storefront API data box. Also, make sure to set the read / write permissions in accordance to what you would like the client to be able to access. Once you've set all the permissions save the app and you will be given a storefront access token. Copy this and replace the placeholder in your index.js file.
Pulling in Data
We are all set to start querying the store's api ✨.
In your app open App.js. Let's import the modules we'll need to make our graphql query:
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
We'll start by writting out a graphql query. To do this we will use the gql template tag. This lets us write graphql queries in our app that will be parsed into the GraphQl js format. The query will look like this:
const HOME_QUERY = gql`
query ShopData {
shop {
name
description
products(first:20) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
id
title
images(first: 1) {
edges {
node {
src
}
}
}
}
}
}
}
}
`;
Now we are going to use the Apollo graphql container to run the query. At the bottom of your App.js file, instead of exporting App we are going to export the App component subscribed the the Apollo data store.
// export default App;
export default graphql(HOME_QUERY, {name: 'shopData'})(App);
We are passing our query to the grapql container. We are also passing an optional name. This will be the name referenced in our App component props. The result of the query will be passed to App in a prop called shopData.
Display Products in Your Shop
To demonstrate how we can use the data we pulled in let's put some product photos and titles on the page.
Still in App.js modify your app component to display a loading screen and then the products.
class App extends Component {
render() {
// waiting for the shop data
if (this.props.shopData && this.props.shopData.loading) {
return Loading ✨
}
// error retrieving shop data
if (this.props.shopData && this.props.shopData.error) {
return Sorry something went wrong. Check back soon.
}
// display products
const productsToDisplay = this.props.shopData.shop.products
return (
{productsToDisplay.edges.map((el, i)=> {
return(
{el.node.title}
)
})}
);
}
}
** Note - we have noticed that the syntax highlighting package we are currently using appends ="" to attributes. In the case of some attribute values this is incorrect. For example the img src attribute should not have "" wrapped around it. We are working on resolving this issue, but for now please note that it might cause a problem if you copy and paste the code
You'll notice that the way we access the data directly maps to the HOME_QUERY we wrote earlier. This is a major benefit of GraphQl APIs, they are self documenting. The data you get back will be in the same format as the query you write. It's almost like you are writing an object with a bunch of keys and then you get data returned with the keys and values.
Setting Up Your Environment Variables
Let's do one more thing to optimize our development flow and get our store ready to push to your preferred online versioning system. We are going to set up an .env file with our store uri and storefront access token.
In the root of your preject create a new .env file. Make sure that this file is listed in your .gitignore file.
In your .env file include the store uri and storefront access token
REACT_APP_STORE_TOKEN=your-access-token
REACT_APP_STORE_URI=https://your-shop.myshopify.com/api/graphql
Note: it's important that your environment variable names start with REACT_APP
Now back in Index.js replace your store uri with process.env.REACT_APP_STORE_URI
and the storefront access token with process.env.REACT_APP_STORE_URI
. Once you have updated your app to use the environment variables make sure to stop and restart the server.