Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

Writing a Custom React Hook for Spotify's Web API (Implicit Grant Flow)

As one of the most popular music streaming services, Spotify encourages developers to craft new and engaging experiences for music lovers around the world. With over seventy endpoints, Spotify's Web API allows external applications to access Spotify's vast catalog of albums, artists, playlists, tracks and podcasts and detailed profile information about the current authorized user. All of this data opens the door to building applications that explore and analyze the data, generate new insights from the data or present the data in exciting new ways. Want to discover new artists based on the artists of the tracks in your playlists? Use the GET https://api.spotify.com/v1/artists/{artist_id}/related-artists endpoint to fetch artists related to an artist based on the analysis of other users' listening histories. Want to re-imagine the user interface for searching and displaying tracks that match a query? Use the GET https://api.spotify.com/v1/search endpoint to query and retrieve results from Spotify's tracks catalog. If you decide to create a Spotify-connected application with React , then centralizing all Spotify-related logic inside of a single, reusable custom hook, named useSpotify , eases the integration of Spotify into the application. This organizes everything Spotify-related in one place. For a component to communicate with Spotify's Web API, just import the useSpotify hook and call the hook within the component. Whenever Spotify updates its API with new endpoints or modified response objects, you edit one single file in the codebase: useSpotify.js . The hook enables all components to get the authorization status of the user and interact with Spotify's Web API. Below, I'm going to show you... Imagine building a dashboard that features a view for searching tracks from Spotify's catalog, a view for managing the current authorized user's saved albums and tracks, etc. For the custom hook useSpotify to support this type of application, it must handle: To begin, let's briefly recap React hooks and how they work. Hooks provide us a way to reuse stateful logic. When multiple components use the same hook, the state within the hook is not shared by those components. Therefore, we will need a provider component to wrap the application and make the hook's object available to any child component that calls the hook with context. Anytime the user decides to "log in" or "log out" (represented as having or not having a valid access token respectively), the changes to the hook's state will cause those components to re-render. Here's the base template of the hook, which exports the provider component <SpotifyComponent /> and a hook that returns the current context value, which comes from the object passed to the value prop of the provider component. ( useSpotify.js ) All of the Spotify-related logic will reside within the useProvideSpotify provider hook, which creates the spotify object that's fed to the provider component, exposes methods for working with Spotify's Web API and manages state variables like token and user . To obtain authorization, the hook will implement methods for facilitating the Implicit Grant Flow . Although the Implicit Grant Flow does not provide a refresh token, it requires only the client-side application to carry out the entire authorization flow. No additional backend code needed! Upon being granted authorization, Spotify issues a short-lived access token that expire within 3600 seconds (1 hour). Once the token expires and is no longer valid, you must complete the entire flow again to obtain a new access token. To start, let's write a login method that opens a popup that prompts the user to... ( useSpotify.js ) Upon authorization, the user is redirected to the redirect URI (e.g. http://localhost:3000/callback ) within the popup. The redirect URI contains a hash fragment with the access token, its type, its expiration time period and state (e.g. http://localhost:3000/callback#access_token=xxxx&expires_in=3600&token_type=Bearer&state=xxxx ) encoded as a query string. When this page loads and its component is mounted, extract the access token and its metadata from the query string and store the token and its expiration timestamp in local storage. Then, call the main window's spotifyAuthCallback method, which was registered back in the login method, to close the popup and update the hook's state with these values. ( useSpotify.js ) By storing the token in local storage, we don't need to constantly ask the user to re-authorize themself if they decide to close the browser, reopen it and revisit the application less than an hour later. And, if the user does revisit the application more than an hour later, then knowing the expiration timestamp makes it possible to invalidate the token and ask agains for authorization. ( useSpotify.js ) Note : Any value stored in local storage is stringified and must be converted back to its appropriate typing. Note : Yes, it's not recommended to store access tokens in local storage due to cross-site scripting (XSS) and possibly being read by malicious JavaScript code. Only do this for demos. For production-grade applications, I recommend going with a different authorization flow (one that involves the server-side and setting the token within an HTTP-only cookie). Anytime the user decides to "log out," invalidate the token and reload the page so that it automatically redirects them to the homepage. ( useSpotify.js ) To restrict the redirect URL to only be visited within the popup by Spotify, let's write a method to check whether the redirect occurs within a "valid" popup that originated from the application itself. ( useSpotify.js ) The useHistory hook from react-router-dom gives a history instance to verify its length is at least two (one entry for Spotify, the other for the redirect). Once the token and expiration timestamp state variables are updated, the hook should automatically fetch the current authorized user's information from Spotify and update the state with this information. ( useSpotify.js ) For the user to be considered "logged in," the hook's state must the token and user's information, and the token cannot be expired. ( useSpotify.js ) To get data from Spotify's Web API, define a method for each endpoint. For this hook, we will only define two methods: one for the GET /me endpoint and another for the GET /search endpoint. Any request sent to the API must have the access token added to its Authorization header to allow Spotify to identify the user and know that the requesting application has permission from the user to access to their data. ( useSpotify.js ) The callEndpoint method serves as a helper method that keeps the endpoint methods' definitions DRY. For more endpoints, visit Spotify's Web API reference here . When the user performs a full-page refresh of the application, it takes time for the application to fetch the user's information. The hook should provide a flag that notifies components when the application is "loading" so that they can present a loading indicator to the user. The application is in a loading state when the hook is initialized, and it is finished loading when it has successfully (or unsuccessfully) fetched the user's information from Spotify. ( useSpotify.js ) The hook will expose the following state variables and methods to child components that call it: ( useSpotify.js ) Using getters allows the component to reference the method call like a flag. So instead of calling hasLoggedIn() , just use hasLoggedIn in the component. Altogether... ( spotify.js ) ( .env ) ( useSpotify.js ) Want to see how this hook works in an actual application? Clone the demo application here and run it locally. Try using this hook for your next Spotify-connected application!

