--- title: "StackApp" description: "Reference documentation for StackClientApp and StackServerApp objects." sidebarTitle: "StackApp" mode: "wide" --- import { AsideSection, ContentSection, MethodAside, MethodContent, MethodLayout, MethodReturns, } from "/snippets/sdk-type-components.jsx"; This is a detailed reference for the `StackApp` object. If you're looking for a more high-level overview, please read the [respective page in the Concepts section](/guides/going-further/stack-app). ## Overview - [StackClientApp](#stackclientapp) - Client-level permissions for frontend code - [StackServerApp](#stackserverapp) - Server-level permissions with full access --- # StackClientApp A `StackApp` with client-level permissions. It contains most of the useful methods and hooks for your client-side code. Most commonly you get an instance of `StackClientApp` by calling [`useStackApp()`](/sdk/hooks/use-stack-app) in a Client Component. ## Table of Contents ```typescript 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<...>; }; ``` ## Constructor Creates a new `StackClientApp` instance. Because each app creates a new connection to Stack Auth's backend, you should re-use existing instances wherever possible. This object is not usually constructed directly. More commonly, you would construct a [`StackServerApp`](#stackserverapp) instead, pass it into your app setup (see the [setup guide](/guides/getting-started/setup)), and then use the `useStackApp()` hook to obtain a `StackClientApp`. The [setup wizard](/guides/getting-started/setup) does these steps for you, so you don't need to worry about it unless you are manually setting up Stack Auth. If you're building a client-only app and don't have a `SECRET_SERVER_KEY`, you can construct a `StackClientApp` directly. Token storage configuration. Base URL for the Stack Auth API. Project ID. Defaults to the `NEXT_PUBLIC_STACK_PROJECT_ID` environment variable. Publishable client key. Defaults to the `NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY` environment variable. Redirect URL configuration. Disable automatic prefetching. ```typescript declare class StackClientApp { constructor(options: { tokenStore: "nextjs-cookie" | "cookie" | { accessToken: string; refreshToken: string; } | Request; baseUrl?: string; projectId?: string; publishableClientKey?: string; urls?: object; noAutomaticPrefetch?: boolean; }); } ``` ```typescript const stackClientApp = new StackClientApp({ tokenStore: "nextjs-cookie", baseUrl: "https://api.stack-auth.com", projectId: "123", publishableClientKey: "123", urls: { home: "/", }, }); ``` ```typescript "use client"; function MyReactComponent() { const stackClientApp = useStackApp(); } ``` ## User Management ### `stackClientApp.getUser([options])` Gets the current user. What to do if the user is not found. ```typescript declare function getUser(options?: { or?: "return-null" | "redirect" | "throw"; }): Promise; ``` ```typescript const userOrNull = await stackClientApp.getUser(); console.log(userOrNull); const user = await stackClientApp.getUser({ or: "redirect" }); console.log(user); ``` ### `stackClientApp.useUser([options])` React hook version of `getUser()`. Equivalent to the [`useUser()`](/sdk/hooks/use-user) standalone hook, which is an alias for `useStackApp().useUser()`. What to do if the user is not found. ```typescript declare function useUser(options?: { or?: "return-null" | "redirect" | "throw"; }): CurrentUser | null; ``` ```jsx "use client"; function MyReactComponent() { const user = useUser(); return user ?
Hello, {user.name}
:
Not signed in
; } ``` ```tsx "use client"; function MyProtectedComponent() { useUser({ or: "redirect" }); return
You can only see this if you are authenticated
; } ```
### `stackClientApp.getProject()` Gets the current project. ```typescript declare function getProject(): Promise; ``` ```typescript const project = await stackClientApp.getProject(); ``` ### `stackClientApp.useProject()` React hook version of `getProject()`. ```typescript declare function useProject(): Project; ``` ```typescript function MyReactComponent() { const project = useProject(); } ``` ## Authentication ### `stackClientApp.signInWithOAuth(provider)` Initiates the OAuth sign-in process with the specified provider. The OAuth provider type. ```typescript declare function signInWithOAuth(provider: string): Promise; ``` ```typescript await stackClientApp.signInWithOAuth("google"); ``` ### `stackClientApp.signInWithCredential([options])` Sign in using email and password credentials. User's email. User's password. Whether to skip redirect after sign-in. ```typescript declare function signInWithCredential(options?: { email?: string; password?: string; noRedirect?: boolean; }): Promise>; ``` ```typescript const result = await stackClientApp.signInWithCredential({ email: "test@example.com", password: "password", }); if (result.status === "error") { console.error("Sign in failed", result.error.message); } ``` ### `stackClientApp.signUpWithCredential([options])` Sign up using email and password credentials. User's email. User's password. Whether to skip redirect after sign-up. ```typescript declare function signUpWithCredential(options?: { email?: string; password?: string; noRedirect?: boolean; }): Promise>; ``` ```typescript const result = await stackClientApp.signUpWithCredential({ email: "test@example.com", password: "password", }); if (result.status === "error") { console.error("Sign up failed", result.error.message); } ``` ### `stackClientApp.sendForgotPasswordEmail(email)` Send a forgot-password email to an email address. The email to send the forgot-password email to. ```typescript declare function sendForgotPasswordEmail( email: string, ): Promise>; ``` ```typescript const result = await stackClientApp.sendForgotPasswordEmail("test@example.com"); if (result.status === "success") { console.log("Forgot password email sent"); } else { console.error("Failed to send forgot password email", result.error.message); } ``` ### `stackClientApp.sendMagicLinkEmail(email)` Send a magic-link or OTP sign-in email to an email address. The email to send the magic link to. ```typescript declare function sendMagicLinkEmail( email: string, ): Promise>; ``` ```typescript const result = await stackClientApp.sendMagicLinkEmail("test@example.com"); ``` --- # StackServerApp Like `StackClientApp`, but with [server permissions](/guides/going-further/stack-app#client-vs-server). Has full read and write access to all users. Since this functionality should only be available in environments you trust (ie. your own server), it requires a `SECRET_SERVER_KEY`. In some cases, you may want to use a `StackServerApp` on the client; an example for this is an internal dashboard that only your own employees have access to. We generally recommend against doing this unless you are aware of and protected against the (potentially severe) security implications of exposing `SECRET_SERVER_KEY` on the client. ## Table of Contents ```typescript type StackServerApp = // Inherits all functionality from StackClientApp & StackClientApp & { new(options): StackServerApp; getUser([id][, options]): Promise; useUser([id][, options]): ServerUser; listUsers([options]): Promise; useUsers([options]): ServerUser[]; createUser([options]): Promise; sendEmail(options): Promise>; getTeam(id): Promise; useTeam(id): ServerTeam; listTeams([options]): Promise; useTeams([options]): ServerTeam[]; listTeamsPaginated([options]): Promise<{ items: ServerTeam[]; nextCursor: string | null }>; useTeamsPaginated([options]): { items: ServerTeam[]; nextCursor: string | null }; createTeam([options]): Promise; } ``` ## Constructor Creates a new `StackServerApp` instance. Token storage configuration. Base URL for the Stack Auth API. Project ID. Publishable client key. Secret server key. Defaults to the `SECRET_SERVER_KEY` environment variable. Redirect URL configuration. Disable automatic prefetching. ```typescript declare class StackServerApp { constructor(options: { tokenStore: "nextjs-cookie" | "cookie" | { accessToken: string; refreshToken: string; } | Request; baseUrl?: string; projectId?: string; publishableClientKey?: string; secretServerKey?: string; urls?: object; noAutomaticPrefetch?: boolean; }); } ``` ```typescript const stackServerApp = new StackServerApp({ tokenStore: "nextjs-cookie", urls: { signIn: "/my-custom-sign-in-page", }, }); ``` ## User Operations ### `stackServerApp.getUser([id], [options])` Enhanced version of `StackClientApp.getUser()` with server permissions. **Overloads:** 1. `getUser(id: string): Promise` to get a user by ID. 2. `getUser(options?: { or?: "return-null" | "redirect" | "throw" }): Promise` to get the current user. ```typescript declare function getUser(id: string): Promise; declare function getUser(options?: { or?: "return-null" | "redirect" | "throw"; }): Promise; ``` ```typescript const currentUser = await stackServerApp.getUser(); console.log(currentUser); const serverUser = await stackServerApp.getUser( "12345678-1234-1234-1234-123456789abc", ); console.log(serverUser); ``` ### `stackServerApp.useUser([id], [options])` Functionally equivalent to [`getUser()`](#stackserverappgetuserid-options), but as a React hook. This should be used on the server-side only. ```typescript declare function useUser( idOrOptions?: string | { or?: "return-null" | "redirect" | "throw" }, options?: { or?: "return-null" | "redirect" | "throw" }, ): ServerUser | CurrentServerUser | null; ``` ### `stackServerApp.listUsers([options])` Lists all users on the project. The cursor to start the result set from. Maximum number of items to return. If omitted, all users are returned. The field to sort results by. Whether to sort in descending order. Defaults to `false`. Free-text search on the user's display name and emails. ```typescript declare function listUsers(options?: { cursor?: string; limit?: number; orderBy?: "signedUpAt"; desc?: boolean; query?: string; }): Promise; ``` ```typescript const users = await stackServerApp.listUsers({ limit: 20 }); console.log(users); if (users.nextCursor) { const nextPageUsers = await stackServerApp.listUsers({ cursor: users.nextCursor, limit: 20, }); console.log(nextPageUsers); } ``` ### `stackServerApp.useUsers([options])` Functionally equivalent to [`listUsers()`](#stackserverapplistusersoptions), but as a React hook. This should be used on the server-side only. ```typescript declare function useUsers(options?: { cursor?: string; limit?: number; orderBy?: "signedUpAt"; desc?: boolean; query?: string; }): ServerUser[]; ``` ### `stackServerApp.createUser([options])` Creates a new user from the server. User's primary email. Whether the email is verified. Whether email auth is enabled. User's password. Enable OTP or magic-link auth. User's display name. ```typescript declare function createUser(options?: { primaryEmail?: string; primaryEmailVerified?: boolean; primaryEmailAuthEnabled?: boolean; password?: string; otpAuthEnabled?: boolean; displayName?: string; }): Promise; ``` ```typescript const passwordUser = await stackServerApp.createUser({ primaryEmail: "test@example.com", primaryEmailAuthEnabled: true, password: "password123", }); const magicLinkUser = await stackServerApp.createUser({ primaryEmail: "test@example.com", primaryEmailVerified: true, primaryEmailAuthEnabled: true, otpAuthEnabled: true, }); ``` ### `stackServerApp.sendEmail(options)` Send custom emails to users. You can send either custom HTML emails or use predefined templates with variables. Email configuration and content. The method returns a `Result` that can include `RequiresCustomEmailServer`, `SchemaError`, and `UserIdDoesNotExist`. ```typescript declare function sendEmail( options: SendEmailOptions, ): Promise>; ``` ```typescript const htmlResult = await stackServerApp.sendEmail({ userIds: ["user-1", "user-2"], subject: "Welcome to our platform!", html: "

