Skip to main content
The ParaProvider component wraps your React application to provide access to Para hooks and manage the SDK instance.

Import

import { ParaProvider } from "@getpara/react-sdk";

Usage

import { ParaProvider } from "@getpara/react-sdk";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        paraClientConfig={{
          apiKey: "your-api-key",
        }}>
        <YourApp />
      </ParaProvider>
    </QueryClientProvider>
  );
}

Loading State

By default, ParaProvider blocks rendering until the SDK is ready. You can customize this behavior:

With Fallback UI

Show a loading indicator instead of a blank screen while the SDK initializes:
<ParaProvider
  paraClientConfig={{ apiKey: "your-api-key" }}
  config={{ appName: "My App" }}
  fallback={<LoadingSpinner />}
>
  <YourApp />
</ParaProvider>

With Immediate Rendering

Render children immediately and let them handle the loading state using useParaStatus():
<ParaProvider
  paraClientConfig={{ apiKey: "your-api-key" }}
  config={{ appName: "My App" }}
  waitForReady={false}
>
  <YourApp />
</ParaProvider>
import { useParaStatus } from "@getpara/react-sdk";

function YourApp() {
  const { isReady } = useParaStatus();

  if (!isReady) return <LoadingSpinner />;
  return <Dashboard />;
}

Advanced Usage

With Event Callbacks

function AppWithCallbacks() {
  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        paraClientConfig={{
          apiKey: process.env.REACT_APP_PARA_API_KEY,
        }}
        callbacks={{
          onLogin: (event) => {
            console.log("User logged in:", event.detail.data);
            navigate("/dashboard");
          },
          onLogout: (event) => {
            console.log("User logged out");
            clearUserData();
            navigate("/");
          },
          onWalletCreated: (event) => {
            console.log("New wallet:", event.detail.data);
            toast.success("Wallet created successfully!");
          },
          onSignMessage: (event) => {
            console.log("Message signed:", event.detail.data);
            analytics.track("message_signed", {
              walletType: event.detail.data.walletType
            });
          }
        }}>
        <YourApp />
      </ParaProvider>
    </QueryClientProvider>
  );
}

With Custom Para Instance

This can be useful if you need to use the Para instance outside of the React tree, i.e. in the callbacks on the ParaProvider.
function AppWithCustomClient() {
  const paraClient = useMemo(() => {
    return new ParaWeb("your-api-key", {
      debugMode: true,
      customHeaders: {
        "X-Custom-Header": "value"
      }
    });
  }, []);

  return (
    <QueryClientProvider client={queryClient}>
      <ParaProvider
        paraClientConfig={paraClient}
        {/* Optional additional ParaProvider config */}
        config={{
          disableAutoSessionKeepAlive: false
        }}>
        <YourApp />
      </ParaProvider>
    </QueryClientProvider>
  );
}

Notes

  • The ParaProvider must wrap any components that use Para hooks
  • It requires QueryClientProvider from React Query as a parent
  • Event callbacks receive events with a detail property containing data and optional error
  • The provider automatically manages session keep-alive unless disabled
  • By default, children are not rendered until the SDK is ready. Use fallback to show loading UI, or waitForReady={false} to render children immediately
  • All child components can access Para hooks without additional setup