--- title: Setup description: Install and configure Stack Auth for your project sidebarTitle: Setup icon: "gear" --- # Setup ## Prerequisites Before getting started, make sure you have a project set up for your chosen platform: - **Next.js**: A [Next.js project](https://nextjs.org/docs/getting-started/installation) using the app router (Stack Auth does not support the pages router on Next.js) - **React**: A [React project](https://react.dev/learn/creating-a-react-app) (we show examples with Vite) - **JavaScript**: A Node.js project with Express - **Python**: A Python environment with your chosen framework (Django, FastAPI, or Flask) We recommend using our **setup wizard** for JavaScript frameworks for a seamless installation experience. For Python, we recommend using the REST API approach. ## Setup Wizard / Manual Installation ### Setup wizard (recommended for JS) #### Run installation wizard The setup wizard is available for JavaScript/TypeScript frameworks. For Python projects, please use the manual installation method. Run Stack's installation wizard with the following command: ```sh title="Terminal" npx @stackframe/stack-cli@latest init ``` #### Update API keys Create an account on [the Stack Auth dashboard](https://app.stack-auth.com/projects), create a new project, and copy its environment variables into the appropriate configuration file. If your project requires publishable client keys, create a project key that includes one and copy that as well. ```bash title=".env.local" NEXT_PUBLIC_STACK_PROJECT_ID= NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY= STACK_SECRET_SERVER_KEY= ``` ```typescript title="stack/client.ts" // Update the values in stack/client.ts created by the wizard export const stackClientApp = new StackClientApp({ projectId: "your-project-id", publishableClientKey: "your-publishable-client-key", tokenStore: "cookie", }); ``` ```bash title=".env" STACK_PROJECT_ID= STACK_PUBLISHABLE_CLIENT_KEY= STACK_SECRET_SERVER_KEY= ``` #### Done! That's it! The wizard should have created or updated the following files in your project: - `app/handler/[...stack]/page.tsx`: Default pages for sign-in, sign-out, account settings, and more - `app/layout.tsx`: Updated to wrap the entire body with `StackProvider` and `StackTheme` - `app/loading.tsx`: Suspense boundary for Stack's async hooks - `stack/server.ts`: Contains the `stackServerApp` for server-side usage - `stack/client.ts`: Contains the `stackClientApp` for client-side usage - `stack/client.ts`: Contains the `stackClientApp` configuration - Your app should be wrapped with `StackProvider` and `StackTheme` - `stack/server.ts`: Contains the `stackServerApp` configuration ### Manual installation The setup wizard also supports existing, complicated projects. Cases where manual installation is necessary are rare for JavaScript frameworks. First, install the appropriate Stack package: ```bash title="Terminal" npm install @stackframe/stack ``` ```bash title="Terminal" npm install @stackframe/react ``` ```bash title="Terminal" npm install @stackframe/js ``` ```bash title="Terminal" npm install @stackframe/js ``` ```bash title="Terminal" pip install requests ``` ```bash title="Terminal" pip install requests ``` ```bash title="Terminal" pip install requests ``` [Register a new account on Stack](https://app.stack-auth.com/handler/sign-up), create a project in the dashboard, and copy the project ID. If your project requires publishable client keys, also create a project key from the left sidebar and copy the publishable client key. For server-side setups, also copy the secret server key. Set up your environment variables or configuration: ```bash title=".env.local" NEXT_PUBLIC_STACK_PROJECT_ID= NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY= STACK_SECRET_SERVER_KEY= ``` ```bash title=".env" # Store these in environment variables or directly in the client file during development VITE_STACK_PROJECT_ID= VITE_STACK_PUBLISHABLE_CLIENT_KEY= ``` ```bash title=".env" STACK_PROJECT_ID= STACK_PUBLISHABLE_CLIENT_KEY= STACK_SECRET_SERVER_KEY= ``` ```bash title=".env" STACK_PROJECT_ID= STACK_PUBLISHABLE_CLIENT_KEY= STACK_SECRET_SERVER_KEY= ``` ```python title="settings.py" 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") ``` ```python title="main.py" 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") ``` ```python title="app.py" 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") ``` Create the Stack app configuration: ```typescript 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 }); ``` ```typescript title="stack/client.ts" import { StackClientApp } from "@stackframe/stack"; export const stackClientApp = new StackClientApp({ // Environment variables are automatically read }); ``` ```typescript title="stack/client.ts" import { StackClientApp } from "@stackframe/react"; // If you use a router, uncomment the appropriate import and the redirectMethod below // import { useNavigate } from "react-router-dom"; // React Router // import { useNavigate } from "@tanstack/react-router"; // TanStack Router export const stackClientApp = new StackClientApp({ projectId: process.env.VITE_STACK_PROJECT_ID || "your-project-id", publishableClientKey: process.env.VITE_STACK_PUBLISHABLE_CLIENT_KEY || "your-publishable-client-key", tokenStore: "cookie", // redirectMethod: { useNavigate }, // Set this for non-Next.js frameworks }); ``` ```typescript title="stack/server.ts" import { StackServerApp } from "@stackframe/js"; export const stackServerApp = new StackServerApp({ projectId: process.env.STACK_PROJECT_ID, publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, secretServerKey: process.env.STACK_SECRET_SERVER_KEY, tokenStore: "memory", }); ``` ```javascript title="stack/server.js" import { StackServerApp } from "@stackframe/js"; export const stackServerApp = new StackServerApp({ projectId: process.env.STACK_PROJECT_ID, publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, secretServerKey: process.env.STACK_SECRET_SERVER_KEY, tokenStore: "memory", }); ``` ```javascript title="stack/client.js" import { StackClientApp } from "@stackframe/js"; export const stackClientApp = new StackClientApp({ projectId: process.env.STACK_PROJECT_ID, publishableClientKey: process.env.STACK_PUBLISHABLE_CLIENT_KEY, tokenStore: "cookie", }); ``` ```python title="views.py" 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() ``` ```python title="main.py" 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() ``` ```python title="app.py" 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() ``` For JavaScript frameworks, create the authentication handler: ```typescript title="app/handler/[...stack]/page.tsx" import { StackHandler } from "@stackframe/stack"; import { stackServerApp } from "@/stack/server"; export default function Handler(props: unknown) { return ; } ``` ```typescript 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 ( ); } export default function App() { return ( } /> hello world} /> ); } ``` ```typescript title="Note" // Express doesn't use built-in handlers // Use the REST API or integrate with your frontend ``` ```javascript title="Note" // Node.js doesn't use built-in handlers // Use the REST API or integrate with your frontend ``` For Next.js and React, wrap your app with Stack providers: ```typescript 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 ( {children} ); } ``` ```typescript title="Note" // Already shown in the App.tsx example above // Make sure to wrap your app with StackProvider and StackTheme ``` For Next.js, add a Suspense boundary: ```typescript title="app/loading.tsx" export default function Loading() { // You can use any loading indicator here return <>Loading...; } ``` For React, add a suspense boundary: ```typescript title="App.tsx" import { Suspense } from "react"; import { StackProvider } from "@stackframe/react"; import { stackClientApp } from "./stack/client"; export default function App() { return ( // Wrap your StackProvider with Suspense for async hooks to work Loading...}> {/* Your app content */} ); } ``` ## Post-setup That's it! Stack is now configured in your project. ### Testing your setup ```bash title="Terminal" # Start your Next.js app npm run dev # Navigate to the sign-up page # http://localhost:3000/handler/sign-up ``` ```bash title="Terminal" # Start your React app npm run dev # Navigate to the sign-up page # http://localhost:5173/handler/sign-up ``` ```bash title="Terminal" # Start your Express server npm start # Use the REST API or integrate with your frontend # Check the REST API documentation for endpoints ``` ```bash title="Terminal" # Start your Node.js app node index.js # Use the REST API or integrate with your frontend # Check the REST API documentation for endpoints ``` ```python title="Terminal" # Test the Stack Auth API connection print(stack_auth_request('GET', '/api/v1/projects/current')) # Start your Django server python manage.py runserver ``` ```python title="Terminal" # Test the Stack Auth API connection print(stack_auth_request('GET', '/api/v1/projects/current')) # Start your FastAPI server uvicorn main:app --reload ``` ```python title="Terminal" # Test the Stack Auth API connection print(stack_auth_request('GET', '/api/v1/projects/current')) # Start your Flask server flask run ``` ### What you'll see For JavaScript frameworks with built-in UI components, you'll see the Stack Auth sign-up page: Stack sign-in page After signing up/in, you will be redirected back to the home page. You can also check out the account settings page. Stack account settings page For Python and backend-only JavaScript setups, you'll interact with Stack Auth through the REST API. ## Example usage Here are some basic usage examples for each platform: ```typescript title="Server Component" import { stackServerApp } from "@/stack/server"; // In a Server Component or API route const user = await stackServerApp.getUser(); if (user) { console.log("User is signed in:", user.displayName); } else { console.log("User is not signed in"); } ``` ```typescript title="Client Component" 'use client'; import { useUser } from "@stackframe/stack"; export default function MyComponent() { const user = useUser(); if (user) { return
Hello, {user.displayName}!
; } else { return
Please sign in
; } } ```
```typescript title="Component" import { useUser } from "@stackframe/react"; export default function MyComponent() { const user = useUser(); if (user) { return
Hello, {user.displayName}!
; } else { return
Please sign in
; } } ```
```typescript title="server.ts" import { stackServerApp } from "./stack/server.js"; app.get('/profile', async (req, res) => { try { // Get access token from request headers const accessToken = req.headers['x-stack-access-token']; const user = await stackServerApp.getUser({ accessToken }); if (user) { res.json({ message: `Hello, ${user.displayName}!` }); } else { res.status(401).json({ error: 'Not authenticated' }); } } catch (error) { res.status(500).json({ error: 'Server error' }); } }); ``` ```javascript title="index.js" import { stackServerApp } from "./stack/server.js"; async function checkUser(accessToken) { try { const user = await stackServerApp.getUser({ accessToken }); if (user) { console.log(`Hello, ${user.displayName}!`); } else { console.log('User not authenticated'); } } catch (error) { console.error('Error:', error); } } ``` ```python title="views.py" # In your views.py def profile_view(request): # Get access token from request headers access_token = request.headers.get('X-Stack-Access-Token') try: user_data = stack_auth_request('GET', '/api/v1/users/me', headers={ 'x-stack-access-token': access_token, }) return JsonResponse({'message': f"Hello, {user_data['displayName']}!"}) except Exception as e: return JsonResponse({'error': 'Not authenticated'}, status=401) ``` ```python title="main.py" from fastapi import FastAPI, Header, HTTPException app = FastAPI() @app.get("/profile") async def get_profile(x_stack_access_token: str = Header(None)): if not x_stack_access_token: raise HTTPException(status_code=401, detail="Access token required") try: user_data = stack_auth_request('GET', '/api/v1/users/me', headers={ 'x-stack-access-token': x_stack_access_token, }) return {"message": f"Hello, {user_data['displayName']}!"} except Exception as e: raise HTTPException(status_code=401, detail="Not authenticated") ``` ```python title="app.py" from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/profile') def profile(): access_token = request.headers.get('X-Stack-Access-Token') if not access_token: return jsonify({'error': 'Access token required'}), 401 try: user_data = stack_auth_request('GET', '/api/v1/users/me', headers={ 'x-stack-access-token': access_token, }) return jsonify({'message': f"Hello, {user_data['displayName']}!"}) except Exception as e: return jsonify({'error': 'Not authenticated'}), 401 ```
## Next steps Next up, we will show you how to [retrieve and update user information](./users), and how to [protect a page](./users#protecting-a-page) from unauthorized access. For Python developers, check out the [REST API documentation](../rest-api/overview) to learn more about the available endpoints and how to use them in your Python application.