Memberstack React Package

Article author
Memberstack Team

React Memberstack is a wrapper around the @memberstack/dom package. It makes it easy to add Memberstack to any React app.

Overview

Welcome to the React Memberstack documentation! The Memberstack React Package is a wrapper around the @memberstack/dom package, designed to make it easy to integrate Memberstack into any React application. Memberstack is a platform that provides user authentication, membership management, and other user-centric features.

For additional functionality check out our DOM Package and Admin Package

Prerequisites

This documentation assumes that you have a working knowledge of React and React Hooks. If you're new to these technologies, we recommend checking out the official React documentation and this guide on React Hooks before proceeding.

Getting Started

To get started, you'll need to install the Memberstack React package from the npm public registry, or using yarn. Here are the commands to do so:

npm install @memberstack/react

yarn add @memberstack/react

Memberstack Provider

After the package has been installed successfully, you can wrap the components that need access to the Memberstack object in the provided MemberstackProvider.

The MemberstackProvider receives a config prop, which contains the memberstack initialization object with DOM modifications.

import { MemberstackProvider } from "@memberstack/react";

const config = {
  publicKey: "pk_...",
};

function Index() {
  return (
    <MemberstackProvider config={config}>
      <App />
    </MemberstackProvider>
  );
}

Hooks

Memberstack React comes packed with custom hooks. These hooks give you access to Memberstack-related data plus a collection of useful methods for checking out, plan management, and authentication.

useMemberstack

The useMemberstack hook returns a reference to the memberstack instance, created by the MemberstackProvider.

import { useMemberstack } from "@memberstack/react";

function Dashboard() {
  const memberstack = useMemberstack();
  const [member, setMember] = React.useState(null);

  React.useEffect(() => {
    memberstack.getCurrentMember()
      .then(({ data: member }) => setMember(member))
      .catch();
  }, []);

  if (!member) return null;

  return (
    <div>
      Welcome, {member.auth.email}
    </div>
  );
}

useAuth

The useAuth hook returns limited information to help access the current session and manage a member’s auth state.

import { useAuth } from "@memberstack/react";

const {
  userId,
  status,
  getToken,
  isLoggedIn,
  signOut
} = useAuth();

useCheckout

The useCheckout hook returns a method that opens a Stripe-hosted checkout session.

import { useCheckout, MemberstackProtected, SignInModal } from "@memberstack/react";
...
const checkout = useCheckout();
...
return (
  <MemberstackProtected onUnauthorized={<SignInModal />}>
    <button
      onClick={async () =>
        checkout({
          priceId: "prc_sb_...",
        })
      }
    >
      Checkout
    </button>
  </MemberstackProtected>
);

useCustomerPortal

The useCustomerPortal hook returns a method that opens a Stripe-hosted customer billing portal session. Members can update their billing information, view invoices and manage subscriptions inside of the portal.

👉 Here’s an example of the portal: https://billing.stripe.com/session/test_YWNjdF8xR3kxaUZBbHF2S3B4SkN1LF9Mc1ByazliV0V0cXdYelZBcVYzb1E3U3doOVcyMFZE01005v3YIkKm

import {
  useCustomerPortal,
  MemberstackProtected,
  SignInModal
} from "@memberstack/react";
...
const openPortal = useCustomerPortal({
  priceIds: ["prc_sb_..."]
});
...
return (
  <MemberstackProtected onUnauthorized={<SignInModal />}>
    <button onClick={openPortal}>Open Portal</button>
  </MemberstackProtected>
);

useMemberstackModal

The useMemberstackModal hook returns the openModal and hideModal methods, which you can use to easily interact with Memberstack's provided modals.

Read the Modals section for more information about the configuration

💡 Although you can directly use the memberstack.openModal method without using the useMemberstackModal hook, the openModal method provided by the hook ensures that the modal always gets loaded once Memberstack has finished initializing. This means that you don't have to make sure that Memberstack is able to open your modal; we take care of that for you.

