Skip to main content
Build an integrations page that lets your tenants connect their apps. We recommend splitting it into two sections: Connections (accounts they’ve already connected) and Integrations (apps available to connect).

Getting Started

  1. Complete the Quickstart: Product Integrations guide.
  2. Ask your coding agent to build the integration catalog for your app:
“Build an integrations page with two sections: ‘Your Connections’ showing connected accounts with disconnect, and ‘Available Integrations’ showing apps that can still be connected. Use the Membrane React SDK.”
If you want to learn how it works under the hood — read on.

React SDK

Install the React SDK and wrap your app with the provider.
npm install @membranehq/react
import { MembraneProvider } from '@membranehq/react'

export function MyApp() {
  return (
    <MembraneProvider fetchToken={fetchToken}>
      <YourApp />
    </MembraneProvider>
  )
}
The fetchToken function should call your backend endpoint that generates authentication tokens.

Complete example

The key pattern: fetch both integrations and connections, then split integrations into “connected” and “available” based on whether a connection exists.
import { useIntegrations, useConnections, useMembrane } from '@membranehq/react'
import { useMemo } from 'react'

function IntegrationsPage() {
  const membrane = useMembrane()
  const { items: integrations, loading: integrationsLoading } = useIntegrations()
  const { items: connections, loading: connectionsLoading } = useConnections()

  // Split integrations into connected vs available
  const connectedIntegrationIds = useMemo(() => new Set(connections?.map((c) => c.integrationId)), [connections])
  const availableIntegrations = useMemo(
    () => integrations?.filter((i) => !connectedIntegrationIds.has(i.id)),
    [integrations, connectedIntegrationIds],
  )

  if (integrationsLoading || connectionsLoading) return <div>Loading...</div>

  return (
    <div>
      {/* Section 1: Connected accounts */}
      <h2>Your Connections</h2>
      {connections?.length === 0 && <p>No connections yet.</p>}
      {connections?.map((connection) => (
        <div key={connection.id}>
          <span>{connection.name}</span>
          {connection.disconnected ? (
            <button onClick={() => membrane.ui.connect({ connectionId: connection.id })}>Reconnect</button>
          ) : (
            <button onClick={() => membrane.connection(connection.id).archive()}>Disconnect</button>
          )}
        </div>
      ))}

      {/* Section 2: Available apps to connect */}
      <h2>Available Integrations</h2>
      {availableIntegrations?.map((integration) => (
        <div key={integration.key}>
          <img src={integration.logoUri} alt='' width={24} />
          <span>{integration.name}</span>
          <button onClick={() => membrane.ui.connect({ integrationKey: integration.key })}>Connect</button>
        </div>
      ))}
    </div>
  )
}
Once an integration is connected, it moves from “Available Integrations” to “Your Connections” automatically. See the Playground for a full working example with styling and additional features.

Hooks reference

HookReturns
useIntegrations(){ items: Integration[], loading, error } — all integrations in your workspace
useConnections(){ items: Connection[], loading, error } — current tenant’s connections
useMembrane()The MembraneClient instance for imperative operations
Pass { search: query } to useIntegrations to add search filtering.

JavaScript SDK

For non-React apps, use the JavaScript SDK directly.
npm install @membranehq/sdk
import { MembraneClient } from '@membranehq/sdk'

const membrane = new MembraneClient({
  fetchToken: async () => {
    const response = await fetch('/api/membrane-token')
    const { token } = await response.json()
    return token
  },
})

// List available integrations
const integrations = await membrane.integrations.find()

// List current tenant's connections
const connections = await membrane.connections.find()

// Connect to an app (opens popup)
await membrane.ui.connect({ integrationKey: 'hubspot' })

// Reconnect a disconnected connection
await membrane.ui.connect({ connectionId: 'con_abc123' })

// Disconnect
await membrane.connection('con_abc123').archive()

REST API

For any language or framework, use the REST API directly. List integrations:
GET https://api.getmembrane.com/integrations
Authorization: Bearer {TOKEN}
List connections:
GET https://api.getmembrane.com/connections
Authorization: Bearer {TOKEN}
Connection UI: Redirect your user to Membrane’s hosted connection page:
https://ui.getmembrane.com/embed/integrations/{INTEGRATION_KEY}/connect?token={TOKEN}
Optional parameters: redirectUri (where to send the user after connecting), allowMultipleConnections=1, name (pre-set connection name). Reconnect: Redirect to:
https://ui.getmembrane.com/embed/connections/{CONNECTION_ID}/refresh?token={TOKEN}
See the full API Reference for all available endpoints.

Advanced