React SDK

Use React hooks and pre-built UI components to integrate Membrane into your React application and build an integrations page for your customers.

🖥️

An interactive version of this guide is available in Membrane Console.

Step 1: Generate Authentication Token

To access Membrane through the REST API or Front-end SDK, you need an access token that contains information about your workspace, permissions, and the customer using the integration.

Create an endpoint on your backend that generates JWT tokens. The token must include your workspace key as the issuer (iss), a customer identifier (id), and an expiration time (exp).

You can find a test token in your workspace settings. To learn how to generate production tokens, check the Authentication guide.

Step 2: Setup React SDK

Install the Membrane React SDK and wrap your app with the provider.

Install React SDK

npm install @membranehq/react

Initialize Provider

The fetchToken function should call your backend endpoint that generates the authentication token from the previous step.

import { MembraneProvider } from '@membranehq/react'

async function fetchToken() {
  const response = await fetch('/api/membrane-token')
  const { token } = await response.json()
  return token
}

export function MyApp() {
  return (
    <MembraneProvider fetchToken={fetchToken}>
      <YourApp />
    </MembraneProvider>
  )
}

Reference: MembraneProvider

Step 3: Display available integrations

Use the useIntegrations hook to fetch the list of available integrations. The hook returns integration metadata including name, logo, and description that you can use to build your catalog UI.

Get list of integrations

import { useIntegrations } from '@membranehq/react'

function IntegrationsCatalog() {
  const { items: integrations, loading } = useIntegrations()

  if (loading) return <div>Loading...</div>

  return (
    <ul>
      {integrations?.map((integration) => (
        <li key={integration.key}>
          <img src={integration.logoUri} alt={integration.name} />
          <span>{integration.name}</span>
        </li>
      ))}
    </ul>
  )
}

Reference: useIntegrations

Search integrations

import { useIntegrations } from '@membranehq/react'

function IntegrationsCatalog({ searchQuery }) {
  const { items: integrations, loading } = useIntegrations({ search: searchQuery })

  // ... render integrations
}

Reference: useIntegrations

Step 4: Let user connect to a selected integration

When a user clicks "Connect" on an integration, call openNewConnection() to launch the connection flow. This opens a popup that guides the user through authentication with the external app.

Open connection flow

import { useMembrane } from '@membranehq/react'

function ConnectButton({ integrationKey }) {
  const membrane = useMembrane()

  const handleConnect = async () => {
    await membrane.integration(integrationKey).openNewConnection()
    // Popup closes automatically after successful connection
    // The useIntegrations hook will automatically refresh
  }

  return <button onClick={handleConnect}>Connect</button>
}

Reference: IntegrationAccessor.openNewConnection

ℹ️

Advanced options

For more control over the connection flow, you can enable multiple connections per integration, customize integration parameters, or implement a custom OAuth callback. See the Connection UI documentation for details.

Step 5: Show connections

When a user connects to an app, a new connection is created. Use the useConnections hook to display the user's connections and show which integrations are active.

Check the disconnected flag on each connection to show the current status. A disconnected connection needs to be re-authenticated.

Get list of connections

import { useConnections } from '@membranehq/react'

function ConnectionsList() {
  const { items: connections, loading } = useConnections()

  if (loading) return <div>Loading...</div>

  return (
    <ul>
      {connections?.map((connection) => (
        <li key={connection.id}>
          <span>{connection.name}</span>
          {connection.disconnected && <span className="status">Disconnected</span>}
        </li>
      ))}
    </ul>
  )
}

Reference: useConnections

Step 6: Manage connection

After a connection is created, let users manage it: re-connect if disconnected, or delete it.

Re-connect

import { useConnections, useMembrane } from '@membranehq/react'

function ConnectionsWithReconnect() {
  const { items: connections } = useConnections()
  const membrane = useMembrane()

  const handleReconnect = async (connectionId) => {
    await membrane.connection(connectionId).openReconnectUI()
    // Opens connection settings where user can re-authenticate
  }

  return (
    <ul>
      {connections?.map((connection) => (
        <li key={connection.id}>
          <span>{connection.name}</span>
          <button onClick={() => handleReconnect(connection.id)}>Reconnect</button>
        </li>
      ))}
    </ul>
  )
}

Reference: ConnectionAccessor.openReconnectUI

Delete connection

import { useConnections, useMembrane } from '@membranehq/react'

function ConnectionsWithDelete() {
  const { items: connections } = useConnections()
  const membrane = useMembrane()

  const handleDelete = async (connectionId) => {
    await membrane.connection(connectionId).archive()
    // The useConnections hook will automatically refresh
  }

  return (
    <ul>
      {connections?.map((connection) => (
        <li key={connection.id}>
          <span>{connection.name}</span>
          <button onClick={() => handleDelete(connection.id)}>Delete</button>
        </li>
      ))}
    </ul>
  )
}

Reference: ConnectionAccessor.archive

Reference

Explore the complete React SDK Reference to discover all available hooks and components.