Loading...
Loading...
The Quiltt React Native SDK provides Components for seamless integration of the Quiltt Connector into your React Native app.
This SDK currently supports iOS and Android.
For full documentation, additional examples and the source code, see the Quiltt React Native SDK on GitHub.
@quiltt/react-native expects react, react-native,react-native-webview, base-64 and react-native-url-polyfill as peer dependencies.
$ npm install base-64 react-native-webview react-native-url-polyfill
$ npm install @quiltt/react-native
$ pnpm add base-64 react-native-webview react-native-url-polyfill
$ pnpm add @quiltt/react-native
# If you're using pnpm with an Expo app, make sure to add `node-linker=hoisted` to your `.npmrc` file
$ yarn add base-64 react-native-webview react-native-url-polyfill
$ yarn add @quiltt/react-native
Quiltt always prioritizes OAuth-based connections, which require your user to provide consent on their institution's website or app, and then be redirected back to your app. This means that your application needs to be able to gracefully handle this redirect by returning them to the Connector flow in your app.
For production Environments, you must always pass a https:// URL to appLauncherUrl. This URL must be a valid App Link (Android) or Universal Link (iOS) that can launch your app, like https://app.mydomain.com/connect_bank.
For more information, see Expo's guides on Android App Links and iOS Universal Links.
For local development, you can use http://. If you're using Expo, we recommend running your dev server with the --tunnel option, which will give you a publicly-accessible URL that you can use to construct your oauthRedirectUrl.
npx expo start --tunnel
This will serve your app from a public URL like: http://xxxxxxx.purple.19000.exp.direct:80.
https://*.callback.quiltt.ioWhen users authenticate with financial institutions, they'll be redirected back to your app via a deep link. You need to listen for these deep links and pass them to the QuilttConnector to complete the OAuth flow.
This deep link handling is primarily needed for Android, where OAuth flows typically open in an external browser. On iOS, the OAuth flow usually stays within the app's web view, so this fallback mechanism may not be necessary. However, implementing it ensures consistent behavior across both platforms.
Some Android users may experience OAuth flows that never complete—they authenticate successfully with their bank but get stuck when redirecting back to your app. This happens because Android opens OAuth pages in an external browser (typically Chrome), and recent changes in how Chrome Custom Tabs and intents handle navigation have made it harder for the WebView to maintain state across this boundary.
To handle this, use the connector's ref API to forward OAuth callbacks:
import { useEffect, useRef } from 'react'
import { Linking, View } from 'react-native'
import { QuilttConnector } from '@quiltt/react-native'
import type { QuilttConnectorHandle } from '@quiltt/react-native'
export const ConnectorScreen = () => {
// Create a ref to the connector
const connectorRef = useRef<QuilttConnectorHandle>(null)
const appLauncherUrl = 'https://myapp.com/quiltt/callback'
// Listen for deep links and forward OAuth callbacks
useEffect(() => {
const subscription = Linking.addEventListener('url', (event) => {
console.log('Deep link received:', event.url)
// Check if this is an OAuth callback for Quiltt
if (event.url.includes('quiltt/callback')) {
console.log('Processing Quiltt OAuth callback')
connectorRef.current?.handleOAuthCallback(event.url)
}
})
return () => subscription.remove()
}, [])
return (
<View style={{ flex: 1 }}>
<QuilttConnector
ref={connectorRef}
connectorId="<CONNECTOR_ID>"
appLauncherUrl={appLauncherUrl}
onExitSuccess={handleExitSuccess}
/>
</View>
)
}
Important Notes:
ref prop is required when handling OAuth callbacksappLauncherUrl configurationTo load the Connector for use by a pre-existing end-user, you'll need to pass a valid Session token. See the Authentication guide for more information on generating Session tokens.
The below example shows how to set up a ConnectorScreen component, using React Navigation to handle Connector callbacks.
The QuilttProvider component is the easiest way to pass a Session token to your application. We recommend putting the component into its own screen so it can use up the entire mobile viewport.
Below is a simple example using React Navigation, with a HomeScreen and ConnectorScreen.
$ npm install @react-navigation/native @react-navigation/native-stack
$ pnpm add @react-navigation/native @react-navigation/native-stack
$ yarn add @react-navigation/native @react-navigation/native-stack
import { QuilttProvider } from '@quiltt/react'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
// Your App HomeScreen
import { ConnectorScreen } from './screens/ConnectorScreen'
import { HomeScreen } from './screens/HomeScreen'
// Screen for Quiltt Connector
const Stack = createNativeStackNavigator()
export const App = () => {
// See https://www.quiltt.dev/authentication/issuing-session-tokens
const sessionToken = '<SESSION_TOKEN_FROM_SERVER>'
return (
<QuilttProvider token={sessionToken}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen
options={{ headerShown: false }}
name="Connector"
component={ConnectorScreen}
/>
</Stack.Navigator>
</NavigationContainer>
</QuilttProvider>
)
}
export default App
ConnectorScreen componentimport { useEffect, useRef } from 'react'
import { Linking, View } from 'react-native'
import { QuilttConnector } from '@quiltt/react-native'
import type { ConnectorSDKCallbackMetadata, QuilttConnectorHandle } from '@quiltt/react-native'
import type { NavigationProp } from '@react-navigation/native'
type ConnectorScreenProps = {
navigation: NavigationProp<any, any>
}
export const ConnectorScreen = ({ navigation }: ConnectorScreenProps) => {
const connectorRef = useRef<QuilttConnectorHandle>(null)
const appLauncherUrl = '<YOUR_HTTPS_APP_LINK>'
// Handle OAuth deep links (primarily needed for Android)
useEffect(() => {
const subscription = Linking.addEventListener('url', (event) => {
if (event.url.includes('quiltt/callback')) {
connectorRef.current?.handleOAuthCallback(event.url)
}
})
return () => subscription.remove()
}, [])
return (
<View style={{ flex: 1 }}>
<QuilttConnector
ref={connectorRef}
connectorId="<CONNECTOR_ID>"
appLauncherUrl={appLauncherUrl}
// See the JavaScript API for the full list of available callbacks
onExitSuccess={(metadata: ConnectorSDKCallbackMetadata) => {
console.log('Successfully connected ' + metadata.connectionId)
navigation.navigate('Home')
}}
onExitAbort={() => navigation.navigate('Home')}
/>
</View>
)
}
import { useEffect, useRef } from 'react'
import { Linking, View } from 'react-native'
import { QuilttConnector } from '@quiltt/react-native'
import type { QuilttConnectorHandle } from '@quiltt/react-native'
export const ConnectorScreen = ({ navigation }) => {
const connectorRef = useRef<QuilttConnectorHandle>(null)
const appLauncherUrl = '<YOUR_HTTPS_APP_LINK>'
useEffect(() => {
const subscription = Linking.addEventListener('url', (event) => {
if (event.url.includes('quiltt/callback')) {
connectorRef.current?.handleOAuthCallback(event.url)
}
})
return () => subscription.remove()
}, [])
return (
<View style={{ flex: 1 }}>
<QuilttConnector
ref={connectorRef}
connectorId="<CONNECTOR_ID>"
appLauncherUrl={appLauncherUrl}
institution="<SEARCH_TERM>"
// See the JavaScript API for the full list of available callbacks
onExitSuccess={(metadata) => {
console.log('Successfully connected ' + metadata.connectionId)
navigation.navigate('Home')
}}
onExitAbort={() => navigation.navigate('Home')}
/>
</View>
)
}
To use the Reconnect Flow, simply supply a connectionId to the QuilttConnector component.
import { useEffect, useRef } from 'react'
import { Linking, View } from 'react-native'
import { QuilttConnector } from '@quiltt/react-native'
import type { QuilttConnectorHandle } from '@quiltt/react-native'
export const ConnectorScreen = ({ navigation }: ConnectorScreenProps) => {
const connectorRef = useRef<QuilttConnectorHandle>(null)
const appLauncherUrl = '<YOUR_HTTPS_APP_LINK>'
useEffect(() => {
const subscription = Linking.addEventListener('url', (event) => {
if (event.url.includes('quiltt/callback')) {
connectorRef.current?.handleOAuthCallback(event.url)
}
})
return () => subscription.remove()
}, [])
return (
<View style={{ flex: 1 }}>
<QuilttConnector
ref={connectorRef}
connectorId="<CONNECTOR_ID>"
connectionId="<CONNECTION_ID>"
appLauncherUrl={appLauncherUrl}
// See the JavaScript API for the full list of available callbacks
onExitSuccess={(metadata) => {
console.log('Successfully reconnected ' + metadata.connectionId)
navigation.navigate('Home')
}}
onExitAbort={() => navigation.navigate('Home')}
/>
</View>
)
}
Use the useQuilttResolvable hook to check if external provider institution IDs (e.g., Plaid) are supported to your connector.
Contact Quiltt Support to enable access to this feature.
import { useQuilttResolvable } from '@quiltt/react-native'
import { useEffect } from 'react'
function ResolvableConnector({ plaidInstitutionId, children }) {
const { checkResolvable, isResolvable, isLoading } = useQuilttResolvable('my-connector-id')
useEffect(() => {
checkResolvable({ plaid: plaidInstitutionId })
}, [plaidInstitutionId])
if (isLoading) return <Text>Checking...</Text>
if (!isResolvable) return null
return <>{children}</>
}
// Usage
<ResolvableConnector plaidInstitutionId="ins_3">
<QuilttConnector connectorId="my-connector-id" />
</ResolvableConnector>
The example above will only render the Quiltt launcher button if your Plaid-enabled Connector supports connecting to Chase.
The React Native package comes bundled with the @quiltt/core package, which contains type definitions for all components and hooks.
See the definition file on GitHub