React Plaid Link Integration
react-plaid-link is a React component and hook library designed for integrating Plaid Link into React applications. As of version 4.1.1, it provides a modern, idiomatic React interface, primarily through the `usePlaidLink` hook, to manage the Plaid Link user experience. The library abstracts away the complexities of embedding and interacting with the Plaid Link JavaScript SDK, handling initialization, callbacks, and lifecycle events. It supports a wide range of React versions, from 16.8 up to 19, demonstrating active maintenance and compatibility with the latest React ecosystems. While the README does not specify a strict release cadence, the version history suggests regular updates to maintain compatibility and incorporate new Plaid Link features. Its primary differentiator is simplifying Plaid Link integration for React developers, offering explicit callback handlers for success, exit, and events, and clear mechanisms for handling OAuth flows.
Common errors
-
Plaid Link exited: { error_code: 'INVALID_LINK_TOKEN', error_type: 'ITEM_ERROR', ... }cause The `link_token` provided to the `usePlaidLink` hook is invalid, expired, or malformed, preventing Plaid Link from initializing correctly.fixVerify your backend is generating a valid, non-expired `link_token` using the Plaid API and that it's correctly passed to the `usePlaidLink` hook. Plaid Link tokens typically expire after 30 minutes, so fetch a fresh one for each new Link session. -
Cannot read properties of undefined (reading 'open') OR open is not a function
cause You are attempting to call the `open()` function returned by `usePlaidLink` before the Plaid Link script has fully loaded and initialized, or `open` was not correctly destructured.fixAlways check the `ready` boolean flag returned by `usePlaidLink` before calling `open()`. For example, `disabled={!ready}` on your button. Also, ensure `const { open, ready } = usePlaidLink(...)` correctly destructures the hook's return value. -
Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause The `usePlaidLink` hook is being called outside of a functional React component or a custom hook, which violates React's Rules of Hooks.fixEnsure `usePlaidLink` is invoked directly within the top level of a functional React component or another custom hook, and not inside loops, conditions, or nested functions. -
TypeError: Cannot destructure property 'open' of 'Object(...)' as it is null.
cause The `usePlaidLink` hook might be returning `null` or `undefined` in some edge cases (e.g., critical initialization failure, or if React context is misconfigured, though less common for this specific error).fixCheck for errors during `usePlaidLink` initialization (e.g., `error` return value). Ensure your React environment is set up correctly and no other issues are preventing the hook from returning its expected object. This error is rare and often points to a deeper React environment problem.
Warnings
- breaking Major version updates (e.g., from v3 to v4) often introduce breaking changes, particularly in API signatures and the preferred integration approach (e.g., moving from class components to hooks). Existing implementations might require significant refactoring.
- gotcha The `link_token` is a critical security credential that MUST be generated securely on your server-side application using the Plaid API. It should never be generated client-side directly within your React application due to security risks and API limitations.
- gotcha When handling OAuth flows, Plaid Link often needs to be opened immediately upon page load (e.g., after a redirect) rather than waiting for a user interaction. Incorrect handling can lead to broken OAuth experiences.
- gotcha Ensure your project's `react` and `react-dom` versions are compatible with the `react-plaid-link` peer dependencies (`^16.8.0 || ^17 || ^18 || ^19`). Incompatible peer dependencies can lead to runtime errors, hook issues, or build failures, even if the package installs successfully.
Install
-
npm install react-plaid-link -
yarn add react-plaid-link -
pnpm add react-plaid-link
Imports
- usePlaidLink
const { usePlaidLink } = require('react-plaid-link');import { usePlaidLink } from 'react-plaid-link'; - PlaidLinkOnSuccessMetadata
import { PlaidLinkOnSuccessMetadata } from 'react-plaid-link';import type { PlaidLinkOnSuccessMetadata } from 'react-plaid-link'; - PlaidLinkOnExitMetadata
import { PlaidLinkOnExitMetadata, PlaidLinkError } from 'react-plaid-link';import type { PlaidLinkOnExitMetadata, PlaidLinkError } from 'react-plaid-link';
Quickstart
import React, { useEffect, useState } from 'react';
import { usePlaidLink, PlaidLinkOnSuccessMetadata, PlaidLinkOnExitMetadata, PlaidLinkError } from 'react-plaid-link';
const MyPlaidLinkComponent: React.FC = () => {
// In a real application, the link_token is generated server-side.
// For this example, replace '<YOUR_GENERATED_LINK_TOKEN>' with a valid token
// fetched from your backend. If you don't have one, Plaid offers a quickstart
// for generating development tokens.
const [linkToken, setLinkToken] = useState<string | null>(null);
useEffect(() => {
// Simulate fetching link_token from your backend
const fetchLinkToken = async () => {
try {
// Example: const response = await fetch('/api/create-link-token');
// const data = await response.json();
// setLinkToken(data.link_token);
// Using a placeholder for demonstration purposes
setLinkToken('link-development-YOURPLAIDCLIENTID'); // Replace with a real token!
} catch (error) {
console.error('Error fetching link token:', error);
}
};
fetchLinkToken();
}, []);
const { open, ready, error } = usePlaidLink({
token: linkToken,
onSuccess: (public_token: string, metadata: PlaidLinkOnSuccessMetadata) => {
// Send the public_token to your server to exchange for an access_token
console.log('Plaid Link successful! Public Token:', public_token, 'Metadata:', metadata);
alert(`Public token received: ${public_token}`);
// Typically, you'd send this to your backend:
// fetch('/api/exchange_public_token', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ public_token, metadata }),
// });
},
onExit: (error: PlaidLinkError | null, metadata: PlaidLinkOnExitMetadata) => {
console.error('Plaid Link exited:', error, 'Metadata:', metadata);
},
onEvent: (eventName: string, metadata: any) => {
console.log('Plaid Link event:', eventName, metadata);
},
onLoad: () => {
console.log('Plaid Link loaded.');
}
});
return (
<div>
<h1>Connect to Plaid</h1>
<button onClick={() => open()} disabled={!ready || !linkToken}>
Connect Bank Account
</button>
{error && <p style={{ color: 'red' }}>Error during Plaid Link initialization: {error.message}</p>}
{!linkToken && <p>Loading Plaid Link token...</p>}
{!ready && linkToken && <p>Plaid Link is loading and not yet ready to open.</p>}
</div>
);
};
export default MyPlaidLinkComponent;