Examples

Login:

import { useMemberstackModal } from "@memberstack/react";

function Login() {
  const { openModal, hideModal } = useMemberstackModal();

  return (
    <div
      onClick={() =>
        openModal({
          type: "LOGIN",
          // planId: "pln_...",
          // priceId: "prc_..."
        })
        .then(({ data, type }) => {
          console.log('data', data);
          console.log('type: ', type);
          hideModal();
        })
      }
    >
      Log in
    </div>
  );
}

Signup:

import { useMemberstackModal } from "@memberstack/react";

function Signup() {
  const { openModal } = useMemberstackModal();

  return (
    <div
      onClick={() =>
        openModal({
          type: "SIGNUP",
          planId: ["pln_..."],
          // priceId: "prc_..."
        })
        .then(({ data, type }) => {
          console.log('data', data);
          console.log('type: ', type);
          hideModal();
        })
      }
    >
      Sign up
    </div>
  );
}

Forgot Password:

import { useMemberstackModal } from "@memberstack/react";

function PasswordSettings() {
  const { openModal } = useMemberstackModal();

  return (
    <div
      onClick={() => openModal({ type: "FORGOT_PASSWORD" })}
    >
      Forgot Password?
    </div>
  );
}

UI Components

Memberstack UI components are used to render beautiful views contained within our prebuilt UI collection. These UI components will automatically open as modals when the page loads.

Presents a sign-up view that takes the same properties specified in the useMemberstackModal requirements.

import { SignUpModal } from "@memberstack/react";

export default function SignUpPage() {
  return (
    <SignUpModal planId={["pln_..."]} />
  );
}

Presents a sign-in view that takes the same properties specified in the useMemberstackModal requirements.

...
import { SignInModal } from "@memberstack/react";

export default function SignInPage() {
  return (
    <SignInModal />
  );
}

Presents a profile view where the user can manage their personal information.

...
import {
  MemberstackProtected,
  SignInModal,
  ProfileModal
} from "@memberstack/react";

export default function ProfilePage() {
  return (
    <MemberstackProtected onUnauthorized={<SignInModal />}>
      <ProfileModal />
      <Link href="/">Go Back</Link>
    </MemberstackProtected>
  );
}

These callback props are found on all modals.

Name Description Type
onSuccess Runs before the onClose when the modal api call is successful ({data,type}) => void
onError Runs before the onClose when the modal api call is unsuccessful (error) => void
onClose Ran every time the modal closes () => void

<SignUpModal />

Name Description Type
planId An array of plan ids for a user to sign up with. string[]

Logic Wrapper Components

Memberstack logic wrappers are components that allow you to conditionally render content based on the member’s logged-in state plus a variety of other checks, like plans & permissions.

Allows you to conditionally render content based on the currently authenticated member, their plans, and/or permissions.

Parameters:

  • allow object An optional object to give you more control over which members to authorize. By default, only authenticated members have access to the protected components, but you can use the values within the access object to get more specific.
  • permissions array A list of permission names.
  • plans array A list of plan ids.
  • onUnauthorized function | React element(s) A callback function or React element to invoke/render when the member is not authorized.
  • fallback React element A fallback element when Memberstack is loading information before (un)authorizing.

Response:

  • None

Examples:

All Authenticated

<MemberstackProtected>
  ...
</MemberstackProtected>

With Permissions

<MemberstackProtected
  allow={{
    permissions: ["view:workout"]
  }}
>
  ...
</MemberstackProtected>

With Plans

<MemberstackProtected
  allow={{
    plans: ["pln_123"]
  }}
>
  ...
</MemberstackProtected>

With Permissions and Plans

<MemberstackProtected
  allow={{
    plans: ["pln_123"],
    permissions: ["view:workout"]
  }}
>
  ...
</MemberstackProtected>

With onUnauthorized Callback

<MemberstackProtected
  onUnauthorized={() => router.redirect('/login')}
