stack/docs/code-examples/setup.ts
BilalG1 38ae913fc9
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migration compat / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests (Local Emulator) / E2E Tests (Local Emulator, Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Runs E2E Fallback Tests / E2E Fallback Tests (Node ${{ matrix.node-version }}) (22.x) (push) Has been cancelled
Lint & build / lint_and_build (24) (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migration compat / Back-compat — Current branch migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migration compat / Forward-compat — Current branch code with ${{ needs.check-migrations-changed.outputs.base_branch }} branch migrations (push) Has been cancelled
DB migration compat / No migration changes (skipped) (push) Has been cancelled
Rename STACK_* env vars to HEXCLAVE_* in env templates, with legacy dual-read (#1588)
## Summary

Completes the env-var side of the Hexclave rebrand: every
`STACK_*`-prefixed variable (including `NEXT_PUBLIC_STACK_*` and
`VITE_STACK_*`) is renamed to `HEXCLAVE_*` across all checked-in `.env`,
`.env.development`, and `.env.example` files (30 files, ~135 keys).
Legacy `STACK_*` names keep working everywhere via dual-read, so
**existing deployments, `.env.local` files, and self-hosted setups need
no immediate migration**.

## How legacy names keep working

- **Server code** already resolves `HEXCLAVE_*` first with `STACK_*`
fallback via `getEnvVariable`. Direct `process.env.STACK_X` readers fed
by the renamed files (prisma seed, e2e tests/helpers, internal-tool
scripts, examples, `prisma.config.ts`) now read `HEXCLAVE_X || STACK_X`.
- **Client code** (Next.js build-time inlining) uses literal dual-read
expressions; the dashboard's `_inlineEnvVars` already had them.
- **Docker/self-hosting**: `docker/server/entrypoint.sh` (shared by the
server and local-emulator images) gets a generic two-way
`HEXCLAVE_`↔`STACK_` env mirror — runs at startup and again before
sentinel replacement — replacing the previous URL-trio-only mirror.
Operators can use either prefix.

## The empty-placeholder trap (`||` vs `??`)

The checked-in templates define empty placeholders (`HEXCLAVE_X=#
comment` parses to `""` via dotenv). With `?? `-based fallbacks, that
empty string would silently shadow a real value under the legacy name —
including legacy vars set in Vercel/CI env at build time, since the
tracked `.env` is present during builds. All fallback chains therefore
treat empty-as-unset (`||`):

- `getEnvVariable` and `getProcessEnv` in `packages/shared`
- the dashboard/docs/example literal dual-reads
- the generated SDK env getters (via
`packages/template/scripts/generate-env.ts`; the generated
`src/generated/env.ts` files are gitignored and regenerate at build)

## Other notable changes

- Tests that override env now set the canonical `HEXCLAVE_*` name (it
wins over `STACK_*`): e2e `cross-domain-auth`, backend
`internal-feedback-emails` in-source test.
- e2e `helpers.ts` port-prefix expansion loop also matches the
`HEXCLAVE_` prefixes.
- `docker/local-emulator/generate-env-development.mjs` reads source keys
canonically (legacy fallback) and emits canonical keys; regenerated
output matches.
- `rotate-secrets.sh` falls back to
`HEXCLAVE_DATABASE_CONNECTION_STRING`.
- Docs code snippets (`docs/code-examples`) renamed outright to
canonical names, consistent with #1571.
- OAuth callback `console.warn` in `packages/template/src/lib/auth.ts`
now says Hexclave.

## Migration note for the team

Local `.env.local` files with legacy `STACK_*` overrides keep working
**unless** the override targets a var that `.env.development` now sets
to a real (non-empty) `HEXCLAVE_*` value — the canonical name wins over
file precedence. Rename those keys in your `.env.local` once.

## Verification

- `typecheck` + `lint` pass on every touched package (shared, backend,
dashboard, e2e, internal-tool, cli, docs, template). Pre-existing
failures on dev (`admin-app-impl.ts` typecheck, dashboard metrics-page
errors) are unchanged (identical error counts with/without this change).
- `getEnvVariable`/`getProcessEnv` fallback semantics smoke-tested
directly (empty-HEXCLAVE → legacy fallback, HEXCLAVE wins when set,
defaults intact).
- `internal-feedback-emails` in-source vitest passes; emulator env
generator `--check` passes; `bash -n` on touched shell scripts.
- Two independent review agents audited the diff for correctness bugs
and coverage gaps; all confirmed findings are fixed in the third commit.

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Renamed all `STACK_*` env vars (including
`NEXT_PUBLIC_STACK_*`/`VITE_STACK_*`) to `HEXCLAVE_*` across env
templates and code, with dual‑read that treats empty as unset, detects
conflicts, ignores post‑build sentinels, and falls back to legacy names.
All GitHub Actions now use `HEXCLAVE_*`; local‑emulator e2e is fixed by
setting `NEXT_PUBLIC_HEXCLAVE_IS_LOCAL_EMULATOR` in CI.

- **Refactors**
- Added conflict‑aware dual‑read helpers (prefer `HEXCLAVE_*`,
empty‑as‑unset, ignore post‑build sentinels, preserve empty passthrough)
and used them across `packages/shared` (resolver + tests),
`apps/dashboard` inline/public envs (with tests), `apps/backend` Prisma
config/seed and vitest (accept both prefixes), `packages/cli`
(API/Dashboard URLs, project ID, `HEXCLAVE_EMULATOR_HOME`; tests),
Docker (`entrypoint.sh` mirroring + `rotate-secrets.sh` DB URL),
docs/components (`docs/src/lib/env.ts`), and examples; hosted/Vite apps
now error if both spellings differ.
- Port‑prefix expansion includes `HEXCLAVE_*`; backend tests use a new
helper to resolve DB connection strings; Prisma prefers
`HEXCLAVE_DATABASE_CONNECTION_STRING` with legacy fallback.
- Generated SDK env getters use plain `HEXCLAVE_*` || `STACK_*` (no
conflict throw); dashboard inline resolver preserves empty/sentinel
passthrough to avoid build failures; docs/examples include dual‑read
utilities.
- Tests now stub canonical `HEXCLAVE_*` flags (e.g., plan limits, bot
challenge, OAuth tokens, hosted handler) to avoid shadowing/conflict
with committed defaults.

- **Migration**
  - No immediate action; legacy `STACK_*` names still work.
- If both names are set with different values, builds/scripts error. Set
only `HEXCLAVE_*` or make both equal.
- SDK consumers won’t see conflict throws; update env names to
`HEXCLAVE_*` over time.

<sup>Written for commit 7539fb9fbf.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/hexclave/hexclave/pull/1588?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

* **Chores**
* Migrated environment variable names from the legacy `STACK_*` prefix
to the new `HEXCLAVE_*` prefix across backend, dashboard, tooling,
Docker, and examples.
* Updated environment/config resolution to prefer `HEXCLAVE_*`, treat
empty strings as unset, and detect conflicts when both `STACK_*` and
`HEXCLAVE_*` are set to different values.
* Updated local emulator, server startup, and env-generation workflows
to use the new names (with legacy fallback where applicable).
* **Documentation**
  * Updated docs and code examples to reference `HEXCLAVE_*` variables.
* **Tests**
* Refreshed unit and e2e coverage to validate dual-read behavior,
conflict detection, and empty-value handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 18:58:53 -07:00

697 lines
21 KiB
TypeScript

import { CodeExample } from '../lib/code-examples';
export const setupExamples = {
'overview': {
'install': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `npx @stackframe/stack-cli@latest init`,
highlightLanguage: 'bash',
filename: 'Terminal'
}
] as CodeExample[],
'use-auth': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `const user = useUser({ or: "redirect" });
return <div>Hi, {user.displayName}</div>;`,
highlightLanguage: 'tsx',
filename: 'page.tsx'
}
] as CodeExample[],
},
'setup': {
'env-wizard': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `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>`,
highlightLanguage: 'bash',
filename: '.env.local'
},
{
language: 'JavaScript',
framework: 'React',
code: `// 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",
});`,
highlightLanguage: 'typescript',
filename: 'stack/client.ts'
},
{
language: 'JavaScript',
framework: 'Vanilla JavaScript',
code: `STACK_PROJECT_ID=<your-project-id>
STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>`,
highlightLanguage: 'bash',
filename: '.env'
}
] as CodeExample[],
'install-package': [
{ language: 'JavaScript', framework: 'Next.js', code: 'npm install @stackframe/stack', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'JavaScript', framework: 'React', code: 'npm install @stackframe/react', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'JavaScript', framework: 'Express', code: 'npm install @stackframe/js', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'JavaScript', framework: 'Node.js', code: 'npm install @stackframe/js', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'Python', framework: 'Django', code: 'pip install requests', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'Python', framework: 'FastAPI', code: 'pip install requests', highlightLanguage: 'bash', filename: 'Terminal' },
{ language: 'Python', framework: 'Flask', code: 'pip install requests', highlightLanguage: 'bash', filename: 'Terminal' },
] as CodeExample[],
'env-config': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `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>`,
highlightLanguage: 'bash',
filename: '.env.local'
},
{
language: 'JavaScript',
framework: 'React',
code: `# Store these in environment variables or directly in the client file during development
VITE_HEXCLAVE_PROJECT_ID=<your-project-id>
VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>`,
highlightLanguage: 'bash',
filename: '.env'
},
{
language: 'JavaScript',
framework: 'Express',
code: `STACK_PROJECT_ID=<your-project-id>
STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>`,
highlightLanguage: 'bash',
filename: '.env'
},
{
language: 'JavaScript',
framework: 'Node.js',
code: `STACK_PROJECT_ID=<your-project-id>
STACK_PUBLISHABLE_CLIENT_KEY=<your-publishable-client-key>
STACK_SECRET_SERVER_KEY=<your-secret-server-key>`,
highlightLanguage: 'bash',
filename: '.env'
},
{
language: 'Python',
framework: 'Django',
code: `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")`,
highlightLanguage: 'python',
filename: 'settings.py'
},
{
language: 'Python', framework: 'FastAPI',
code: `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")`,
highlightLanguage: 'python',
filename: 'main.py'
},
{
language: 'Python',
framework: 'Flask',
code: `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")`,
highlightLanguage: 'python',
filename: 'app.py'
}
] as CodeExample[],
'stack-config': [
{
language: 'JavaScript',
framework: 'Next.js',
variant: 'server',
code: `import "server-only";
import { StackServerApp } from "@stackframe/stack";
export const stackServerApp = new StackServerApp({
tokenStore: "nextjs-cookie", // storing auth tokens in cookies
});`,
highlightLanguage: 'typescript',
filename: 'stack/server.ts'
},
{
language: 'JavaScript',
framework: 'Next.js',
variant: 'client',
code: `import { StackClientApp } from "@stackframe/stack";
export const stackClientApp = new StackClientApp({
// Environment variables are automatically read
});`,
highlightLanguage: 'typescript',
filename: 'stack/client.ts'
},
{
language: 'JavaScript',
framework: 'React',
code: `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_HEXCLAVE_PROJECT_ID || "your-project-id",
publishableClientKey: process.env.VITE_HEXCLAVE_PUBLISHABLE_CLIENT_KEY || "your-publishable-client-key",
tokenStore: "cookie",
// redirectMethod: { useNavigate }, // Set this for non-Next.js frameworks
});`,
highlightLanguage: 'typescript',
filename: 'stack/client.ts'
},
{
language: 'JavaScript',
framework: 'Express',
variant: 'server',
code: `import { StackServerApp } from "@stackframe/js";
export const stackServerApp = new StackServerApp({
projectId: process.env.HEXCLAVE_PROJECT_ID,
publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY,
secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY,
tokenStore: "memory",
});`,
highlightLanguage: 'typescript',
filename: 'stack/server.ts'
},
{
language: 'JavaScript',
framework: 'Express',
variant: 'client',
code: `import { StackClientApp } from "@stackframe/js";
export const stackClientApp = new StackClientApp({
projectId: process.env.HEXCLAVE_PROJECT_ID,
publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY,
tokenStore: "cookie",
});`,
highlightLanguage: 'typescript',
filename: 'stack/client.ts'
},
{
language: 'JavaScript',
framework: 'Node.js',
variant: 'server',
code: `import { StackServerApp } from "@stackframe/js";
export const stackServerApp = new StackServerApp({
projectId: process.env.HEXCLAVE_PROJECT_ID,
publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY,
secretServerKey: process.env.HEXCLAVE_SECRET_SERVER_KEY,
tokenStore: "memory",
});`,
highlightLanguage: 'javascript',
filename: 'stack/server.js'
},
{
language: 'JavaScript',
framework: 'Node.js',
variant: 'client',
code: `import { StackClientApp } from "@stackframe/js";
export const stackClientApp = new StackClientApp({
projectId: process.env.HEXCLAVE_PROJECT_ID,
publishableClientKey: process.env.HEXCLAVE_PUBLISHABLE_CLIENT_KEY,
tokenStore: "cookie",
});`,
highlightLanguage: 'javascript',
filename: 'stack/client.js'
},
{
language: 'Python',
framework: 'Django',
code: `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()`,
highlightLanguage: 'python',
filename: 'views.py'
},
{
language: 'Python',
framework: 'FastAPI',
code: `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()`,
highlightLanguage: 'python',
filename: 'main.py'
},
{
language: 'Python',
framework: 'Flask',
code: `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()`,
highlightLanguage: 'python',
filename: 'app.py'
}
] as CodeExample[],
'auth-handlers': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `import { StackHandler } from "@stackframe/stack";
import { stackServerApp } from "@/stack/server";
export default function Handler(props: unknown) {
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
}`,
highlightLanguage: 'typescript',
filename: 'app/handler/[...stack]/page.tsx'
},
{
language: 'JavaScript',
framework: 'React',
code: `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>
);
}`,
highlightLanguage: 'typescript',
filename: 'App.tsx'
},
{
language: 'JavaScript',
framework: 'Express',
code: `// Express doesn't use built-in handlers
// Use the REST API or integrate with your frontend`,
highlightLanguage: 'typescript',
filename: 'Note'
},
{
language: 'JavaScript',
framework: 'Node.js',
code: `// Node.js doesn't use built-in handlers
// Use the REST API or integrate with your frontend`,
highlightLanguage: 'javascript',
filename: 'Note'
}
] as CodeExample[],
'app-providers': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `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>
);
}`,
highlightLanguage: 'typescript',
filename: 'app/layout.tsx'
},
{
language: 'JavaScript',
framework: 'React',
code: `// Already shown in the App.tsx example above
// Make sure to wrap your app with StackProvider and StackTheme`,
highlightLanguage: 'typescript',
filename: 'Note'
}
] as CodeExample[],
'loading-boundary': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `export default function Loading() {
// You can use any loading indicator here
return <>
Loading...
</>;
}`,
highlightLanguage: 'typescript',
filename: 'app/loading.tsx'
}
] as CodeExample[],
'suspense-boundary': [
{
language: 'JavaScript',
framework: 'React',
code: `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
<Suspense fallback={<div>Loading...</div>}>
<StackProvider app={stackClientApp}>
{/* Your app content */}
</StackProvider>
</Suspense>
);
}`,
highlightLanguage: 'typescript',
filename: 'App.tsx'
}
] as CodeExample[],
'test-setup': [
{
language: 'JavaScript',
framework: 'Next.js',
code: `# Start your Next.js app
npm run dev
# Navigate to the sign-up page
# http://localhost:3000/handler/sign-up`,
highlightLanguage: 'bash',
filename: 'Terminal'
},
{
language: 'JavaScript',
framework: 'React',
code: `# Start your React app
npm run dev
# Navigate to the sign-up page
# http://localhost:5173/handler/sign-up`,
highlightLanguage: 'bash',
filename: 'Terminal'
},
{
language: 'JavaScript',
framework: 'Express',
code: `# Start your Express server
npm start
# Use the REST API or integrate with your frontend
# Check the REST API documentation for endpoints`,
highlightLanguage: 'bash',
filename: 'Terminal'
},
{
language: 'JavaScript',
framework: 'Node.js',
code: `# Start your Node.js app
node index.js
# Use the REST API or integrate with your frontend
# Check the REST API documentation for endpoints`,
highlightLanguage: 'bash',
filename: 'Terminal'
},
{
language: 'Python',
framework: 'Django',
code: `# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your Django server
python manage.py runserver`,
highlightLanguage: 'python',
filename: 'Terminal'
},
{
language: 'Python',
framework: 'FastAPI',
code: `# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your FastAPI server
uvicorn main:app --reload`,
highlightLanguage: 'python',
filename: 'Terminal'
},
{
language: 'Python',
framework: 'Flask',
code: `# Test the Stack Auth API connection
print(stack_auth_request('GET', '/api/v1/projects/current'))
# Start your Flask server
flask run`,
highlightLanguage: 'python',
filename: 'Terminal'
}
] as CodeExample[],
'basic-usage': [
{
language: 'JavaScript',
framework: 'Next.js',
variant: 'server',
code: `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");
}`,
highlightLanguage: 'typescript',
filename: 'Server Component'
},
{
language: 'JavaScript',
framework: 'Next.js',
variant: 'client',
code: `'use client';
import { useUser } from "@stackframe/stack";
export default function MyComponent() {
const user = useUser();
if (user) {
return <div>Hello, {user.displayName}!</div>;
} else {
return <div>Please sign in</div>;
}
}`,
highlightLanguage: 'typescript',
filename: 'Client Component'
},
{
language: 'JavaScript',
framework: 'React',
code: `import { useUser } from "@stackframe/react";
export default function MyComponent() {
const user = useUser();
if (user) {
return <div>Hello, {user.displayName}!</div>;
} else {
return <div>Please sign in</div>;
}
}`,
highlightLanguage: 'typescript',
filename: 'Component'
},
{
language: 'JavaScript',
framework: 'Express',
code: `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' });
}
});`,
highlightLanguage: 'typescript',
filename: 'server.ts'
},
{
language: 'JavaScript',
framework: 'Node.js',
code: `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);
}
}`,
highlightLanguage: 'javascript',
filename: 'index.js'
},
{
language: 'Python',
framework: 'Django',
code: `# 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)`,
highlightLanguage: 'python',
filename: 'views.py'
},
{
language: 'Python',
framework: 'FastAPI',
code: `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")`,
highlightLanguage: 'python',
filename: 'main.py'
},
{
language: 'Python',
framework: 'Flask',
code: `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`,
highlightLanguage: 'python',
filename: 'app.py'
}
] as CodeExample[]
}
};