Welcome, {user.displayName || "User"}
AuthenticationAuthorizationNextJSUser ManagementReact
Description
Stack Auth is the authentication service of choice for creating and managing user authentication and authorization.
Globs
*.tsx, *.ts
---
description: Stack Auth is the authentication service of choice for creating and managing user authentication and authorization.
globs: *.tsx, *.ts
---
# Stack Auth Guidelines
## Setup Guidelines
- Run the installation wizard with:
`npx @stackframe/init-stack@latest`
- Update your API keys in your `.env.local` file:
- `NEXT_PUBLIC_STACK_PROJECT_ID`
- `NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY`
- `STACK_SECRET_SERVER_KEY`
- Key files created/updated include:
- `app/handler/[...stack]/page.tsx` (default auth pages)
- `app/layout.tsx` (wrapped with StackProvider and StackTheme)
- `app/loading.tsx` (provides a Suspense fallback)
- `stack.ts` (initializes your Stack server app)
## Components Guidelines
- Use pre-built components from `@stackframe/stack` like `<UserButton />`, `<SignIn />`, and `<SignUp />` to quickly set up auth UI.
- You can also compose smaller pieces like `<OAuthButtonGroup />`, `<MagicLinkSignIn />`, and `<CredentialSignIn />` for custom flows.
- Example:
```tsx
import { SignIn } from '@stackframe/stack';
export default function Page() {
return <SignIn />;
}
```
## User Management Guidelines
- In Client Components, use the `useUser()` hook to retrieve the current user (it returns `null` when not signed in).
- Update user details using `user.update({...})` and sign out via `user.signOut()`.
- For pages that require a user, call `useUser({ or: "redirect" })` so unauthorized visitors are automatically redirected.
## Client Component Guidelines
- Client Components rely on hooks like `useUser()` and `useStackApp()`.
- Example:
```tsx
"use client";
import { useUser } from "@stackframe/stack";
export function MyComponent() {
const user = useUser();
return <div>{user ? `Hello, ${user.displayName}` : "Not logged in"}</div>;
}
```
## Server Component Guidelines
- For Server Components, use `stackServerApp.getUser()` from your `stack.ts` file.
- Example:
```tsx
import { stackServerApp } from "@/stack";
export default async function ServerComponent() {
const user = await stackServerApp.getUser();
return <div>{user ? `Hello, ${user.displayName}` : "Not logged in"}</div>;
}
```
## Page Protection Guidelines
- Protect pages by:
- Using `useUser({ or: "redirect" })` in Client Components.
- Using `await stackServerApp.getUser({ or: "redirect" })` in Server Components.
- Implementing middleware that checks for a user and redirects to `/handler/sign-in` if not found.
- Example middleware:
```tsx
export async function middleware(request: NextRequest) {
const user = await stackServerApp.getUser();
if (!user) {
return NextResponse.redirect(new URL('/handler/sign-in', request.url));
}
return NextResponse.next();
}
export const config = { matcher: '/protected/:path*' };
```
## Stack App Object Guidelines
- The StackApp object provides core functionality:
- Use `useStackApp()` in Client Components (StackClientApp) which requires a publishable client key.
- Use `stackServerApp` in Server Components (StackServerApp) which needs your secret server key.
- Methods come in two flavors: promise-based (`getXyz`) and hook-based (`useXyz`), so choose based on your component type.
## SDK Reference
Below are some of the types available in Stack Auth:
```tsx
type StackClientApp = {
new(options): StackClientApp;
getUser([options]): Promise;
useUser([options]): User;
getProject(): Promise;
useProject(): Project;
signInWithOAuth(provider): void;
signInWithCredential([options]): Promise;
signUpWithCredential([options]): Promise;
sendForgotPasswordEmail(email): Promise;
sendMagicLinkEmail(email): Promise;
};
type StackServerApp =
& StackClientApp
& {
new(options): StackServerApp;
getUser([id][, options]): Promise;
useUser([id][, options]): ServerUser;
listUsers([options]): Promise;
useUsers([options]): ServerUser[];
createUser([options]): Promise;
getTeam(id): Promise;
useTeam(id): ServerTeam;
listTeams(): Promise;
useTeams(): ServerTeam[];
createTeam([options]): Promise;
}
type CurrentUser = {
id: string;
displayName: string | null;
primaryEmail: string | null;
primaryEmailVerified: boolean;
profileImageUrl: string | null;
signedUpAt: Date;
hasPassword: boolean;
clientMetadata: Json;
clientReadOnlyMetadata: Json;
selectedTeam: Team | null;
update(data): Promise;
updatePassword(data): Promise;
getAuthHeaders(): Promise<Record>;
getAuthJson(): Promise;
signOut([options]): Promise;
delete(): Promise;
getTeam(id): Promise;
useTeam(id): Team | null;
listTeams(): Promise;
useTeams(): Team[];
setSelectedTeam(team): Promise;
createTeam(data): Promise;
leaveTeam(team): Promise;
getTeamProfile(team): Promise;
useTeamProfile(team): EditableTeamMemberProfile;
hasPermission(scope, permissionId): Promise;
getPermission(scope, permissionId[, options]): Promise;
usePermission(scope, permissionId[, options]): TeamPermission | null;
listPermissions(scope[, options]): Promise;
usePermissions(scope[, options]): TeamPermission[];
listContactChannels(): Promise;
useContactChannels(): ContactChannel[];
};
```
## Examples
### Example: custom-profile-page
#### Task
Create a custom profile page that:
- Displays the user's avatar, display name, and email.
- Provides options to sign out.
- Uses Stack Auth components and hooks.
#### Response
##### File: app/profile/page.tsx
###### Code
```tsx
'use client';
import { useUser, useStackApp, UserButton } from '@stackframe/stack';
export default function ProfilePage() {
const user = useUser({ or: "redirect" });
const app = useStackApp();
return (
Welcome, {user.displayName || "User"}
Email: {user.primaryEmail}
<button onClick={() => user.signOut()}>Sign Out
);
}
```