stack/docs/templates/getting-started/setup.mdx
BilalG1 23b9eb831a
Init script agent mode and react option (#897)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->

<!-- RECURSEML_SUMMARY:START -->
## High-level PR Summary
This PR adds support for non-interactive initialization in the Stack
Auth initialization script. It introduces a `STACK_DISABLE_INTERACTIVE`
environment variable flag and makes appropriate changes throughout the
codebase to handle non-interactive flows. The changes include improving
type definitions, adding automatic determination of project type (JS vs
Next.js) and configuration (client vs server) when running in
non-interactive mode, and better error handling for cases where required
information is missing. These changes enable CI/CD scenarios and
automation for Stack Auth integration.

⏱️ Estimated Review Time: 0h 20m

<details>
<summary>💡 Review Order Suggestion</summary>

| Order | File Path |
|-------|-----------|
| 1 | `packages/init-stack/src/index.ts` |
</details>



<!-- RECURSEML_SUMMARY:END -->

<!-- RECURSEML_ANALYSIS:START -->
## Review by RecurseML

_🔍 Review performed on
[bba4db2..974e4fd](bba4db2ab0...974e4fda92)_

 No bugs found, your code is sparkling clean

<details>
<summary> Files analyzed, no issues (1)</summary>

  • `packages/init-stack/src/index.ts`
</details>

[![Need help? Join our
Discord](https://img.shields.io/badge/Need%20help%3F%20Join%20our%20Discord-5865F2?style=plastic&logo=discord&logoColor=white)](https://discord.gg/n3SsVDAW6U)
<!-- RECURSEML_ANALYSIS:END -->
<!-- ELLIPSIS_HIDDEN -->


----

> [!IMPORTANT]
> Adds non-interactive and React project initialization options to Stack
Auth setup script, updates tests and documentation.
> 
>   - **Behavior**:
> - Adds `--agent-mode` option in `index.ts` for non-interactive CLI
runs.
> - Adds `--react` option in `index.ts` for React project
initialization.
> - Updates `writeReactClientFile()` in `index.ts` to handle
React-specific setup.
>   - **Scripts**:
> - Updates `package.json` to include `test-run-react` and
`test-run-react:manual` scripts.
> - Modifies existing test scripts in `package.json` to use
`--agent-mode`.
>   - **Documentation**:
> - Updates `setup.mdx` to include React setup instructions and
wizard/manual tabs.
>   - **Misc**:
>     - Removes `STACK_DISABLE_INTERACTIVE` checks in `index.ts`.
>     - Updates error handling and logging in `index.ts`.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for f63a2a57ef. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>

----


<!-- ELLIPSIS_HIDDEN -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- New Features
- First-class React project initialization (--react) with automatic
React client scaffolding.
- Added --agent-mode for fully non-interactive CLI runs and consistent
--no-browser behavior.
- Public env var for local React package override
(STACK_REACT_INSTALL_PACKAGE_NAME_OVERRIDE).

- Chores
- Standardized non-interactive flows across scripts (removed legacy
interactive gating).

- Tests
- Updated test scaffolding and run commands to use agent-mode and
browser-free execution.

- Documentation
- Converted setup docs to a wizard-style experience with consolidated
wizard/manual tabs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-09-15 18:47:05 -07:00

596 lines
22 KiB
Plaintext

---
title: Setup
---
{/* IF_PLATFORM: next */}
<Info>
Welcome to the Next.js SDK setup guide. If you're looking for guides for other frameworks, check out the [React SDK Setup](/docs/react/getting-started/setup), or the [JavaScript SDK Setup](/docs/js/getting-started/setup).
</Info>
## Setup
Before getting started, make sure you have a [Next.js project](https://nextjs.org/docs/getting-started/installation) using the app router, as Stack Auth does not support the pages router.
We recommend using our **setup wizard** for a seamless installation experience. The wizard automatically detects your project structure and walks you through the setup process. If you encounter any issues with the wizard, you can follow our manual installation steps instead.
<Tabs defaultValue="wizard">
<TabsList>
<TabsTrigger value="wizard">Setup wizard (recommended)</TabsTrigger>
<TabsTrigger value="manual">Manual installation</TabsTrigger>
</TabsList>
<TabsContent value="wizard">
<Steps>
<Step>
### Run installation wizard
</Step>
Run Stack's installation wizard with the following command:
```sh title="Terminal"
npx @stackframe/init-stack@latest
```
<Step>
### Update API keys
</Step>
Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its environment variables into the `.env.local` file of your Next.js project:
```sh title=".env.local"
NEXT_PUBLIC_STACK_PROJECT_ID=<your-project-id>
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>
```
<Step>
### Done!
</Step>
That's it! The following files should have been created or updated in your project:
- `app/handler/[...stack]/page.tsx`: This file contains the default pages for sign-in, sign-out, account settings, and more. If you prefer, later you will learn how to [use custom pages](../customization/custom-pages.mdx) instead.
- `app/layout.tsx`: The layout file was updated to wrap the entire body with `StackProvider` and `StackTheme`.
- `app/loading.tsx`: If not yet found, Stack automatically adds a Suspense boundary to your app. This is shown to the user while Stack's async hooks, like `useUser`, are loading.
- `stack/server.ts`: This file contains the `stackServerApp` which you can use to access Stack from Server Components, Server Actions, API routes, and middleware.
- `stack/client.ts`: This file contains the `stackClientApp` which you can use to access Stack from Client Components
</Steps>
</TabsContent>
<TabsContent value="manual">
<Info>
Note: The setup wizard also supports existing, complicated projects. Cases where manual installation is necessary are rare.
</Info>
If you are struggling with the setup wizard, please reach out to us on our [Discord](https://discord.stack-auth.com) first, where we'll be happy to help you.
<Steps>
<Step>
### Install npm package
</Step>
First, install Stack with npm, yarn, or pnpm:
```bash title="Terminal"
npm install @stackframe/stack
```
<Step>
### Create API keys
</Step>
If you haven't already, [register a new account on Stack](https://app.stack-auth.com/handler/sign-up). Create a project in the dashboard, create a new API key from the left sidebar, and copy the project ID, publishable client key, and secret server key into a new file called `.env.local` in the root of your Next.js project:
```sh title=".env.local"
NEXT_PUBLIC_STACK_PROJECT_ID=<your-project-id>
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>
```
<Step>
### Create `stack/server.ts` file
</Step>
Create a new file `stack/server.ts` in your root directory and fill it with the following:
```tsx title="stack/server.ts"
import "server-only";
import { StackServerApp } from "@stackframe/stack";
export const stackServerApp = new StackServerApp({
tokenStore: "nextjs-cookie", // storing auth tokens in cookies
});
```
This will read the environment variables automatically and create a server app that you can later use to access Stack from your Next.js server.
Check out the [`StackServerApp` documentation](../sdk/objects/stack-app.mdx) to learn more about its other options.
<Step>
### Create Stack handler
</Step>
Create a new file in `app/handler/[...stack]/page.tsx` and paste the following code:
```tsx title="app/handler/[...stack]/page.tsx"
import { StackHandler } from "@stackframe/stack";
import { stackServerApp } from "@/stack/server";
export default function Handler(props: unknown) {
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
}
```
This will create pages for sign-in, sign-up, password reset, and others. Additionally, it will be used as a callback URL for OAuth. You can [replace them with your own pages](../customization/custom-pages.mdx) later.
<Step>
### Add StackProvider to `layout.tsx`
</Step>
In your `app/layout.tsx`, wrap the entire body with a `StackProvider` and `StackTheme`. Afterwards, it should look like this:
```tsx title="app/layout.tsx"
import React from "react";
import { StackProvider, StackTheme } from "@stackframe/stack";
import { stackServerApp } from "@/stack/server";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<StackProvider app={stackServerApp}>
<StackTheme>
{children}
</StackTheme>
</StackProvider>
</body>
</html>
);
}
```
<Step>
### Add Suspense boundary
</Step>
By default, Stack uses [`Suspense`](https://react.dev/reference/react/Suspense) to handle loading states. To show a loading indicator while Stack is fetching user data, make sure there is a `loading.tsx` file in your `app` directory:
```tsx title="app/loading.tsx"
export default function Loading() {
// You can use any loading indicator here
return <>
Loading...
</>;
}
```
<Step>
### Done!
</Step>
</Steps>
</TabsContent>
</Tabs>
## Post-setup
That's it! Stack is now configured in your Next.js project. If you start your Next.js app with `npm run dev` and navigate to [http://localhost:3000/handler/signup](http://localhost:3000/handler/sign-up), you will see the sign-up page.
<div className="stack-white-image-showcase stack-350h">
<img src="/imgs/sign-in.png" alt="SignIn" />
</div>
After signing up/in, you will be redirected back to the home page. We will show you how to add user information to it in the next section. You can also check out the [http://localhost:3000/handler/account-settings](http://localhost:3000/handler/account-settings) page which looks like this:
![Stack account settings page](/imgs/account-settings.png)
## Next steps
Next up, we will show you how to [retrieve and update user information](./users.mdx), and how to [protect a page](./users.mdx#protecting-a-page) from unauthorized access.
{/* ELSE_IF_PLATFORM react */}
<Info>
Welcome to the React SDK setup guide! If you're looking for guides for other frameworks, check out the [Next.js SDK Setup](/docs/next/getting-started/setup), or the [JavaScript SDK Setup](/docs/js/getting-started/setup).
</Info>
Before getting started, make sure you have a [React project](https://react.dev/learn/creating-a-react-app) setup. We show an example here of a Vite React project.
We recommend using our **setup wizard** for a seamless installation experience. The wizard automatically detects your project structure and walks you through the setup process. If you encounter any issues with the wizard, you can follow our manual installation steps instead.
<Tabs defaultValue="wizard">
<TabsList>
<TabsTrigger value="wizard">Setup wizard (recommended)</TabsTrigger>
<TabsTrigger value="manual">Manual installation</TabsTrigger>
</TabsList>
<TabsContent value="wizard">
<Steps>
<Step>
### Run installation wizard
</Step>
Run Stack's installation wizard with the following command:
```sh title="Terminal"
npx @stackframe/init-stack@latest
```
<Step>
### Update API keys
</Step>
Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its values into the `stack/client.ts` file created by the wizard.
<Step>
### Wrap your app
</Step>
This example uses react-router, but all React apps should wrap the app with `StackProvider` and `StackTheme`.
```tsx title="App.tsx"
import { StackHandler, StackProvider, StackTheme } from "@stackframe/react";
import { Suspense } from "react";
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
import { stackClientApp } from "./stack/client";
function HandlerRoutes() {
const location = useLocation();
return (
<StackHandler app={stackClientApp} location={location.pathname} fullPage />
);
}
export default function App() {
return (
<Suspense fallback={null}>
<BrowserRouter>
<StackProvider app={stackClientApp}>
<StackTheme>
<Routes>
<Route path="/handler/*" element={<HandlerRoutes />} />
<Route path="/" element={<div>hello world</div>} />
</Routes>
</StackTheme>
</StackProvider>
</BrowserRouter>
</Suspense>
);
}
```
<Step>
### Done!
</Step>
That's it! Stack is now configured in your React project. If you start your app and navigate to [http://localhost:5173/handler/sign-up](http://localhost:5173/handler/sign-up), you will see the sign-up page.
<div className="stack-white-image-showcase stack-350h">
<img src="/imgs/sign-in.png" alt="SignIn" />
</div>
After signing up/in, you will be redirected back to the home page. You can also check out the [http://localhost:5173/handler/account-settings](http://localhost:5173/handler/account-settings) page.
</Steps>
</TabsContent>
<TabsContent value="manual">
<Steps>
<Step>
### Install npm package
</Step>
```bash title="Terminal"
npm install @stackframe/react
```
<Step>
### Create API keys
</Step>
If you haven't already, [register a new account on Stack](https://app.stack-auth.com/projects), create a project in the dashboard, create a new API key from the left sidebar, and copy the project ID and publishable client key. Store them based on your project setup (environment variables or directly in the client file during development).
<Step>
### Create `stack/client.ts` file
</Step>
Create a new file `stack/client.ts` in your root directory and fill it with the following Stack app initialization code:
```tsx title="stack/client.ts"
import { StackClientApp } from "@stackframe/react";
// If you use React Router, uncomment the next line and the redirectMethod below
// import { useNavigate } from "react-router-dom";
export const stackClientApp = new StackClientApp({
// You should store these in environment variables based on your project setup
projectId: "your-project-id",
publishableClientKey: "your-publishable-client-key",
tokenStore: "cookie",
// redirectMethod: { useNavigate }, // Optional: only if using react-router-dom
});
```
<Step>
### Update `App.tsx`
</Step>
If you're using React Router, update your `App.tsx` file to wrap the entire app with a `StackProvider` and `StackTheme` and add a `StackHandler` route to handle the authentication flow.
```tsx title="App.tsx"
import { StackHandler, StackProvider, StackTheme } from "@stackframe/react";
import { Suspense } from "react";
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
import { stackClientApp } from "./stack/client";
function HandlerRoutes() {
const location = useLocation();
return (
<StackHandler app={stackClientApp} location={location.pathname} fullPage />
);
}
export default function App() {
return (
<Suspense fallback={null}>
<BrowserRouter>
<StackProvider app={stackClientApp}>
<StackTheme>
<Routes>
<Route path="/handler/*" element={<HandlerRoutes />} />
<Route path="/" element={<div>hello world</div>} />
</Routes>
</StackTheme>
</StackProvider>
</BrowserRouter>
</Suspense>
);
}
```
<Step>
### Done!
</Step>
That's it! Stack is now configured in your React project. If you start your app and navigate to [http://localhost:5173/handler/sign-up](http://localhost:5173/handler/sign-up), you will see the sign-up page.
<div className="stack-white-image-showcase stack-350h">
<img src="/imgs/sign-in.png" alt="SignIn" />
</div>
After signing up/in, you will be redirected back to the home page. You can also check out the [http://localhost:5173/handler/account-settings](http://localhost:5173/handler/account-settings) page.
</Steps>
</TabsContent>
</Tabs>
{/* ELSE_IF_PLATFORM js */}
<Info>
Welcome to the JavaScript SDK setup guide. If you're looking for guides for other frameworks, check out the [React SDK Setup](/docs/react/getting-started/setup), or the [Next.js SDK Setup](/docs/next/getting-started/setup).
</Info>
Before getting started, make sure you have a JavaScript project set up (such as Node.js, Vite, or any other JavaScript framework).
We recommend using our **setup wizard** for a seamless installation experience. The wizard automatically detects your project structure and walks you through the setup process. If you encounter any issues with the wizard, you can follow our manual installation steps instead.
<Tabs defaultValue="wizard">
<TabsList>
<TabsTrigger value="wizard">Setup wizard (recommended)</TabsTrigger>
<TabsTrigger value="manual">Manual installation</TabsTrigger>
</TabsList>
<TabsContent value="wizard">
<Steps>
<Step>
### Run installation wizard
</Step>
Run Stack's installation wizard with the following command:
```sh title="Terminal"
npx @stackframe/init-stack@latest
```
<Step>
### Update API keys
</Step>
Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its values into the `stack/server.ts` or `stack/client.ts` file.
<Tabs defaultValue="server">
<TabsList>
<TabsTrigger value="server">Server</TabsTrigger>
<TabsTrigger value="client">Client</TabsTrigger>
</TabsList>
<TabsContent value="server">
```tsx title="stack/server.ts"
import { StackServerApp } from "@stackframe/js";
export const stackServerApp = new StackServerApp({
// You should store these in environment variables based on your project setup
projectId: "your-project-id",
publishableClientKey: "your-publishable-client-key",
secretServerKey: "your-secret-server-key",
tokenStore: "memory",
});
```
</TabsContent>
<TabsContent value="client">
```tsx title="stack/client.ts"
import { StackClientApp } from "@stackframe/js";
export const stackClientApp = new StackClientApp({
// You should store these in environment variables based on your project setup
projectId: "your-project-id",
publishableClientKey: "your-publishable-client-key",
tokenStore: "cookie",
});
```
</TabsContent>
</Tabs>
</Steps>
</TabsContent>
<TabsContent value="manual">
<Steps>
<Step>
### Install npm package
</Step>
```bash title="Terminal"
npm install @stackframe/js
```
<Step>
### Update API keys
</Step>
Then, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project with an API key, and copy its values into the `stack/server.ts` or `stack/client.ts` file.
<Step>
### Initialize the app
</Step>
<Tabs defaultValue="server">
<TabsList>
<TabsTrigger value="server">Server</TabsTrigger>
<TabsTrigger value="client">Client</TabsTrigger>
</TabsList>
<TabsContent value="server">
```typescript title="stack/server.ts"
import { StackServerApp } from "@stackframe/js";
const stackServerApp = new StackServerApp({
// You should store these in environment variables based on your project setup
projectId: "your-project-id-from-dashboard",
publishableClientKey: "your-publishable-client-key-from-dashboard",
secretServerKey: "your-secret-server-key-from-dashboard",
tokenStore: "memory",
});
```
</TabsContent>
<TabsContent value="client">
```tsx title="stack/client.ts"
import { StackClientApp } from "@stackframe/js";
const stackClientApp = new StackClientApp({
// You should store these in environment variables based on your project setup
projectId: "your-project-id",
publishableClientKey: "your-publishable-client-key",
tokenStore: "cookie",
});
```
</TabsContent>
</Tabs>
</Steps>
</TabsContent>
</Tabs>
## Example usage
<Tabs defaultValue="server">
<TabsList>
<TabsTrigger value="server">Server</TabsTrigger>
<TabsTrigger value="client">Client</TabsTrigger>
</TabsList>
<TabsContent value="server">
```typescript
import { stackServerApp } from "@/stack/server";
const user = await stackServerApp.getUser("user_id");
await user.update({
displayName: "New Display Name",
});
const team = await stackServerApp.createTeam({
name: "New Team",
});
await team.addUser(user.id);
```
</TabsContent>
<TabsContent value="client">
```typescript
import { stackClientApp } from "@/stack/client";
await stackClientApp.signInWithCredential({
email: "test@example.com",
password: "password123",
});
const user = await stackClientApp.getUser();
await user.update({
displayName: "New Display Name",
});
await user.signOut();
```
</TabsContent>
</Tabs>
## Next steps
Check out the [Users](./users.mdx) to learn how to retrieve and update user information, or [Example pages](./example-pages.mdx) to see how to build your sign-in/up pages.
{/* ELSE_IF_PLATFORM python */}
<Info>
Welcome to the Python setup guide. If you're looking for guides for other frameworks, check out the [Next.js SDK Setup](/next/getting-started/setup), [React SDK Setup](/react/getting-started/setup), or the [JavaScript SDK Setup](/js/getting-started/setup).
</Info>
Our recommended way to use Stack Auth with Python is with the [REST API](../rest-api/overview.mdx). It provides a fully documented way to interact with Stack Auth from any Python framework, including Flask, FastAPI, and Django.
For the purpose of this guide, we will use the `requests` library to make HTTP requests to the Stack Auth API. If you haven't already, you can install it in your environment with `pip install requests`.
<Steps>
### Create API keys
First, create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), and copy your project ID, publishable client key, and secret server key into a safe place (eg. environment variables).
From there, you can access them in your Python code. You can then read them like this:
```python
import os
stack_project_id = os.getenv("STACK_PROJECT_ID")
stack_publishable_client_key = os.getenv("STACK_PUBLISHABLE_CLIENT_KEY")
stack_secret_server_key = os.getenv("STACK_SECRET_SERVER_KEY")
```
### Make a request
Next, create a helper function to make requests to the Stack Auth API:
```python
import requests
def stack_auth_request(method, endpoint, **kwargs):
res = requests.request(
method,
f'https://api.stack-auth.com/{endpoint}',
headers={
'x-stack-access-type': 'server', # or 'client' if you're only accessing the client API
'x-stack-project-id': stack_project_id,
'x-stack-publishable-client-key': stack_publishable_client_key,
'x-stack-secret-server-key': stack_secret_server_key, # not necessary if access type is 'client'
**kwargs.pop('headers', {}),
},
**kwargs,
)
if res.status_code >= 400:
raise Exception(f"Stack Auth API request failed with {res.status_code}: {res.text}")
return res.json()
print(stack_auth_request('GET', '/api/v1/projects/current'))
```
### Retrieve the access tokens
If you're building a backend server, most likely you'll want to use the currently signed in user's access token. Most normally, you would send this with all your requests to the backend in an HTTP header.
In Stack Auth's JavaScript SDK, you can retrieve the access token [from the `stackClientApp` object](/sdk/types/user#currentusergetauthjson). Then, you can use said access token to make requests to Stack Auth:
```python
access_token = # access token retrieved from the JavaScript SDK
print(stack_auth_request('GET', '/api/v1/users/me', headers={
'x-stack-access-token': access_token,
}))
```
### Done!
</Steps>
## Next steps
Check out the [REST API documentation](../rest-api/overview.mdx) to learn more about the available endpoints and how to use them in your Python application.
{/* END_PLATFORM */}