Add Netlify Identity Authentication to any React App in 5 minutes with React Context, Hooks and Suspense
Tags: react, netlifyidentity
Published: 2019-06-21 11:33:26

---
title: Add Netlify Identity Authentication to any React App in 5 minutes with React Context, Hooks and Suspense
published: true
description: Adding authentication is a pain point for many React beginners. We’ve made it ridiculously easy to add Netlify Identity onto any React app, including create-react-app, Gatsby, Next.js, or any other setup you may have, by wrapping it all into one simple React Hook! However, this article is more about effective design patterns for introducing authentication into React apps, and any reader should be able to write similar wrappers for their preferred provider.
tags: React, Netlify Identity
---

> 💁🏼‍♂️Bottom Line Up Front: [Here's a demo](https://react-netlify-identity-widget.netlify.com/) of the identity widget we'll see in this article, although you are free to write your own authentication UI!
> 💁🏼‍♂️If you want to skip the explanation and just get to the quickest start, skip to the [React Netlify Identity Widget](#reactlazy-and-suspense-with-raw-reactnetlifyidentitywidget) section below!

Adding authentication is a pain point for many React beginners. We’ve made it ridiculously easy to add Netlify Identity onto any React app, including `create-react-app`, Gatsby, Next.js, or any other setup you may have, by wrapping it all into one simple React Hook! However, this article is more about effective design patterns for introducing authentication into React apps, and any reader should be able to write similar wrappers for their preferred provider.

For the purposes of our examples though, we will use [Netlify Identity](https://www.netlify.com/docs/identity/?utm_source=blog&utm_medium=devto&utm_campaign=devex). This is a very simple authentication service provided by Netlify, with a [generous free tier](https://www.netlify.com/pricing/?utm_source=blog&utm_medium=devto&utm_campaign=devex#identity). You can use this for [gated content](https://www.netlify.com/blog/2018/01/23/getting-started-with-jwt-and-identity/?utm_source=blog&utm_medium=devto&utm_campaign=devex), [site administration](https://www.netlify.com/blog/2019/02/21/the-role-of-roles-and-how-to-set-them-in-netlify-identity/?utm_source=blog&utm_medium=devto&utm_campaign=devex), [authenticated functions](https://www.netlify.com/blog/2018/03/29/jamstack-architecture-on-netlify-how-identity-and-functions-work-together/?utm_source=blog&utm_medium=devto&utm_campaign=devex), and more. Users primarily access this functionality through `GoTrue-JS`, the [3kb JS client](https://www.netlify.com/blog/2018/12/07/gotrue-js---bringing-authentication-to-static-sites-with-just-3kb-of-js/?utm_source=blog&utm_medium=devto&utm_campaign=devex) for accessing Netlify Identity. Because it is just an open source API (that you can [self-host](https://github.com/netlify/gotrue)), you don’t need to host your app on Netlify, nor even have a [JAMstack app](http://jamstack.org?utm_source=blog&utm_medium=devto&utm_campaign=devex), to be able to use it.

## Hooks and Context with `react-netlify-identity`

For React users, we recently wrapped up all the functionality of `GoTrue-JS` into a very easy to use React Hook. This made Netlify Identity dramatically easier to use by being a drop-in authentication solution for most React apps.

Assuming you have an existing Netlify site instance (if you don’t, you can set that up by clicking [here](https://app.netlify.com/start/deploy?repository=https://github.com/netlify/create-react-app-lambda&stack=cms&utm_source=blog&utm_medium=devto&utm_campaign=devex)) and [have enabled Netlify Identity](https://www.netlify.com/docs/identity/?utm_source=blog&utm_medium=devto&utm_campaign=devex#getting-started) on it, you get started by installing:

```bash
    npm i react-netlify-identity
```

The library has an `IdentityContext` internally, but you never have to manipulate it manually. Instead wrap the `IdentityContextProvider` around the root of your app:

```js
import React from "react"
import { IdentityContextProvider } from "react-netlify-identity"
function App() {
  const url = "https://your-identity-instance.netlify.com/" // supply the url of your Netlify site instance with Identity enabled. VERY IMPORTANT
  return <IdentityContextProvider url={url}>{/* rest of your app */}</IdentityContextProvider>
}
```

That’s all the setup you need!

Now you can use the exposed identity methods anywhere in your app (they are documented in [the README](https://github.com/sw-yx/react-netlify-identity), but also you can get autocompletion hints since the library is written in TypeScript):

```js
import { useIdentityContext } from "react-netlify-identity"

// log in/sign up example
function Login() {
  const { loginUser, signupUser } = useIdentityContext()
  const formRef = React.useRef()
  const signup = () => {
    const email = formRef.current.email.value
    const password = formRef.current.password.value
    signupUser(email, password)
      .then((user) => console.log("Success! Signed up", user))
      .catch((err) => console.error(err))
  }
  // write similar logic for loginUser
  // return a form attached to formRef, with email and password fields
}
```

Normally this is where I point you to a [working demo](https://netlify-gotrue-in-react.netlify.com/) with [source code](https://github.com/sw-yx/react-netlify-identity/tree/master/example) and leave you to “go forth and write your authenticated apps”, but even this is too much work to be done especially for “quick & easy” demos.

When we said 5 minutes, we meant 5 minutes.

## Sidebar: Is that a Hook or a Context?

If you’re squinting at `useIdentityContext` and wondering what that is, you’re not alone. If it is a Context, why not export an `IdentityContext` so that the user can call `useContext(IdentityContext)`? If it is a Hook, why did you need to wrap an `IdentityContextProvider` at the app root in the first place?

Short answer: It’s both.

`react-netlify-identity` exports a Custom Provider _and_ a Custom Consumer Hook, a pattern [popularized by Kent C Dodds](https://kentcdodds.com/blog/how-to-use-react-context-effectively). The Custom Provider lets us initialize required info (the Netlify Identity instance) once, while The Custom Consumer Hook lets us take care of the nitty gritty details of null checks, as well as allows us to refine types for TypeScript users.

## React.lazy and Suspense with `react-netlify-identity-widget`

Where `react-netlify-identity` exports reusable authentication behavior for your apps, it has no opinion at all on your authentication UI. This can halt your productivity while you futz around designing the auth UI of your dreams, meanwhile not getting feedback from real users on the core app or site that you actually want to show.

What `react-netlify-identity-widget` aims to do is to provide a “good enough” authentication UI for you to get going fast, while offering customizability in styling and being a drop-in solution on virtually any app. To be a drop-in solution, the best UI paradigm is using a modal, which comes with its own accessibility issues, so we lean on the excellent [Reach UI](https://ui.reach.tech/) project to provide accessible components.

To get going, install:

```bash
    ## this re-exports react-netlify-identity, no separate install needed
    npm i react-netlify-identity-widget
    ## peer dependencies, if you don't already have them
    npm i @reach/dialog @reach/tabs @reach/visually-hidden
```

To use this widget, you set up the `IdentityContextProvider` exactly as above:

```js
import { useIdentityContext, IdentityContextProvider } from "react-netlify-identity-widget"

function App() {
  const url = "https://your-identity-instance.netlify.com/"
  return <IdentityContextProvider value={url}>{/** rest of your app **/}</IdentityContextProvider>
}
export default App
```

The only new things you need to do pertain to rendering the Modal widget, which the default export of the library, as well as (optionally) importing the CSS, if you don’t want to write your own. It is a controlled component, so you just need to pass in a boolean to `showDialog` to indicate if you want it open or closed (as well as give it an `onCloseDialog` callback to close itself):

```js
import "react-netlify-identity-widget/styles.css"
// code split the modal til you need it!
const IdentityModal = React.lazy(() => import("react-netlify-identity-widget"))

function Main() {
  const identity = useIdentityContext()
  const [dialog, setDialog] = React.useState(false)
  const isLoggedIn = identity && identity.isLoggedIn
  return (
    <div className="App">
      <button className="btn" onClick={() => setDialog(isLoggedIn)}>
        {isLoggedIn ? "LOG OUT" : "LOG IN"}
      </button>
      <React.Suspense fallback="loading...">
        <IdentityModal showDialog={dialog} onCloseDialog={() => setDialog(false)} />
      </React.Suspense>
    </div>
  )
}
```

What is that `React.lazy` function and `React.Suspense` component? These are [relatively new React features for code splitting](https://reactjs.org/blog/2018/10/23/react-v-16-6.html) by making [dynamically imported](https://webpack.js.org/guides/code-splitting/#dynamic-imports) components declarative. This way, even though `react-netlify-identity-widget` is a trim [6kb min+gzipped](https://bundlephobia.com/result?p=react-netlify-identity-widget@0.1.1), your user doesn’t pay unnecessary JS import cost until they try to log in, making your app that much snappier to load.

Run your app ([example here](https://react-netlify-identity-widget.netlify.com/?)), click your log in button, and get this modal:

![](https://paper-attachments.dropbox.com/s_33B1E747B4EA51EE372C4DD79ED96CA43B598BF484C23D59491C5FFCCC760A2E_1559884212463_image.png)

The widget helps to bake in a litany of authentication UI standards you’ll want to consider (or avoid implementing for your MVP’s):

- Login
- Signup
- Logout
- Email confirmation
- [External Provider authentication](https://www.netlify.com/docs/identity/?utm_source=blog&utm_medium=devto&utm_campaign=devex#external-provider-login) with Google/GitHub/GitLab/Bitbucket
- (pending) Password Recovery

More importantly, it takes all the decision-making out of adding an authentication UI on top of your existing app at very little cost. To check against authentication information anywhere in your app (eg for [Protected Routes](https://www.gatsbyjs.org/docs/building-a-site-with-authentication/) or getting a canonical user ID), you simply call `useIdentityContext` just like before.

## Conclusion

While this article uses Netlify Identity for its authentication provider, the design patterns we describe can easily be used by any other provider like Auth0, Okta, or one you roll yourself. We simply think these are excellent use cases for combining the best of React’s new features for a fantastic developer experience for authentication, traditionally a time-sucking, undifferentiated feature to add and do well. It is possible that this library may evolve to accept multiple adapters for authentication providers in future - if you are interested in collaborating on one unified API for all authentication in React, [get in touch](https://github.com/sw-yx/react-netlify-identity/issues/new)!