title: "React / Next.js Quickstart" description: "Get started with TitaniumVault authentication in your React or Next.js application in under 10 minutes." order: 1
React / Next.js Quickstart
This guide will walk you through adding TitaniumVault authentication to your React or Next.js application.
Prerequisites
- Node.js 18+ installed
- A TitaniumVault account and application configured
- React 18+ or Next.js 13+ project
Installation
Install the TitaniumVault React SDK:
npm install @titaniumvault/react
Configuration
1. Set up environment variables
Create a .env.local file in your project root:
NEXT_PUBLIC_TV_DOMAIN=your-org.titanium-vault.com
NEXT_PUBLIC_TV_CLIENT_ID=your-client-id
NEXT_PUBLIC_TV_REDIRECT_URI=http://localhost:3000/callback
2. Wrap your app with the provider
For Next.js App Router, update your app/layout.tsx:
import { TitaniumVaultProvider } from '@titaniumvault/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<TitaniumVaultProvider
domain={process.env.NEXT_PUBLIC_TV_DOMAIN!}
clientId={process.env.NEXT_PUBLIC_TV_CLIENT_ID!}
redirectUri={process.env.NEXT_PUBLIC_TV_REDIRECT_URI!}
>
{children}
</TitaniumVaultProvider>
</body>
</html>
);
}
For React (Vite or CRA), update your main.tsx:
import { TitaniumVaultProvider } from '@titaniumvault/react';
ReactDOM.createRoot(document.getElementById('root')!).render(
<TitaniumVaultProvider
domain={import.meta.env.VITE_TV_DOMAIN}
clientId={import.meta.env.VITE_TV_CLIENT_ID}
redirectUri={import.meta.env.VITE_TV_REDIRECT_URI}
>
<App />
</TitaniumVaultProvider>
);
Add Login/Logout
Create a login button component:
'use client';
import { useAuth } from '@titaniumvault/react';
export function LoginButton() {
const { isAuthenticated, isLoading, loginWithRedirect, logout, user } = useAuth();
if (isLoading) {
return <button disabled>Loading...</button>;
}
if (isAuthenticated) {
return (
<div>
<span>Welcome, {user?.name}</span>
<button onClick={() => logout({ returnTo: window.location.origin })}>
Logout
</button>
</div>
);
}
return (
<button onClick={() => loginWithRedirect()}>
Login
</button>
);
}
Handle the Callback
For Next.js App Router, create app/callback/page.tsx:
'use client';
import { useEffect } from 'react';
import { useAuth } from '@titaniumvault/react';
import { useRouter } from 'next/navigation';
export default function CallbackPage() {
const { handleRedirectCallback, isLoading, error } = useAuth();
const router = useRouter();
useEffect(() => {
const handleCallback = async () => {
try {
await handleRedirectCallback();
router.push('/dashboard');
} catch (err) {
console.error('Callback error:', err);
}
};
handleCallback();
}, [handleRedirectCallback, router]);
if (error) {
return <div>Error: {error.message}</div>;
}
return <div>Processing login...</div>;
}
Protect Routes
Create a protected route wrapper:
'use client';
import { useAuth } from '@titaniumvault/react';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
export function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, isLoading, loginWithRedirect } = useAuth();
const router = useRouter();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
loginWithRedirect();
}
}, [isLoading, isAuthenticated, loginWithRedirect]);
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return null;
}
return <>{children}</>;
}
Use it in your protected pages:
import { ProtectedRoute } from '@/components/ProtectedRoute';
export default function DashboardPage() {
return (
<ProtectedRoute>
<h1>Dashboard</h1>
{/* Protected content */}
</ProtectedRoute>
);
}
Calling APIs with Access Tokens
Get an access token for API calls:
'use client';
import { useAuth } from '@titaniumvault/react';
export function ApiComponent() {
const { getAccessToken } = useAuth();
const callApi = async () => {
const token = await getAccessToken();
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
console.log(data);
};
return <button onClick={callApi}>Call API</button>;
}
Next Steps
- Configure MFA for enhanced security
- Set up SAML SSO for enterprise connections
- Implement role-based access with scopes
Troubleshooting
"Redirect URI mismatch" error
Ensure your redirect URI in the TitaniumVault dashboard exactly matches NEXT_PUBLIC_TV_REDIRECT_URI, including the protocol and trailing slashes.
Token not refreshing
The SDK automatically handles token refresh. If you're experiencing issues, check that your refresh token settings are configured correctly in the TitaniumVault dashboard.
CORS errors
If making API calls from the browser, ensure your API is configured to accept requests from your application's origin.