>
  ...
</MemberstackProtected>

With onUnauthorized Element

<MemberstackProtected
  onUnauthorized={<UnauthorizedPage />}
>
  ...
</MemberstackProtected>

With Fallback

<MemberstackProtected
  fallback={<div>Loading.....</div>}
>
  ...
</MemberstackProtected>

Allows you to conditionally render content based on the member being logged in

Parameters:

  • None

Response:

  • None

Example:

<LoggedOut>
  <LoginScreen />
</LoggedOut>

<LoggedIn>
  <p>Logged In</p>
</LoggedIn>

<MemberstackProtected
  fallback={<div>Loading.....</div>}
  onUnauthorized={<SignInModal onSuccess={({ data }) => {
    console.log(data)
  }} />}
>
  <div>
    <main>
      <h1>
        Welcome to
        <br />
        <a href="https://memberstack.com">Memberstack</a>!
      </h1>

      {userId} - {isLoggedIn}

      <button onClick={signOut}>Sign Out</button>
    </main>
  </div>
</MemberstackProtected>

Examples

React-Router

Getting started

Install react-router-dom & @memberstack/react

// main.tsx

import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import { MemberstackProvider } from '@memberstack/react';
import Settings from './Settings.tsx';

ReactDOM.createRoot(document.getElementById('root')!)
  .render(
    <BrowserRouter>
      <MemberstackProvider config={{
        publicKey: import.meta.env.VITE_MEMBERSTACK_PUBLIC_KEY as string
      }}>
        <Routes>
          <Route path='/' index element={<App />} />
          <Route path='/settings' element={<Settings />} />
        </Routes>
      </MemberstackProvider>
    </BrowserRouter>
  );
// App.tsx

import './App.css';
import { LoggedIn, LoggedOut, MemberstackProtected, SignInModal, useAuth } from "@memberstack/react";

function App() {
  const { userId, signOut, isLoggedIn } = useAuth();

  return (
    <>
      <LoggedOut><p>Logged Out</p></LoggedOut>
      <LoggedIn><p>Logged In</p></LoggedIn>
      <MemberstackProtected
        fallback={<div>Loading.....</div>}
        onUnauthorized={<SignInModal onSuccess={({ data }) => {
          console.log(data)
        }} />}
      >
        <div>
          <main>
            <h1>
              Welcome to
              <br />
              <a href="https://memberstack.com">Memberstack</a>!
            </h1>

            {userId} - {isLoggedIn}

            <button onClick={signOut}>Sign Out</button>
          </main>
        </div>
      </MemberstackProtected>
    </>
  );
}

export default App;
// Settings.tsx

import './App.css';
import {ProfileModal} from "@memberstack/react";
import { useNavigate } from "react-router-dom";

function Settings() {
  let navigate = useNavigate();

  const handleModalClose = () => {
    navigate("/");
  };

  return (
    <div>
      <ProfileModal onClose={handleModalClose} />
    </div>
  );
}

export default Settings;

Was this article helpful?

Comments

5 comments

  • Comment author
    Ali Yar Khan

    Can this work in React Native ?

    1
  • Comment author
    Duncan Hamra

    Hey Ali Yar Khan, we have not tested any Memberstack apps in React Native. We've been focused on web. 

    0
  • Comment author
    Edgar

    Hi! Got a security question. Memberstack Provider requires a config prop containing the public key. What's Memberstack's approach to hiding the public key on the client side? If we are to send it as a server request - the client can still access it if they visit the endpoint URL.

    0
  • Comment author
    Duncan Hamra

    Edgar great question!

    I need Tylers confirmation on this but, public key represents which Memberstack customer you are (so that we know which directory to check your users against). This is not confidential information, so there is no problem that this information can be seen.
    1
  • Comment author
    Tyler Bell

    Hi Edgar, the public key is not confidential and is public 🙂

    1

Please sign in to leave a comment.