Skip to main content
The frontend SDK lets you authenticate users with third-party APIs directly from your browser code. It is available on npm as @nangohq/frontend.

Installation

npm install @nangohq/frontend

Constructor

import Nango from '@nangohq/frontend';

// Recommended: use a connect session token (created server-side)
const nango = new Nango({ connectSessionToken: '<SESSION-TOKEN>' });

// Legacy: use a public key directly (still supported)
const nango = new Nango({ publicKey: '<PUBLIC-KEY>' });
connectSessionToken
string
A short-lived session token created server-side via nango.createConnectSession(). This is the recommended approach — it scopes the session to a specific end user and limits which integrations they can connect.
publicKey
string
Your environment public key from the Nango dashboard. This is not sensitive, but it gives access to all integrations. Prefer connectSessionToken for production.
host
string
The Nango instance URL. Defaults to https://api.nango.dev. Use http://localhost:3003 for local development or your self-hosted instance URL.
websocketsPath
string
Custom WebSocket path for self-hosted instances. Defaults to /.
width
number
Width of the OAuth popup window in pixels.
height
number
Height of the OAuth popup window in pixels.
debug
boolean
When true, prints additional console logs to help debug authorization issues.
Find your public key in Settings > Environment Settings in the Nango dashboard.

Connect UI

The recommended way to integrate Nango in your frontend. openConnectUI renders a full-screen iframe that guides users through connecting their accounts.
const connectUI = nango.openConnectUI({
    sessionToken: '<SESSION-TOKEN>',
    onEvent: (event) => {
        if (event.type === 'connect') {
            console.log('Connected:', event.payload.connectionId);
        }
        if (event.type === 'close') {
            console.log('User closed the Connect UI');
        }
        if (event.type === 'error') {
            console.error('Error:', event.payload.errorMessage);
        }
    }
});
sessionToken
string
The connect session token. Can be set asynchronously via connectUI.setSessionToken(token) after the UI is opened.
onEvent
(event: ConnectUIEvent) => void
Callback fired on UI events. See event types below.
baseURL
string
The URL to load the Connect UI from. Defaults to https://connect.nango.dev.
apiURL
string
The Nango API URL to use inside the Connect UI. Defaults to https://api.nango.dev.
detectClosedAuthWindow
boolean
When true, a closed OAuth popup is treated as a failed authorization. Defaults to false.
lang
string
Language code for the Connect UI (e.g. en, fr). Defaults to the browser language.
themeOverride
'light' | 'dark' | 'system'
Override the UI theme, independent of your dashboard setting.
Returns A ConnectUI instance with the following methods:
  • connectUI.setSessionToken(token) — update the session token asynchronously
  • connectUI.close() — programmatically close the Connect UI

Connect UI events

Event typePayloadDescription
readyThe iframe has loaded and is ready to receive the session token.
connect{ connectionId, providerConfigKey }A connection was successfully created.
closeThe user closed the Connect UI.
error{ errorType, errorMessage }An error occurred during the flow.
settings_changedConnectUISettingsThe user changed a UI setting (e.g. theme).

React integration

import { useState } from 'react';
import Nango from '@nangohq/frontend';

export function ConnectButton() {
    const [status, setStatus] = useState<string>('idle');

    const handleConnect = async () => {
        // 1. Create a session token server-side
        const res = await fetch('/api/nango/session', { method: 'POST' });
        const { token } = await res.json();

        // 2. Open Connect UI
        const nango = new Nango({ connectSessionToken: token });

        nango.openConnectUI({
            onEvent: (event) => {
                if (event.type === 'connect') {
                    setStatus(`Connected: ${event.payload.connectionId}`);
                } else if (event.type === 'error') {
                    setStatus(`Error: ${event.payload.errorMessage}`);
                }
            }
        });
    };

    return (
        <button onClick={handleConnect}>
            Connect an integration
        </button>
    );
}

Headless auth (nango.auth)

For custom auth flows without the Connect UI, use nango.auth directly. This opens an OAuth popup or submits credentials to Nango.
Opens a popup window for the OAuth flow.
try {
    const result = await nango.auth('my-github-integration');
    console.log('Connected:', result.connectionId);
} catch (error) {
    console.error('Auth failed:', error.type, error.message);
}
Parameters
providerConfigKey
string
required
The integration ID as configured in the Nango dashboard.
connectionId
string
An optional ID for this connection. If omitted, Nango generates one.
options.credentials
object
Credentials to submit for non-OAuth integrations. Accepts apiKey, username/password, oauth_client_id_override/oauth_client_secret_override, and others depending on the provider.
options.detectClosedAuthWindow
boolean
When true, closing the OAuth popup before completion is treated as a failed auth.
options.authorization_params
Record<string, string>
Additional query parameters to append to the OAuth authorization URL.
options.user_scope
string[]
User-specific OAuth scopes (Slack only).
Success response
providerConfigKey
string
The integration ID.
connectionId
string
The ID of the newly created connection.

Reconnect

Re-authorizes an existing connection. Requires a connect session token.
const nango = new Nango({ connectSessionToken: '<SESSION-TOKEN>' });

try {
    await nango.reconnect('my-github-integration');
} catch (error) {
    console.error(error.message);
}

Plain JavaScript integration

<script type="module">
    import Nango from 'https://cdn.jsdelivr.net/npm/@nangohq/frontend/dist/index.js';

    async function connectGitHub() {
        const res = await fetch('/api/nango/session', { method: 'POST' });
        const { token } = await res.json();

        const nango = new Nango({ connectSessionToken: token });
        nango.openConnectUI({
            onEvent: (event) => {
                if (event.type === 'connect') {
                    document.getElementById('status').textContent =
                        'Connected: ' + event.payload.connectionId;
                }
            }
        });
    }

    document.getElementById('connect-btn').addEventListener('click', connectGitHub);
</script>

<button id="connect-btn">Connect GitHub</button>
<p id="status"></p>

Error handling

All auth errors throw an AuthError instance with a type and message.
import Nango, { AuthError } from '@nangohq/frontend';

try {
    await nango.auth('my-github-integration');
} catch (error) {
    if (error instanceof AuthError) {
        switch (error.type) {
            case 'blocked_by_browser':
                alert('Please allow popups for this site.');
                break;
            case 'window_closed':
                console.log('User cancelled the flow.');
                break;
            case 'connection_test_failed':
                alert('Invalid credentials. Please try again.');
                break;
            default:
                console.error('Auth error:', error.type, error.message);
        }
    }
}
Error types
TypeDescription
missing_auth_tokenNeither a public key nor a session token was provided.
blocked_by_browserThe OAuth popup was blocked by the browser.
invalid_host_urlThe provided host URL is invalid.
missing_credentialsRequired credentials were not provided.
window_closedThe OAuth window was closed before the flow completed.
connection_test_failedCredential validation failed before the connection was established.
missing_connect_session_tokenReconnect was called without a session token.
resource_cappedThe connection limit for your plan has been reached.
unknown_errorAn unexpected error occurred.

Build docs developers (and LLMs) love