Welcome!

Thanks for joining us.

", }); if (htmlResult.status === "error") { console.error("Failed to send email:", htmlResult.error); } ``` ```typescript const templateResult = await stackServerApp.sendEmail({ userIds: ["user-1"], templateId: "welcome-template", variables: { userName: "John Doe", activationUrl: "https://app.com/activate/token123", }, }); ```
## Team Management ### `stackServerApp.getTeam(id)` Get a team by its ID. Team ID. ```typescript declare function getTeam(id: string): Promise; ``` ```typescript const team = await stackServerApp.getTeam("team_id_123"); ``` ### `stackServerApp.useTeam(id)` Functionally equivalent to [`getTeam(id)`](#stackserverappgetteamid), but as a React hook. This should be used on the server-side only. ```typescript declare function useTeam(id: string): ServerTeam; ``` ### `stackServerApp.listTeams([options])` Lists all teams on the current project. For cursor-based pagination over teams, see [`listTeamsPaginated`](#stackserverapplistteamspaginatedoptions). The field to sort results by. Whether to sort in descending order. Defaults to `false`. ```typescript declare function listTeams(options?: { orderBy?: "createdAt"; desc?: boolean; }): Promise; ``` ```typescript const teams = await stackServerApp.listTeams(); console.log(teams); ``` ### `stackServerApp.useTeams([options])` Functionally equivalent to [`listTeams()`](#stackserverapplistteamsoptions), but as a React hook. This should be used on the server-side only. ```typescript declare function useTeams(options?: { orderBy?: "createdAt"; desc?: boolean; }): ServerTeam[]; ``` ### `stackServerApp.listTeamsPaginated([options])` Lists teams on the current project with cursor-based pagination, optional filtering, and ordering. The returned array carries an extra `nextCursor` property; pass it back as `cursor` to load the next page. Cursor returned as `nextCursor` from a previous response. Maximum number of items to return. If omitted, all matching teams are returned. The field to sort results by. Whether to sort in descending order. Defaults to `false`. Free-text search on the team's display name (and team ID if the query is a UUID). ```typescript declare function listTeamsPaginated(options?: { cursor?: string; limit?: number; orderBy?: "createdAt"; desc?: boolean; query?: string; }): Promise<{ items: ServerTeam[]; nextCursor: string | null }>; ``` ```typescript const teams = await stackServerApp.listTeamsPaginated({ limit: 20 }); console.log(teams); if (teams.nextCursor) { const nextPageTeams = await stackServerApp.listTeamsPaginated({ cursor: teams.nextCursor, limit: 20, }); console.log(nextPageTeams); } ``` ### `stackServerApp.useTeamsPaginated([options])` Functionally equivalent to [`listTeamsPaginated()`](#stackserverapplistteamspaginatedoptions), but as a React hook. This should be used on the server-side only. ```typescript declare function useTeamsPaginated(options?: { cursor?: string; limit?: number; orderBy?: "createdAt"; desc?: boolean; query?: string; }): { items: ServerTeam[]; nextCursor: string | null }; ``` ### `stackServerApp.createTeam([options])` Creates a team without adding a user to it. Team display name. Team profile image URL. ```typescript declare function createTeam(options?: { displayName?: string; profileImageUrl?: string | null; }): Promise; ``` ```typescript const team = await stackServerApp.createTeam({ displayName: "New Team", profileImageUrl: "https://example.com/profile.jpg", }); ```