State & Context
Global State Management
Blogify manages authentication and user sessions through a centralized React Context provider. This ensures that user data is consistent across the application and that protected routes remain secure during navigation.
UserContext Provider
The UserContext serves as the primary source of truth for the current visitor's authentication status. It wraps the application to provide high-level state without the need for prop-drilling.
Provided State Properties:
| Property | Type | Description |
| :--- | :--- | :--- |
| user | User \| null | The current authenticated user object. Contains id, name, email, and profile_picture_url. |
| loading | boolean | Indicates if the application is currently fetching the session from Supabase. |
The useUser Hook
To consume the authentication state in any functional component, use the useUser custom hook.
import { useUser } from '@/context/UserContext';
function ProfileButton() {
const { user, loading } = useUser();
if (loading) return <div>Loading...</div>;
if (!user) {
return <button>Sign In</button>;
}
return <div>Welcome, {user.name}</div>;
}
Route Protection
Authentication state is enforced at the component level using the RequireAuth wrapper. This component observes the UserContext and redirects unauthenticated users to the login page while preserving their intended destination.
Usage in Pages:
import { RequireAuth } from '@/components';
export default function CreatePostPage() {
return (
<RequireAuth>
<div className="editor-container">
{/* Only authenticated users see this */}
<h1>Create a New Post</h1>
</div>
</RequireAuth>
);
}
Authentication Workflow & Persistence
Blogify uses Supabase Auth as the underlying engine. The state synchronization follows this lifecycle:
- Initialization: On application load,
UserContextchecks for an existing session in local storage via the Supabase client. - State Updates: The context listens to auth state changes (SIGN_IN, SIGN_OUT). When a user logs in via
signInWithPassword, the context updates theuserobject automatically. - API Integration: The
lib/api.tsmodule uses these sessions to include the necessary JWTs for backend requests. For example,createPostanduploadImageverify the active session before execution. - Data Persistence: User profiles are stored in a
userstable in PostgreSQL, linked by the Supabaseuid.
Type Definitions
The following interfaces define the structure of the user state:
export interface User {
id: string;
name: string;
email: string;
profile_picture_url?: string;
created_at: string;
}
export interface LoginResponse {
id: string;
name: string;
email: string;
access_token?: string;
refresh_token?: string;
}