A guide to integrate Para SDK with TanStack Start while preserving server-side rendering capabilities.
This guide will walk you through the process of integrating the Para SDK with TanStack Start while preserving server-side rendering (SSR) capabilities.
TanStack Start is a full-stack React framework powered by TanStack Router. It provides full-document SSR, streaming, server functions, bundling, and more using tools like Nitro and Vite. It’s ready to deploy to your favorite hosting provider!
TanStack Start uses Nitro and Vite to bundle and deploy your application, providing:
A unified API for SSR, streaming, and hydration
Extraction of server-only code from your client-side code (e.g., server functions)
Bundling your application for deployment to any hosting provider
Since TanStack Start uses Vite under the hood, we need to set up polyfills for modules like crypto, buffer, etc. that Para SDK relies on. However, we only want to run these polyfills on the client, not on the server.
Install the Vite Node Polyfills plugin:
npm install vite-plugin-node-polyfills --save-dev
Configure the polyfills in your app.config.ts:
import { defineConfig } from "@tanstack/react-start/config";import tsConfigPaths from "vite-tsconfig-paths";import { nodePolyfills } from "vite-plugin-node-polyfills";export default defineConfig({ tsr: { appDirectory: "src" }, // Base configuration (applied to both client and server) vite: { plugins: [tsConfigPaths({ projects: ["./tsconfig.json"] })], define: { // This helps modules determine the execution environment "process.browser": true, }, }, // Client-specific configuration routers: { client: { vite: { // Apply node polyfills only on the client side plugins: [nodePolyfills()], }, }, },});
This approach:
Avoids loading node polyfills on the server where they’re unnecessary and can cause conflicts
Sets process.browser to true which helps modules determine the execution environment
Ensures proper resolution of browser-specific code paths
In TanStack Start, Para SDK components must be loaded client-side only to avoid SSR conflicts. This is accomplished using a combination of React.lazy for dynamic loading and ClientOnly from TanStack Router to prevent server rendering.
1
Create Environment Constants
First, set up your API key and environment constants in a file like src/constants.ts:
Para offers two hosted environments: Environment.BETA (alias Environment.DEVELOPMENT) for testing, and
Environment.PROD (alias Environment.PRODUCTION) for live use. Select the environment that matches your current
development phase.
2
Create a Providers Component
Create a providers component that will wrap your application with both the QueryClientProvider and lazy-loaded ParaProvider:
import React from "react";import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import { ClientOnly } from "@tanstack/react-router";import { API_KEY, ENVIRONMENT } from "~/constants";const queryClient = new QueryClient();// Lazy load ParaProvider to avoid SSR issuesconst LazyParaProvider = React.lazy(() => import("@getpara/react-sdk").then((mod) => ({ default: mod.ParaProvider })));export default function Providers({ children }: React.PropsWithChildren) { return ( <ClientOnly fallback={null}> <QueryClientProvider client={queryClient}> <LazyParaProvider paraClientConfig={{ apiKey: API_KEY, env: ENVIRONMENT }}> {children} </LazyParaProvider> </QueryClientProvider> </ClientOnly> );}
The ClientOnly component ensures that the ParaProvider is only rendered on the client side, preventing hydration mismatches. The fallback prop determines what to show during server-side rendering.
3
Wrap Your App with Providers
Now, wrap your root component with the Providers component:
Beta Testing Credentials In the BETA Environment, you can use any email ending in @test.getpara.com (like
dev@test.getpara.com) or US phone numbers (+1) in the format (area code)-555-xxxx (like (425)-555-1234). Any OTP
code will work for verification with these test credentials. These credentials are for beta testing only. You can
delete test users anytime in the beta developer console to free up user slots.
The Para SDK uses styled-components internally which can cause issues during server-side rendering. By using React.lazy and ClientOnly, we ensure Para components are only evaluated in the browser environment where styled-components works correctly.