Profile component is a ready-to-use, customizable profile page that includes:
Profile component is a ready-to-use, customizable profile page that includes:
interface ProfileProps {
branding?: Branding;
errorElement?: ReactNode;
fallbackElement?: ReactNode;
}
interface Branding {
theme: 'light' | 'dark';
logoUrl: string | null;
primaryColor: string;
backgroundImage?: string | null;
}interface Branding {
theme: 'light' | 'dark'; // Color theme
logoUrl: string | null; // Company logo URL
primaryColor: string; // Brand color (hex)
backgroundImage?: string | null; // Optional background
}// app/profile/page.tsx
import Profile from 'authsafe-nextjs/client';
import { getAuth, initAuthSafe } from 'authsafe-nextjs/server';
initAuthSafe({
clientId: process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID!,
domain: process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN!,
});
export default async function ProfilePage() {
const session = await getAuth();
// Fetch branding server-side
const response = await fetch(
`${process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN}/auth/branding?client_id=${process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID}`,
{ cache: 'no-store' },
);
const branding = response.ok ? await response.json() : undefined;
return <Profile branding={branding} />;
}// pages/profile.tsx
import Profile, { Branding } from 'authsafe-nextjs/client';
import { GetServerSideProps } from 'next';
interface ProfilePageProps {
branding?: Branding;
}
export default function ProfilePage({ branding }: ProfilePageProps) {
return <Profile branding={branding} />;
}
export const getServerSideProps: GetServerSideProps = async () => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN}/auth/branding?client_id=${process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID}`,
);
const branding = await response.json();
return { props: { branding } };
} catch (error) {
return { props: {} };
}
};import Profile from 'authsafe-nextjs/client';
export default function ProfilePage() {
return <Profile />;
}import Profile from 'authsafe-nextjs/client';
import Link from 'next/link';
export default function ProfilePage() {
return (
<Profile
errorElement={
<div className="flex flex-col items-center justify-center min-h-screen">
<h1 className="text-2xl font-bold mb-4">Authentication Required</h1>
<p className="text-gray-600 mb-6">
Please sign in to view your profile
</p>
<Link
href="/api/auth/signin"
className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
>
Sign In
</Link>
</div>
}
/>
);
}import Profile from 'authsafe-nextjs/client';
export default function ProfilePage() {
return (
<Profile
fallbackElement={
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<div className="inline-block w-16 h-16 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mb-4" />
<p className="text-gray-600">Loading your profile...</p>
</div>
</div>
}
/>
);
}GET /auth/branding?client_id={clientId}{
"theme": "dark",
"logoUrl": "https://cdn.example.com/logo.png",
"primaryColor": "#3B82F6",
"backgroundImage": null
}const response = await fetch(
`${process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN}/auth/branding?client_id=${process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID}`,
{ cache: 'no-store' },
);
const branding = await response.json();branding.theme prop:
<Profile
branding={{
theme: 'dark',
primaryColor: '#8B5CF6',
logoUrl: null,
}}
/>// app/profile/page.tsx
import Profile from 'authsafe-nextjs/client';
import { getAuth, initAuthSafe } from 'authsafe-nextjs/server';
import { redirect } from 'next/navigation';
initAuthSafe({
clientId: process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID!,
domain: process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN!,
});
async function getBranding() {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_AUTHSAFE_DOMAIN}/auth/branding?client_id=${process.env.NEXT_PUBLIC_AUTHSAFE_CLIENT_ID}`,
{ cache: 'no-store' },
);
if (!response.ok) return undefined;
return await response.json();
} catch {
return undefined;
}
}
export default async function ProfilePage() {
const session = await getAuth();
if (!session) {
redirect('/api/auth/signin?returnTo=/profile');
}
const branding = await getBranding();
return (
<div className="min-h-screen bg-gray-50">
<nav className="bg-white shadow-sm border-b">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex items-center">
<h1 className="text-xl font-bold">My App</h1>
</div>
</div>
</div>
</nav>
<main>
<Profile branding={branding} />
</main>
</div>
);
}