The StackOne Hub lets end-users authenticate and configure connectors enabled in your StackOne projects.
Choosing a Hub Version
StackOne offers two Hub versions. We recommend New Hub (beta) for new projects.
New Hub (beta) Hub (v1) Package @stackone/hub@stackone/react-hub / connect.jsArchitecture Native React component Iframe-based (loads external script) React Support Yes Yes Non-React Support Not yet Yes (connect.js) Filtering & Search Yes No Error Messages Detailed with resolution steps Basic Theming Full theming via design system Limited styling options Performance Fast (direct API calls) Average (iframe network hops) Status Beta (Recommended) Legacy
Why New Hub (beta)?
New Hub (beta) is a ground-up rebuild with a fundamentally different architecture:
Native React Component : New Hub (beta) renders directly in your React tree. Hub (v1) loads an external script (connect.js) that injects an iframe. This means New Hub (beta) shares your app’s React context, supports proper component composition, and eliminates iframe-related overhead.
Direct API Communication : New Hub (beta) makes API calls directly from your app. Hub (v1) routes requests through an iframe hosted on StackOne’s domain, adding latency from cross-origin communication and extra network hops.
Full Theming Support : New Hub (beta) uses our Malachite design system, giving you complete control over colors, typography, and styling. You can match your app’s design without CSS hacks or iframe styling limitations.
Better Event Handling : New Hub (beta) uses native React callbacks. Hub (v1) relies on postMessage to communicate events across the iframe boundary, which can be less reliable and harder to debug.
Use New Hub (beta) for new projects. It’s in beta but production-ready. Hub (v1) remains available for existing implementations.
Quick Start
New Hub (beta) - React
Hub (v1) - React
Hub (v1) - Vanilla JS
New Hub (beta) (@stackone/hub) offers filtering, search, detailed error messages, and full theming support. New Hub (beta) is in beta. APIs may change without notice.
Install the package
npm install @stackone/hub
Get a session token from your backend
The Hub needs a connect session token to securely communicate with StackOne. This token must be generated server-side to keep your API key secure. async function retrieveConnectSessionToken () {
const response = await fetch ( '/api/stackone/connect-session' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ username: '[email protected] ' }),
});
const { token } = await response . json ();
return token ;
}
See Connect your Backend with StackOne for backend implementation.
Add the component
import { StackOneHub } from "@stackone/hub" ;
import { useEffect , useState } from "react" ;
function ConnectorPage () {
const [ token , setToken ] = useState < string >();
useEffect (() => {
retrieveConnectSessionToken (). then ( setToken );
}, []);
if ( ! token ) return < div > Loading... </ div > ;
return (
< StackOneHub
token = { token }
onSuccess = { ( account ) => {
console . log ( 'Connected:' , account . id , account . provider );
} }
onCancel = { () => console . log ( 'Cancelled' ) }
onClose = { () => console . log ( 'Closed' ) }
/>
);
}
Hub (v1) is our legacy Hub. For new projects, use New Hub (beta) above.
The legacy Hub (@stackone/react-hub) provides a hook-based API.
Install the package
npm install @stackone/react-hub
Create a function to retrieve the session token
The Hub needs a connect session token to securely communicate with StackOne. This token must be generated server-side to keep your API key secure. export const retrieveConnectSessionToken = async ({ username , provider }) => {
const response = await fetch ( '/api/stackone/connect-session' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
originUsername: username ,
provider , // optional - skip connector listing
}),
});
const { token } = await response . json ();
return { token };
};
See Connect your Backend with StackOne for backend implementation.
Create a Link Account Button
import { useCallback } from 'react' ;
import { useStackOneHub } from '@stackone/react-hub' ;
const LinkAccountButton = () => {
const { startConnect } = useStackOneHub ();
const startFlow = useCallback ( async () => {
const { token } = await retrieveConnectSessionToken ({
username: '[email protected] '
});
startConnect ({
sessionToken: token ,
onSuccess : ( account ) => {
console . log ( 'Account linked:' , account );
},
onCancel : () => console . log ( 'Cancelled' ),
onClose : () => console . log ( 'Closed' ),
});
}, [ startConnect ]);
return < button onClick = { startFlow } > Connect Account </ button > ;
};
Hub (v1) is our legacy Hub. New Hub (beta) doesn’t yet support vanilla JS. For non-React apps, use connect.js below or generate Auth Links from the dashboard. The legacy Hub provides connect.js, a standalone JavaScript library for non-React applications.
Install the connect script
HTML Script Tag
Dynamic JavaScript
< script src = "https://app.stackone.com/stackone/connect.js" ></ script >
Create a function to retrieve the session token
async function retrieveConnectSessionToken () {
const response = await fetch ( '/api/stackone/connect-session' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ username: '[email protected] ' }),
});
return response . json ();
}
See Connect your Backend with StackOne for backend implementation.
Start the connect flow
const { token } = await retrieveConnectSessionToken ();
Connect . start ({
sessionToken: token ,
onSuccess : ( account ) => {
console . log ( 'Account linked:' , account );
},
onCancel : () => {
console . log ( 'User cancelled' );
},
onClose : () => {
console . log ( 'Hub closed' );
},
});
API Reference
The StackOneHub component accepts these props: Prop Type Default Description tokenstring— Connect session token from your backend mode'integration-picker' | 'csv-importer''integration-picker'Hub mode accountIdstring— Pre-select a specific account to edit baseUrlstring'https://api.stackone.com'StackOne API base URL appUrlstring'https://app.stackone.com'StackOne App URL heightstring'500px'Component height theme'light' | 'dark' | PartialMalachiteTheme'light'Theme configuration showFooterLinksbooleantrueShow footer links onSuccess(account: { id: string; provider: string }) => void— Called when account is connected onCancel() => void— Called when user cancels onClose() => void— Called when hub closes
import { StackOneHub } from "@stackone/hub" ;
< StackOneHub
token = { sessionToken }
mode = "integration-picker"
height = "600px"
theme = "dark"
showFooterLinks = { false }
onSuccess = { ( account ) => {
console . log ( `Connected ${ account . provider } with ID ${ account . id } ` );
} }
onCancel = { () => console . log ( 'User cancelled' ) }
onClose = { () => console . log ( 'Hub closed' ) }
/>
The useStackOneHub hook returns a startConnect function: const { startConnect } = useStackOneHub ({ connectUrl? : string });
StartOptions Option Type Required Description sessionTokenstringYes Connect session token from your backend apiUrlstringNo Custom API URL stylesHubStylesNo Style customization onSuccess(account: Account) => voidNo Called when account is connected onCancel() => voidNo Called when user cancels onClose() => voidNo Called when hub closes
import { useStackOneHub } from '@stackone/react-hub' ;
const { startConnect } = useStackOneHub ();
startConnect ({
sessionToken: token ,
onSuccess : ( account ) => {
console . log ( 'Connected account:' , account . id );
},
onCancel : () => console . log ( 'Cancelled' ),
onClose : () => console . log ( 'Closed' ),
});
After loading the script, use the global Connect object: Connect . start ({
sessionToken: string , // Required - from your backend
apiUrl? : string , // Optional - custom API URL
styles? : HubStyles , // Optional - style customization
onSuccess? : ( account ) => void ,
onCancel? : () => void ,
onClose? : () => void ,
});
Full example: Connect . start ({
sessionToken: token ,
styles: {
inline: { containerId: 'hub-container' , width: '100%' , height: '600px' },
options: { back: true , close: true , bgColor: '#f5f5f5' },
},
onSuccess : ( account ) => {
console . log ( 'Account linked:' , account );
// account has: id, provider, status, etc.
},
onCancel : () => {
console . log ( 'User cancelled the flow' );
},
onClose : () => {
console . log ( 'Hub modal was closed' );
},
});
Style Customization
New Hub (beta) supports full theming with the theme prop: < StackOneHub
token = { token }
theme = "dark" // or "light"
/>
For custom theming, pass a PartialMalachiteTheme object: < StackOneHub
token = { token }
theme = { {
colors: {
primary: {
background: '#6366f1' ,
foreground: '#ffffff' ,
},
card: {
background: '#fafafa' ,
},
},
} }
/>
See the @stackone/hub repository for full theme options. The legacy Hub uses a styles object with two sections: HubStyles Interface interface HubStyles {
inline ?: {
containerId : string ; // Required - DOM element ID to embed the hub
width ?: string ; // e.g., '400px', '100%'
height ?: string ; // e.g., '500px', '100%'
};
options ?: {
back ?: boolean ; // Show/hide back arrow (default: true)
close ?: boolean ; // Show/hide close button (default: true)
bgColor ?: string ; // Background color (e.g., 'white', '#f0f0f0')
};
}
Default (Modal) vs Inline Default (Modal) - Hub opens in a centered modal overlay:startConnect ({ sessionToken: token });
Inline - Hub embeds in a specific container:startConnect ({
sessionToken: token ,
styles: {
inline: {
containerId: 'my-hub-container' ,
width: '400px' ,
height: '600px' ,
},
options: {
back: false ,
close: false ,
bgColor: 'transparent' ,
},
},
});
Hub Behavior Customization
Control which connectors appear in the Hub by configuring the connect session on your backend.
Filtering Connectors
You can specify a provider or categories property when creating the connect session to control which connectors appear in the Hub:
provider : Opens the Hub directly at the credential entry screen for a specific connector, bypassing the connector listing
categories : Filters the Hub to show only connectors from specified categories (e.g., hris, ats)
If neither is specified, the Hub displays all connectors enabled for the project.
The connector specified in provider must be enabled in the Auth Configs page of the associated project.
Find valid provider keys in the Supported Connectors list under the Provider Key column.
Backend Examples
JavaScript
JavaScript (Categories)
// Skip connector list, go directly to BambooHR
const result = await stackOne . connectSessions . createConnectSession ({
originOwnerId: "customer-123" ,
originOwnerName: "Acme Inc" ,
provider: "bamboohr" , // Go directly to this connector
});
Event Callbacks
All Hub versions support these callbacks:
Callback When it fires onSuccessUser successfully connects an account. Receives account object with id and provider. onCancelUser explicitly cancels the flow (clicks cancel/back). onCloseHub closes for any reason (success, cancel, or clicking outside modal).
Use onSuccess to update your UI or trigger backend syncs. Use onClose as a cleanup handler that always runs.
startConnect ({
sessionToken: token ,
onSuccess : ( account ) => {
// Refresh your linked accounts
fetchLinkedAccounts ();
showNotification ( `Connected to ${ account . provider } ` );
},
onCancel : () => {
// User backed out - maybe show a prompt
console . log ( 'Connection cancelled' );
},
onClose : () => {
// Always runs - cleanup
setIsConnecting ( false );
},
});
Dashboard Access
You can also use the Hub directly from the StackOne dashboard without embedding:
Connection Links
Generate connection links from your dashboard to share with end-users.
Direct Account Linking
Link accounts directly from the dashboard interface.
Backend Setup
Both hub versions require a connect session token generated from your backend. This keeps your API key secure.