Thumbnail Image of Tutorial Writing a Custom React Hook for Spotify's Web API (Implicit Grant Flow)

    The newline Guide to Creating React Libraries from Scratch Is Now Live! 

    Creating your own React library is a way to share code for reuse, but it has other benefits such as improving the productivity of your team, as well as building your profile as an open source contributor. However, there's often a steep learning curve because of all the best practices that might easily take you years of coding to try and pick up by trial and error. In this course, we walk you through every step of creating your own React library that other developers can consume, and in the process, you learn all the best practices for shipping a quality modern JavaScript/TypeScript project. You'll dive into: The course is taught by Lead Software Engineer Dylan Paulus, who works for Schweitzer Engineer Laboratories. Dylan was a web developer at PlayStation, the leading game console company, as well as at Eastern Washington University. He has also contributed to open source projects like Rocket Chat and React-Cosmos. You can read more details about the course over at https://www.newline.co/courses/creating-react-libraries-from-scratch

    Thumbnail Image of Tutorial The newline Guide to Creating React Libraries from Scratch Is Now Live! 

    I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

    This has been a really good investment!

    Advance your career with newline Pro.

    Only $30 per month for unlimited access to over 60+ books, guides and courses!

    Learn More

    3 Ways to Optimize Your Development Workflow When Working with React & Node

    Find out how to optimize your development workflow when running Create React App and a Node server at the same time.If you’ve ever worked on a project with multiple package.json  files, you might know the pain of juggling multiple terminal tabs, remembering which commands start up which server, or handling CORS errors.  Luckily, there are a few tools available to us that can alleviate some of these headaches. In this post, we’ll go over three things you can do to optimize your development workflow when working on a project with a React front end (specifically, Create React App ) and Node back end. Let's say we're working in a monorepo with two package.json  files — one is in a client directory for a React front end powered by Create React App , and one is in the root of the repo for a Node back end that exposes an API that our React app uses. Our React app runs on localhost:3000 and our Node app runs on localhost:8888 . Both apps are started using npm start .  The directory structure looks something like this: Since we have two package.json  files, this means that to have our front end and back end up and running we need to make sure we've run npm install and npm start in both the root directory and the client directory. Let’s take a look at how we can streamline this. One improvement we can make to our development workflow is adding a build tool to run multiple npm commands at the same time to save us the hassle of running npm start in multiple terminal tabs. To do this, we can add an npm package called Concurrently to the root of our project. At the root of our project, we’ll install it as a dev dependency. Then in our root package.json scripts, we’ll update our start script to use Concurrently. Now, we have three npm scripts. npm run server starts up our Node app, npm run client runs npm start in the client directory to start up our React app, and npm start runs both npm run server and npm run client at the same time. Here’s what it should look like now when running npm start in the root of our directory. Another aspect of our workflow we can improve is dependency installation. Currently, we need to manually run  npm install for each package.json  file we have when setting up the project. Instead of going through that hassle, we can add a postinstall script to our root package.json to automatically run npm install in the client directory after installation has finished in the root directory. Now, when we install our monorepo, all we need to do to get up and running is run npm install then npm start at the root of the project. No need to cd into any other directories to run other commands. As we mentioned above, our Node back end exposes API endpoints that are used by our React app. Let’s say our Node app has a /refresh_token  endpoint. Out of the box, if we tried to send a GET request to http://localhost:8888/refresh_token from our React app on http://localhost:3000 , we would run into CORS issues. CORS stands for Cross-Origin Resource Sharing . Usually, when you encounter CORS errors, it's because you are trying to access resources from another domain (i.e. http://localhost:3000  and http://localhost:8888 ), and the domain you're requesting resources from is not permitted. To tell the development server to proxy any unknown requests to our API server in development, we can set up a proxy in our React app's package.json file. In client/package.json , we’ll add a proxy for http://localhost:8888 (where our Node app runs). Now, if we restart the server and set up a request to our Node app's /refresh_token endpoint (without the http://localhost:8888 ) using fetch() , the CORS error should be resolved. The next time you work on a monorepo project like this, try out these three tips to streamline your development workflow! Be sure to check out our new course being released soon, Build a Spotify Connected App , where we apply these concepts to build a real-world, full stack web app!

    Thumbnail Image of Tutorial 3 Ways to Optimize Your Development Workflow When Working with React & Node

    Breaking Down OAuth with Spotify

    Learn the basics of OAuth and how it works in the context of Spotify’s OAuth flow.If you’re interested in working with the Spotify API, you’ll need an OAuth token in order to access most of its data. In this blog post, we’ll explain what OAuth is, how it works, and break down each step in the context of Spotify’s OAuth flow. OAuth (Open Authorization) is a secure, industry-standard protocol that allows you to approve one application interacting with another on your behalf without giving away your password . Instead of passing user credentials from app to app, OAuth lets you pass authorization between apps over HTTPS with access tokens (kind of like a special code). For example, you can tell Facebook that it’s okay for Spotify to access your profile or post updates to your timeline without having to give Spotify your Facebook password. This way it's less risky for both you and Facebook — in the event Spotify suffers a breach, your Facebook password remains safe. Similarly, when a user authorizes an app to access their Spotify account data, that app shouldn’t be storing their username or password anywhere. As developers, we don’t want to be responsible for sensitive information like this, so instead, we rely on the secure OAuth protocol to take care of the authorization flow with access tokens. When trying to understand OAuth, it's important to remember that it's about authorization , not authentication. Authorization is asking for permission to do things. Authentication is about proving you are the correct person by providing credentials like a username or password. OAuth scenarios almost always represent two unrelated sites or services trying to accomplish something on behalf of users or their software. All three have to work together, with multiple approvals, for the completed transaction to get authorized . Since OAuth is a way to authorize an app without giving away your username and password, you can picture it like a series of handshakes . If all handshakes are completed, then your reward is a unique access token that only your app can use to access resources from a service. There are four main roles that need to "shake hands" to get that token. In addition to these four roles, there is also the concept of scopes in OAuth. Scopes are used to specify exactly which resources should be available to the client that is asking for authorization. They provide users of third-party apps with the confidence that only the information they choose to share will be shared, and nothing more. The resource server (e.g. the Spotify API) is in charge of defining these scope values, and which resources they relate to. The Spotify API has many scopes for many different purposes. For example, the user-read-private scope is for read access to a user's subscription details and is required if you want to access the https://api.spotify.com/v1/me endpoint to get the currently logged-in user's profile information. There is also a scope called playlist-modify-private that is required if you need write access to a user's private playlists. This scope allows you to do things like add items to a playlist or upload a custom playlist cover image. Check out all of the available scopes for the Spotify API here . As we mentioned before, all of the back and forth hand-shaking that OAuth requires us to do is for one thing: an access token .  You can think of access tokens like the two-factor authentication codes that some services send you via text message for you to log in. Just like two-factor auth codes, OAuth tokens have a limited time in which they are valid. After a while, all tokens expire, and you'll need to request another one (or refresh it). In the end, this is all for security — in case someone gets hold of your unique access token, they can only access your private data for a limited amount of time before they're locked out. Now that we've gone over OAuth roles, scopes, and tokens, let's look at how they all tie together in the context of Spotify’s OAuth flow. Before any client or server requests are even made, there are two things the client (your app) needs in order to kick off the OAuth flow: the client ID and the client secret . These are two strings that are used to identify and authenticate your specific app when requesting an access token. With Spotify, your app's unique client ID and client secret can be found in the developer dashboard . Once we have these two values, we're ready to initiate the OAuth flow. First, the client (your app) sends an authorization request containing the client ID and secret to the authorization server (the Spotify Accounts Service). This request also includes any scopes the client needs and a redirect URI which the authorization server should send the access token to. Second, the authorization server (Spotify) authenticates the client (your app) using the client ID and secret, then verifies that the requested scopes are permitted. After step 2, the user is redirected to a page on the Spotify authorization server where they can grant the app access to their Spotify account. In our case, the user will have been sent to a page that belongs to the Spotify accounts service (note the accounts.spotify.com URL in the screenshot below), where they can log in to Spotify. Once the user grants access by logging into Spotify, the authorization server redirects the user back to the client (your app) with an access token. Sometimes, a refresh token is also returned with the access token. Finally, the client can use the access token to access resources from the resource server (the Spotify API). If all of this feels like a lot, don't worry, it's because it is! OAuth is super tricky, but for a good reason — security! All you really need to remember is this: The five basic steps of the Spotify OAuth flow: Try out implementing Spotify’s OAuth flow yourself! It’s not as daunting as you might think — the documentation describes everything you need to implement the flow. Be sure to check out our new course being released soon, Build a Spotify Connected App , where we apply these concepts to build a real-world, full stack web app!

    Thumbnail Image of Tutorial Breaking Down OAuth with Spotify

    5 Minute Intro to REST APIs

    Learn the basics of APIs and what makes an API "RESTful"So what is an API (Application Programming Interface)? It's pretty simple from a high-level — two applications interfacing (or “talking”) with each other via programs. APIs also make our lives easier by abstracting away complex code and replacing it with simpler, more straightforward code. For example, think about what happens when you open a music streaming app and play a song. There's probably some code that runs when you hit play that looks something like this: That play() function is an API method that abstracts away things like: As developers, we don't need to know or care about the lower-level code when we call the play() method, and that's fine! APIs are here to make our lives easier. In JavaScript, APIs are usually based on objects . In the example above, the mediaPlayer object is the entry point for the API, and play() is the API method . Let's take a look at a more common example you've probably encountered before. If you've ever written JavaScript like this: then congrats, you've used the DOM (Document Object Model) API ! Here, the document object is being used as the entry point for the DOM API, and querySelector() is the API method . In the web development world, APIs generally fall into two categories: So if an API is a set of rules that allow one piece of software to talk to another, then REST (Representational State Transfer) is a standard set of rules that developers follow to create an API. Six conditions that need to be met for an API to be considered RESTful: I think you’d be hard-pressed to find anyone who remembers the definition of each of these conditions off the top of their head, so the gist of it is this: In a nutshell, you should be able to receive a piece of data (a.k.a.  resource ) when you access a predefined URL. Each of these URLs, also known as “ endpoints ", are part of what is called a request , and the data you receive from the request is called a response . The data provided by these responses are usually in the form of JSON ( JavaScript Object Notation ). A RESTful request is composed of four parts: Let’s take a quick look at what each of these four parts are. The "endpoint" is the URL you request. All REST APIs have a base URL (also known as the "root" endpoint). For example, the base URL of Spotify's API is https://api.spotify.com while the base URL of GitHub's API is https://api.github.com . Additionally, each endpoint in a REST API has a path that determines the resource being requested. In the example endpoint above, https://api.spotify.com/v1 is the base URL, and /playlists/59ZbFPES4DQwEjBpWHzrtC is the path to a particular playlist. The HTTP method is the type of request you send to the server. There are five common types of HTTP methods: GET , POST , PUT , PATCH , and DELETE . They are used to perform four possible operations: Create, Read, Update, or Delete (CRUD). When working with a REST API, the documentation should tell you which HTTP method to use with each request. Headers are key-value pairs that are used to provide information to both the client and server. You can store things like authentication tokens, cookies, or other metadata in HTTP headers.  For example, the header below tells the server to expect JSON content. You can find a complete list of valid headers on MDN’s HTTP Headers Reference . The "body" of a request contains any information you want to send to the server and is normally transmitted in the HTTP request's body by sending a single JSON-encoded data string . This information is usually the data you'd like to create a new resource with (with a POST request) or the modified value of a resource you'd like to update (with a PUT or PATCH request).  Now that we know the parts of an HTTP request, let’s take a look at what is returned in an HTTP response: the status code and the body data. Responses always include an HTTP status code in the response header. These status codes are numbers that indicate whether a request was successfully completed and range from the 100s to the 500s. Similar to HTTP requests, responses usually return body data in the form of JSON . To wrap it all up, let’s take a look at a real-world example with the Spotify API. Spotify’s Web API, which has a base URL of https://api.spotify.com/v1 , has an endpoint that lets you get a playlist by its ID . If you take a look at the docs , you'll see that the HTTP request’s endpoint ( https://api.spotify.com/v1/playlists/{playlist_id} ) requires a GET   HTTP method and must have a valid Authorization header . It also requires a path parameter of the playlist’s ID. So if you send a  GET request to https://api.spotify.com/v1/playlists/59ZbFPES4DQwEjBpWHzrtC , the API's response will include body data that look like this: This JSON includes things like the playlist’s number of followers, the URL of the cover image, the playlist’s name, and much more. Now that you have a solid understanding of REST APIs, try interacting with one yourself! Be sure to check out our new course being released soon, Build a Spotify Connected App , where we apply these concepts to build a real-world, full stack web app!

    Thumbnail Image of Tutorial 5 Minute Intro to REST APIs