How To Call Data From The Strava API In Your React App

Josh-Gotro
JavaScript in Plain English
9 min readOct 11, 2020

--

Photo by Jeremy Lapak

Sometime in September or October every year, people shake the dust from their running shoes and begin training for marathons scheduled in early spring the next year.

It takes months to train, so a good plan is necessary. Ramp your miles up too fast and you risk injury, go too slow and you won’t have enough miles on your legs to finish 26.2 on race day.

One of the best tools for keeping you on track is a good running app. I use Strava because it tracks data including distance, pace, heart rate, personal best times, and more. It’s also a social app so supporting your friends, sharing activities, and public challenges are core features.

I am working on a project/React app to replace and upgrade my current training system that was created in google docs. In the new version, I want to import my workout information so I can see my progress and get insights in one place. Luckily for me, Strava has an open and supported API.

This guide will walk you through how to access your personal workout data from Strava into your JavaScript project.

Find the Strava API documentation here. This article is based on Strava’s Getting Started Guide as well as this video series by Franchyze923.

Overview

  • Create or log in to your Strava account
  • Setup a new app in your Strava account
  • About scope
  • Use Swagger to test your endpoints
  • Create an Authorization Token
  • Get your Access Token and Refresh Token
  • Call the Strava API from your React App.

Create or log in to your Strava account

Click here to log in or create a Strava account.

Setup a new app in your Strava Account

Once you are logged in, navigate to https://www.strava.com/settings/api. You have to manually enter the address in the browser the first time, but after that, you can navigate there through the Stava website by clicking settings.

It would be a good idea to bookmark this page or keep it open in a tab. You will visit it frequently throughout this tutorial.

Fill out the following info:

  • Application Name: Name this whatever you like.
  • Category: I’m building a marathon planning schedule, so I chose “Training”.
  • Club: If you are part of a club you may choose to select it, otherwise leave this field blank.
  • Website: URL for the website you are creating. If you don’t have one just put https://www.strava.sampleapp.com.
  • Application Description: Optional field for describing what your app will do.
  • Authorization Callback Domain: For now enter localhost. This allows access to the API in developing mode. Update this field to developers.strava.com while testing endpoints in Swagger (more on that later), and update it to your domain once your app is deployed.

Once the fields are filled out, check the box indicating you have read and agree with Strava’s API Agreement.

Click Create.

You will be prompted to add an App Icon. You can change this any time so feel free to use a placeholder for now. Upload and save.

You should see something like this:

Scroll up. You now have the following information.

About Scope

Scope in the Strava API represents the different access levels you need in order to read or change the User’s data.

As a developer of a third-party app, we determine what permissions we are going to ask Strava to grant us for a specific user. It is good practice to ask for what you need; no less, and no more.

Strava, through the authentication process, tells the user what permissions the third-party app is requesting and allows the user to grant or deny that access.

In this case, we are both the Developer and the User, so this should be an easy task.

When you set up a new app in the Strava settings, the Access Token and Refresh Token listed above will work for one type of scope, read.

Depending on what information you want, this may not be enough access. See the image below to see how much access each scope option allows.

I want access to all my activities including those set to private, so I will use the activity:read_all scope. This will give the correct access permissions to my Refresh Token and Access Token.

In the next step, we will preview what our data looks like when it is returned, and confirm what scope is needed to access that data.

Feel free to use any endpoints you wish but remember to swap it and it’s scope place of mine throughout the rest of this guide if you do so.

Test your endpoint in Swagger

Swagger is a tool that Strava offers that allows you to get familiar with their API. It shows what responses look like based on what endpoints you call and what scope is needed to access those endpoints.

In order for the Swagger tool to work, return to the settings section of your Strava account. In the field Authorization Callback Domain, replace localhost with developers.strava.com.

Click Update.

Remember to keep this page open, you will use your Client ID and Client Secret a lot in the following steps. (click show next to the Client Secret to reveal the information).

Navigate to Swagger. You will see all the available endpoints as you scroll down the page. Clicking on an endpoint will show you what scope is needed to access the data, as well as parameters for each route.

Because Swagger is going to return real information to us, we need to give it the authorization to call the API.

I am going to use the get route, /athlete/activities endpoint. Click on that row.

The first line will describe what scope you need to access this information. This endpoint requires activity:read to return only public information or activity:read_all to return all information.

Returns the activities of an athlete for a specific identifier. Requires activity:read. Only Me activities will be filtered out unless requested by a token with activity:read_all.

As I’ve mentioned before, I want all data including activities set to private, so I will choose activity:read_all.

Next, scroll back to the top of the page and click on the green button, Authorize.

Enter the Client ID and Client Secret from your Strava account in their appropriate fields.

Select the scope listed in the endpoint you plan on using. I selected activity:read_all for this project.

Note, there is a known bug in this tool that will only allow you to test at one scope at a time.

Scroll down and click Authorize.

You will be redirected to an OAuth2 page, where you will click Authorize again.

The app information you entered in Stava including the picture shows up here.

After you have authorized, you will be redirected back to Swagger. Click close on the popup screen.

