React Examples ​
Complete examples for using Flowfull Clients with React.
Basic Setup ​
App Setup with Provider ​
typescript
// App.tsx
import { PubflowProvider } from '@pubflow/react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './pages/Login';
import Dashboard from './pages/Dashboard';
import Users from './pages/Users';
function App() {
return (
<PubflowProvider
config={{
baseUrl: import.meta.env.VITE_BACKEND_URL,
bridgeBasePath: '/bridge',
authBasePath: '/auth'
}}
>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/users" element={<Users />} />
</Routes>
</BrowserRouter>
</PubflowProvider>
);
}
export default App;Authentication ​
Login Page ​
typescript
// pages/Login.tsx
import { useState } from 'react';
import { useAuth } from '@pubflow/react';
import { useNavigate } from 'react-router-dom';
function Login() {
const { login, isLoading, isAuthenticated } = useAuth();
const navigate = useNavigate();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
// Redirect if already authenticated
if (isAuthenticated) {
navigate('/dashboard');
return null;
}
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setError('');
try {
const result = await login({ email, password });
if (result.success) {
navigate('/dashboard');
} else {
setError(result.error || 'Login failed');
}
} catch (err) {
setError('An error occurred');
}
}
return (
<div className="login-page">
<h1>Login</h1>
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
required
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Logging in...' : 'Login'}
</button>
{error && <div className="error">{error}</div>}
</form>
</div>
);
}
export default Login;Protected Route ​
typescript
// components/ProtectedRoute.tsx
import { useAuth } from '@pubflow/react';
import { Navigate } from 'react-router-dom';
interface ProtectedRouteProps {
children: React.ReactNode;
allowedTypes?: string[];
}
function ProtectedRoute({ children, allowedTypes }: ProtectedRouteProps) {
const { user, isAuthenticated, isLoading } = useAuth();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
if (allowedTypes && user?.userType && !allowedTypes.includes(user.userType)) {
return <Navigate to="/access-denied" replace />;
}
return <>{children}</>;
}
export default ProtectedRoute;
// Usage in App.tsx
<Route
path="/dashboard"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
/>Data Fetching ​
User List with Pagination ​
typescript
// pages/Users.tsx
import { useState } from 'react';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';
interface User {
id: string;
name: string;
email: string;
userType: string;
}
function Users() {
const [page, setPage] = useState(1);
const userService = useBridgeApi<User>({ endpoint: 'users' });
const { data, meta, isLoading, error, refetch } = useBridgeQuery(
userService,
'list',
{ page, limit: 10, orderBy: 'name' }
);
if (isLoading) return <div>Loading users...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>Users</h1>
<button onClick={refetch}>Refresh</button>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Type</th>
</tr>
</thead>
<tbody>
{data?.map(user => (
<tr key={user.id}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.userType}</td>
</tr>
))}
</tbody>
</table>
<div className="pagination">
<button
onClick={() => setPage(p => p - 1)}
disabled={page === 1}
>
Previous
</button>
<span>Page {page} of {Math.ceil((meta?.total || 0) / 10)}</span>
<button
onClick={() => setPage(p => p + 1)}
disabled={!meta?.hasMore}
>
Next
</button>
</div>
</div>
);
}
export default Users;Next Steps ​
- React Native Examples - Mobile examples
- Next.js Examples - SSR examples
- Real-World Apps - Complete applications