You did it! Now click “Close”

Now, scroll back down to /athlete/activites and expand it. click on Try it out.

Click the big Execute button.

Scroll down and check out the response! That is what your data will look like when it is returned to you.

This is ONE activity returned… look at all that info!!

Feel free to change the parameters or checkout other endpoints to decide exactly what data you would like returned. Remember that if you look at endpoints that require a different scope, you will need to reauthorize with Swagger, and you can only look at one scope at a time.

  • ** If you see a blank array returned, then it means you haven’t recorded any activities in the time frame selected. Feel relieved that the call is working, but record an activity (or change the parameters to capture a recorded activity) so you can see data!***

Intermission

I don’t know about you, but I could use a short break. Perhaps some Cate Le Bon is in order:

Open only if avant-grade in a welch accent sounds good to you.

Create an Authorization Token

We need an Authorization Token in order to request anAccess Token and Refresh Token.

Paste your information into the following URL (note: line breaks added for clarity):

http://www.strava.com/oauth/authorize?client_id=[CLIENT_ID]&response_type=code&redirect_uri=http://localhost/exchange_token&approval_prompt=force&scope=[YOUR_SELECTED_SCOPE]

Here is what it looks like with my info added and the line breaks removed:

http://www.strava.com/oauth/authorize?client_id=54753&response_type=code&redirect_uri=http://localhost/exchange_token&approval_prompt=force&scope=activity:read_all

Navigate to the URL you just created. Click Authorize.

You will be redirected to a page that fails to open. This is expected!!

Don’t fret, we expected this.

Copy the URL of the page. It will look something like this:

http://localhost/exchange_token?state=&code=b29e1998446705436f2a2952b21eeb8f76c070c9&scope=read,activity:read_all

With added breaks for clarity:

http://localhost/exchange_token?state=&code=b29e1998446705436f2a2952b21eeb8f76c070c9&scope=read,activity:read_all

The second line is your authorization code. Copy down everything after &code= , in this case, it is b29e1998446705436f2a2952b21eeb8f76c070c9.

We are going to use this authorization code to request our Refresh Token and Access Token.

Get your Access Token and Refresh Token

Enter your information into the following URL ( breaks added for clarity):

https://www.strava.com/oauth/token?
client_id=[YOUR_CLIENT_ID]
&client_secret=[YOUR_CLIENT_SECRET]
&code=[AUTHORIZATION_CODE]
&grant_type=authorization_code

Here it is with my info entered and with the breaks removed:

https://www.strava.com/oauth/token?client_id=54753&client_secret=6308cc42367f364b3e1c29ede9434d1b92e9b06c&code=b29e1998446705436f2a2952b21eeb8f76c070c9&grant_type=authorization_code

Open your Terminal and type in the following cURL POST request with the URL you just made in place of [URL]:

curl -X POST [URL]

Mine looks like this:

curl -X POST https://www.strava.com/oauth/token\?client_id\=54753\&client_secret\=6308cc42367f364b3e1c29ede9434d1b92e9b06c\&code\=b29e1998446705436f2a2952b21eeb8f76c070c9\&grant_type\=authorization_code

Here is what that return looks like with line breaks for clarity:

Copy the Refresh Token , we will use it in our React App.

An Access Token is only good for 6 hours before it expires. We use the Refresh Token to request a new one. As far as I know, the Refresh Token does not expire.

Call the Strava API from React

We are in the home stretch!

First, go back into your Strava settings and change the Authorization Callback Domain field back to localhost.

Open your react app and navigate into a component that renders to the DOM. For this example, I will use App.js.

I’ve added some styling not shown here for the demonstration

line 1: Import React with hooks useState and useEffect.

line 4–5: Set state for a loading boolean and to hold all of the data we receive.

12–13: Set a variable to hold our Refresh Tokenand the URL to send requests for the current Access Token.

16: Set variable for the URL for requesting activities.

19–25: When the page loads, the useEffect will request a current Access Token. Once the token is retrieved, it passes it to a function called getActivities.

28–34: getActivites fetches the activities using the current access code passed from useEffect. It sets the results to state, switches our loading boolean from from true to false, or displays any errors if they occur.

36–42: Create function showActivities. If our loading boolean is true it will return LOADING. if it is false, it will print our activity state to the console and display the total count of activities to the DOM.

44–49: Return a <div> that calls on our showActivities function which will determine what will be shown on the DOM.

You did it!

Congrats!! you have successfully called the Strava API from your React App.

Don’t forget after you have deployed your app to go back into your Strava settings and change the Authorization Callback Domain field to your domain.

Thanks to Franchyze923 who has one of the only video tutorials I could find covering this subject.

Check out some of my other stories; Send Email From Your React App With EmailJS, CSS Reset, or Recoil.js & simple global state.

Questions? Comments? Concerns? Contact me at joshuagauthreaux@gmail.com or through joshgotro.com.

Thank you for reading and be well!

--

--

Hi, I’m Josh Gauthreaux. I’m a full-stack web developer from Austin, TX. I love people and I love building things.