mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Update documentation
This commit is contained in:
parent
800392ef23
commit
e9bca40daf
94
docs/docs/01-getting-started/01-setup.md
Normal file
94
docs/docs/01-getting-started/01-setup.md
Normal file
@ -0,0 +1,94 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Installation & Setup
|
||||
|
||||
## Installation
|
||||
|
||||
To get started with the Stack, you need to have [Next.js](https://nextjs.org/docs) setup for you project. If you are starting from scratch, run the following command to create a new Next.js project:
|
||||
|
||||
```bash
|
||||
npx create-next-app@latest stack-example
|
||||
```
|
||||
|
||||
Once you have your Next.js project setup, you can install Stack by running the following command:
|
||||
|
||||
```bash
|
||||
npm install @stackframe/stack
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. If you haven't already, [register a new account on Stack](https://app.stackframe.co). 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:
|
||||
|
||||
```javascript
|
||||
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>
|
||||
```
|
||||
|
||||
2. Create `StackServerApp` in `lib/stack.ts`:
|
||||
|
||||
```tsx
|
||||
import "server-only";
|
||||
import { StackServerApp } from "@stackframe/stack";
|
||||
|
||||
export const stackApp = new StackServerApp({
|
||||
// Automatically reads your API keys from the environment variables you set above.
|
||||
//
|
||||
// Alternatively, you could set them manually:
|
||||
//
|
||||
// projectId: process.env.NEXT_PUBLIC_STACK_PROJECT_ID,
|
||||
// publishableClientKey: process.env.NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY,
|
||||
// secretServerKey: process.env.STACK_SECRET_SERVER_KEY,
|
||||
|
||||
tokenStore: "nextjs-cookie", // storing auth tokens in cookies
|
||||
});
|
||||
```
|
||||
|
||||
This will create a server app that you can later use to access Stack from your Next.js server.
|
||||
|
||||
3. Create a new file in `app/handler/[...stack]/page.tsx` and paste the following code:
|
||||
|
||||
```tsx
|
||||
import { StackHandler } from "@stackframe/stack";
|
||||
import { stackApp } from "lib/stack";
|
||||
|
||||
export default function Handler(props) {
|
||||
return <StackHandler app={stackApp} {...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](/docs/customization) later.
|
||||
|
||||
|
||||
4. In your `app/layout.tsx`, wrap your entire layout with a `StackProvider`. Afterwards, it should look like this:
|
||||
|
||||
```tsx
|
||||
import { StackProvider } from "@stackframe/stack";
|
||||
import { stackApp } from "@stackframe/stack";
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<StackProvider app={stackApp}>
|
||||
{children}
|
||||
</StackProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
This lets you use the `useStackApp()` and `useUser()` hooks.
|
||||
|
||||
5. 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`, you will see the Stack sign-up page!
|
||||
|
||||

|
||||
|
||||
|
||||
## Next steps
|
||||
|
||||
Next, we will show you how to get user information, protect a page, and modify the user profile.
|
||||
155
docs/docs/01-getting-started/02-users.md
Normal file
155
docs/docs/01-getting-started/02-users.md
Normal file
@ -0,0 +1,155 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
|
||||
# Users & Protected Pages
|
||||
|
||||
In [the last section](/docs/01-setup), we created `StackServerApp` and `StackProvider`. In this section, we will show you how to utilize them for accessing and modifying the current user information on Server Components and Client Components, respectively.
|
||||
|
||||
## Client Components
|
||||
|
||||
We can use the `useStackApp()` hook to get a `StackClientApp` object. With it, we can retrieve the current user in Client Components:
|
||||
|
||||
```tsx
|
||||
"use client";
|
||||
import { useStackApp } from "@stackframe/stack";
|
||||
|
||||
export function MyComponent() {
|
||||
const app = useStackApp();
|
||||
const user = app.useUser();
|
||||
|
||||
return <div>{user ? `Hello, ${user.displayName}` : 'You are not logged in'}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
Because it's so common, `useUser()` is also exposed as a standalone hook. This means that you can simply invoke `useUser()` as an alias for `useStackApp().useUser()`. (This is not true for other hooks; for example, you must call `useStackApp().useProject()` instead of `useProject()`.)
|
||||
|
||||
## Server Components
|
||||
|
||||
On Server Components, you don't need `useStackApp()`. Instead, you can just import the `StackServerApp` that you created in the previous chapter:
|
||||
|
||||
```tsx
|
||||
import "server-only";
|
||||
import { stackApp } from "lib/stack";
|
||||
|
||||
export default async function MyComponent() {
|
||||
const user = await stackApp.getUser();
|
||||
|
||||
return <div>{user ? `Hello, ${user.displayName}` : 'You are not logged in'}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
The difference between `getUser()` and `useUser()` is that `useUser()` will re-render the component when the user changes (for example on signout), while `getUser()` will only fetch the user once. Since Server Components cannot re-render, `useUser()` cannot be used there.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
## Protecting a page
|
||||
|
||||
Call `useUser` (or `getUser`) with the `{ or: 'redirect' }` option to protect the page. If the user is not logged in, they will be redirected to the sign-in page.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="client" label="Client Component" default>
|
||||
```tsx
|
||||
"use client";
|
||||
import { useStackApp } from "@stackframe/stack";
|
||||
|
||||
export default function Protected() {
|
||||
useUser({ or: 'redirect' });
|
||||
return <h1>You can only see this if you are logged in</h1>
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="server" label="Server Component">
|
||||
```tsx
|
||||
import "server-only";
|
||||
import { useStackApp } from "@stackframe/stack";
|
||||
|
||||
export default async function Protected() {
|
||||
await stack.getUser({ or: 'redirect' });
|
||||
return <h1>You can only see this if you are logged in</h1>
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Examples
|
||||
|
||||
### User profile
|
||||
|
||||
Stack automatically creates a user profile on sign-up. Let's create a page that displays this information.
|
||||
|
||||
Depending on whether you want to use a Client or Server Component, copy the following code into `app/page.tsx`:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="client" label="Client Component" default>
|
||||
```tsx
|
||||
'use client';
|
||||
import { useStackApp } from "@stackframe/stack";
|
||||
|
||||
export default function PageClient() {
|
||||
const app = useStackApp();
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
{user ? (
|
||||
<div>
|
||||
<p>Welcome, {user.displayName}</p>
|
||||
<p>Your e-mail: {user.primaryEmail}</p>
|
||||
<p>Your e-mail verification status: {user.primaryEmailVerified}</p>
|
||||
<button onClick={() => app.signOut()}>Sign Out</button>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<p>You are not logged in</p>
|
||||
<button onClick={() => app.redirectToSignIn()}>Sign in</button>
|
||||
<button onClick={() => app.redirectToSignUp()}>Sign up</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="server" label="Server Component">
|
||||
```tsx
|
||||
import "server-only";
|
||||
import { stack } from "../lib/stack";
|
||||
|
||||
export default async function Page() {
|
||||
const user = await stack.getUser();
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
{user ? (
|
||||
<div>
|
||||
<p>Welcome, {user.displayName}</p>
|
||||
<p>Your e-mail: {user.primaryEmail}</p>
|
||||
<p>Your e-mail verification status: {user.primaryEmailVerified}</p>
|
||||
<button onClick={() => app.signOut()}>Sign Out</button>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<p>You are not logged in</p>
|
||||
<button onClick={() => app.redirectToSignIn()}>Sign in</button>
|
||||
<button onClick={() => app.redirectToSignUp()}>Sign up</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Next steps
|
||||
|
||||
Next, we will take a look at the actions that can be taken from the server-side.
|
||||
11
docs/docs/01-getting-started/03-server-side.md
Normal file
11
docs/docs/01-getting-started/03-server-side.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Server-Side App
|
||||
|
||||
Compared to `StackClientApp` (which is available to everyone with just a publishable client key), `StackServerApp` has some extra features. Particularly, it can be used to view & modify *other* users. Hence, it is crucial to keep the secret server key secure.
|
||||
|
||||
## Next steps
|
||||
|
||||
Next, we will try to understand what steps we need to go into production.
|
||||
11
docs/docs/01-getting-started/04-going-into-production.md
Normal file
11
docs/docs/01-getting-started/04-going-into-production.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Going Into Production
|
||||
|
||||
// TODO
|
||||
|
||||
## Next steps
|
||||
|
||||
Next, we will show how to customize or create your own custom pages.
|
||||
@ -1,83 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Install & Setup
|
||||
|
||||
## Installation
|
||||
|
||||
To get started with the Stack, you need to have [Next.js](https://nextjs.org/docs) setup for you project. If you are starting from scratch, run the following command to create a new Next.js project:
|
||||
|
||||
```bash
|
||||
npx create-next-app@latest stack-example
|
||||
```
|
||||
|
||||
Once you have your Next.js project setup, you can install Stack by running the following command:
|
||||
|
||||
```bash
|
||||
npm install @stack/next
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. Register an account on Stack [here](https://stack.app) if you don't already have and account. Create an project in the dashboard, and put the Project ID, publishable client key, and secret server key in the `.env.local` file in the root of your Next.js project like this:
|
||||
|
||||
```javascript
|
||||
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>
|
||||
```
|
||||
|
||||
2. Create `StackServerApp` in `lib/stack.ts`:
|
||||
|
||||
```tsx
|
||||
import { StackServerApp } from '@stack/next';
|
||||
|
||||
export const stack = new StackServerApp({
|
||||
tokenStore: "nextjs-cookie", // storing auth tokens in cookies
|
||||
});
|
||||
```
|
||||
|
||||
This will create a server app that handles all the server side functions. You can import it from other files to use the functions bind to it.
|
||||
|
||||
3. Create a new file and its parent folders in the Next.js app folder: `app/handler/[...stack]/page.tsx`. Then add the following code to the file:
|
||||
|
||||
```tsx
|
||||
import { StackHandler } from "stack";
|
||||
import { stackServerApp } from "lib/stack";
|
||||
|
||||
export default function Handler(props) {
|
||||
return <StackHandler app={stackServerApp} {...props} />;
|
||||
}
|
||||
```
|
||||
|
||||
The handler will be handle all the pages like `signin`, `signup`, `password-reset`, etc. automatically for you. You can later customize and change the route of these pages easily.
|
||||
|
||||
|
||||
4. In your `app/layout.tsx`, add the `StackProvider`, it should look something like this:
|
||||
```tsx
|
||||
import { StackProvider } from '@stack/next';
|
||||
import { stack } from 'lib/stack';
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<StackProvider app={stack}>
|
||||
{children}
|
||||
</StackProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The provider will provide information to the frontend functions and hooks.
|
||||
|
||||
5. That's it! Stack is not 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`, you should see the Stack signup page liek this:
|
||||

|
||||
|
||||
|
||||
## Next steps
|
||||
|
||||
Now you have a basic stack setup in your Next.js project and you can already access all the features like signup, signin, reset password, etc. In the next section, we will show you how to protect a page, get user information, and using functions like signout.
|
||||
85
docs/docs/02-advanced-guides/01-customization/01-overview.md
Normal file
85
docs/docs/02-advanced-guides/01-customization/01-overview.md
Normal file
@ -0,0 +1,85 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
title: Overview
|
||||
---
|
||||
|
||||
# Customization Overview
|
||||
|
||||
Stack provides two ways to customize the UI:
|
||||
|
||||
- **CSS customization**: You can modify default UI looks by overriding the styles of class names beginning with `wl_`, such as `wl_btn`.
|
||||
- **Custom pages**: You can create custom pages for sign in, sign up, reset password and more, thanks to built-in components.
|
||||
- **From scratch**: If all else fails, you can always reimplement our components from scratch with the helper functions that we provide.
|
||||
|
||||
## CSS customization
|
||||
|
||||
You can modify the default UI looks by overriding the styles of class names beginning with `wl_`, such as `wl_btn`. (Please stay tuned — we're updating this part of the documentation!)
|
||||
|
||||
## Custom pages
|
||||
|
||||
By default, `StackHandler` creates all pages you need. However, if you'd like a bit of additional control, you can always use our built-in components (such as `<SignIn />`) to build your own pages for all features. For example, if you have the following in `app/signin/page.tsx`:
|
||||
|
||||
```tsx
|
||||
import { SignIn } from "@stackframe/stack";
|
||||
|
||||
export default function CustomSignInPage() {
|
||||
return <div>
|
||||
<h1>My Custom Sign In page</h1>
|
||||
<SignIn />
|
||||
</div>;
|
||||
}
|
||||
```
|
||||
|
||||
Then you can instruct the Stack app in `lib/stack.ts` to use your custom sign in page:
|
||||
|
||||
```tsx
|
||||
export const stackApp = new StackServerApp({
|
||||
// ...
|
||||
// add these three lines
|
||||
urls: {
|
||||
signIn: '/signin',
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
You are now all set! If you visit the `/signin` page, you should see your custom sign in page. If your user visits a protected page or the old `/handler/signin` URL, they will be redirected to your new sign-in page.
|
||||
|
||||
For more examples, please refer to the [Examples](/docs/category/examples).
|
||||
|
||||
|
||||
## From scratch
|
||||
|
||||
We also provide the low-level functions powering our components, so that you can build your own logic. For example, to build a custom OAuth sign-in button, create a file at `app/signin/page.tsx`:
|
||||
|
||||
```tsx
|
||||
"use client";
|
||||
import { useStackApp } from "@stackframe/stack";
|
||||
|
||||
export default function CustomOAuthSignInPage() {
|
||||
const app = useStackApp();
|
||||
|
||||
return <div>
|
||||
<h1>My Custom Sign In page</h1>
|
||||
<button onClick={async () => await app.signInWithOauth('google')}>Sign In with Google</button>
|
||||
</div>;
|
||||
}
|
||||
```
|
||||
|
||||
Again, edit the Stack app in `lib/stack.ts` to use your custom sign in page:
|
||||
|
||||
```tsx
|
||||
export const stackApp = new StackServerApp({
|
||||
// ...
|
||||
// add these three lines
|
||||
urls: {
|
||||
signIn: '/signin',
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
As above, visit the `/signin` page to see your newly created custom OAuth page.
|
||||
|
||||
|
||||
## Next steps
|
||||
|
||||
Take a look at the [customization examples](/docs/category/examples) to see how to build custom pages for sign in, sign up, reset password, and more.
|
||||
@ -4,7 +4,7 @@ sidebar_position: 1
|
||||
|
||||
# Sign In
|
||||
|
||||
## Default Sign In Component
|
||||
## Custom page with `SignIn` component
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
@ -13,11 +13,11 @@ import { useStackApp, SignIn } from "stack";
|
||||
export default function DefaultSignIn() {
|
||||
const app = useStackApp();
|
||||
|
||||
return <SignIn fullPage redirectUrl={app.urls.userHome}/>;
|
||||
return <SignIn fullPage redirectUrl={app.urls.userHome} />;
|
||||
}
|
||||
```
|
||||
|
||||
Note that if you don't pass in a `redirectUrl`, the user will be redirected to the same page, which is useful if you want to build a sign in modal.
|
||||
`redirectUrl` is optional and defaults to the current page.
|
||||
|
||||
|
||||
## Custom OAuth Sign In
|
||||
@ -40,4 +40,4 @@ export default function CustomOAuthSignIn() {
|
||||
|
||||
## Custom Credential Sign In
|
||||
|
||||
```tsx
|
||||
```tsx
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"label": "Pages",
|
||||
"position": 7,
|
||||
"label": "Examples",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"label": "Server API",
|
||||
"position": 6,
|
||||
"label": "Customization",
|
||||
"position": 1,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
|
||||
# User and Protect Page
|
||||
|
||||
## User information page
|
||||
|
||||
Let's create a home page which will show the user name and a log out button when the user is logged in, and links to the login and signup when the user is not logged in. Let's create a page in `app/page.tsx`.
|
||||
|
||||
Note that if you are using client component, you have to put this in a separate file like `apps/page-client.tsx` and import it in the `app/page.tsx` file.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="client" label="Client Component" default>
|
||||
```tsx
|
||||
'use client';
|
||||
import { useUser, redirectToSignIn, redirectToSignUp, signOut } from '@stack/next';
|
||||
|
||||
export default function Home() {
|
||||
const user = useUser();
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
{user ? (
|
||||
<div>
|
||||
<p>Welcome, {user.displayName}</p>
|
||||
<button onClick={signOut}>Sign Out</button>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<p>You are not logged in</p>
|
||||
<button onClick={redirectToSignIn}>Sign in</button>
|
||||
<button onClick={redirectToSignUp}>Sign up</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="server" label="Server Component">
|
||||
```tsx
|
||||
import { stack } from '../lib/stack';
|
||||
|
||||
export default function Page() {
|
||||
const user = await stack.getUser();
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
{user ? (
|
||||
<div>
|
||||
<p>Welcome, {user.displayName}</p>
|
||||
<a href={stack.signOutUrl}>Sign Out</a>
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<p>You are not logged in</p>
|
||||
<a href={stack.signInUrl}>Sign in</a>
|
||||
<a href={stack.signUpUrl}>Sign up</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Now if you navigate to `http://localhost:3000`, you should see the home page.
|
||||
|
||||
## Protect a page
|
||||
|
||||
If you want to protect a page so that only logged in users can access it, you can add `{ or: 'redirect' }` to the `useUser` hook or `stack.getUser` function. Here is an example server side example:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="client" label="Client Component" default>
|
||||
```tsx
|
||||
'use client';
|
||||
import { useUser, redirectToSignIn } from '@stack/next';
|
||||
|
||||
export default function Protected() {
|
||||
useUser({ or: 'redirect' });
|
||||
return <h1>You can only see this if you are logged in</h1>
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="server" label="Server Component">
|
||||
```tsx
|
||||
import { stack } from '../lib/stack';
|
||||
|
||||
export default function Protected() {
|
||||
await stack.getUser({ or: 'redirect' });
|
||||
return <h1>You can only see this if you are logged in</h1>
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Next steps
|
||||
|
||||
Now you have a basic stack setup in your Next.js project and you also know how to use and interact with the stack functions. In the next sections, we will show how to customize or create your own custom pages and how to use stack in your backend server.
|
||||
|
||||
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# User
|
||||
# App
|
||||
@ -0,0 +1,6 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_class_name: starred
|
||||
---
|
||||
|
||||
# StackHandler
|
||||
@ -0,0 +1,6 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_class_name: starred
|
||||
---
|
||||
|
||||
# StackProvider
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"label": "Next.js API",
|
||||
"position": 5,
|
||||
"label": "Components",
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# EmailVerification
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# ForgotPassword
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# OauthCallback
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# PasswordReset
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# SignIn
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# SignUp
|
||||
@ -0,0 +1,6 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_class_name: starred
|
||||
---
|
||||
|
||||
# useStackApp
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"label": "Standalone Hooks",
|
||||
"position": 3,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
---
|
||||
|
||||
# useUser
|
||||
@ -1,41 +0,0 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Custom Pages
|
||||
|
||||
Stack handler automatically creates all the pages you need with a good default design, so you can get started very quickly without any extra setup. However, if you want to customize the look or even have some special logic, you can create your own pages and tell the handler to redirect to your pages instead.
|
||||
|
||||
## Custom OAuth sign in page
|
||||
|
||||
Here we show an example of how to create a simple custom OAuth sign in page. For demostration purpose, we won't style it, but you can choose your favorite UI framework and make it look good! If you want to know how to build other custome pages like credential sign in, signup, or reset password, you can find detailed information of all the pages are in the [Custom Pages](/docs/category/pages) section.
|
||||
|
||||
Create a new file `app/signin/page.tsx` and add the following code:
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
import { useStackApp } from "stack";
|
||||
|
||||
export default function CustomOAuthSignIn() {
|
||||
const app = useStackApp();
|
||||
|
||||
return <div>
|
||||
<h1>My Custom Sign In page</h1>
|
||||
<button onClick={async () => await app.signInWithOauth('google')}>Sign In with Google</button>
|
||||
</div>;
|
||||
}
|
||||
```
|
||||
|
||||
Now, to let the handler know that you are going to use your custom sign in page, you need to setup the url in the `StackServerApp`, which should locate in `lib/stack.ts` if you followed the previous tutorial:
|
||||
|
||||
```tsx
|
||||
import { StackServerApp } from '@stack/next';
|
||||
|
||||
export const stack = new StackServerApp({
|
||||
urls: {
|
||||
signIn: '/signin',
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
You are now all set! If you visit the `/signin` page, you should see your custom sign in page. Also when the user goes to a protected page, stack will automatically redirect you to your custom sign in page.
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Server Usage
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Auth
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# User
|
||||
@ -1,5 +0,0 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Auth
|
||||
@ -13,14 +13,14 @@ const config = {
|
||||
favicon: "img/favicon.ico",
|
||||
|
||||
// Set the production url of your site here
|
||||
url: "https://your-docusaurus-site.example.com",
|
||||
url: "https://docs.stackframe.co",
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: "/",
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: "facebook", // Usually your GitHub org/user name.
|
||||
organizationName: "stackframe-projects", // Usually your GitHub org/user name.
|
||||
projectName: "docusaurus", // Usually your repo name.
|
||||
|
||||
onBrokenLinks: "throw",
|
||||
@ -54,9 +54,6 @@ const config = {
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
prism: {
|
||||
additionalLanguages: ["bash"],
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: "dark",
|
||||
disableSwitch: true,
|
||||
@ -74,7 +71,7 @@ const config = {
|
||||
items: [
|
||||
{
|
||||
type: "docSidebar",
|
||||
sidebarId: "tutorialSidebar",
|
||||
sidebarId: "docsSidebar",
|
||||
position: "left",
|
||||
label: "Documentation",
|
||||
},
|
||||
@ -88,6 +85,7 @@ const config = {
|
||||
prism: {
|
||||
theme: prismThemes.github,
|
||||
darkTheme: prismThemes.dracula,
|
||||
additionalLanguages: ["bash"],
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.1.1",
|
||||
"@docusaurus/preset-classic": "3.1.1",
|
||||
"@docusaurus/plugin-content-docs": "3.1.1",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
|
||||
@ -2,7 +2,35 @@
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
docsSidebar: [
|
||||
{
|
||||
type: 'html',
|
||||
value: 'Getting Started',
|
||||
className: 'sidebar-title',
|
||||
},
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: '01-getting-started',
|
||||
},
|
||||
{
|
||||
type: 'html',
|
||||
value: 'Advanced Guides',
|
||||
className: 'sidebar-title',
|
||||
},
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: '02-advanced-guides',
|
||||
},
|
||||
{
|
||||
type: 'html',
|
||||
value: 'API Documentation',
|
||||
className: 'sidebar-title',
|
||||
},
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: '03-api-documentation',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default sidebars;
|
||||
|
||||
@ -23,3 +23,17 @@ html[data-theme='dark'] {
|
||||
.prism-code {
|
||||
background-color: rgb(15,23,42,50) !important;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 0.7rem;
|
||||
font-weight: bold;
|
||||
opacity: 70%;
|
||||
margin-top: 1.5rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.starred > a::before {
|
||||
content: "★";
|
||||
color: #f0d000;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
@ -136,6 +136,9 @@ importers:
|
||||
'@docusaurus/core':
|
||||
specifier: 3.1.1
|
||||
version: 3.1.1(@docusaurus/types@3.1.1)(eslint@8.30.0)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
|
||||
'@docusaurus/plugin-content-docs':
|
||||
specifier: 3.1.1
|
||||
version: 3.1.1(eslint@8.30.0)(react-dom@18.2.0)(react@18.2.0)(typescript@5.3.3)
|
||||
'@docusaurus/preset-classic':
|
||||
specifier: 3.1.1
|
||||
version: 3.1.1(@algolia/client-search@4.22.1)(@types/react@18.2.60)(eslint@8.30.0)(react-dom@18.2.0)(react@18.2.0)(search-insights@2.13.0)(typescript@5.3.3)
|
||||
@ -2217,7 +2220,7 @@ packages:
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
tslib: 2.6.2
|
||||
utility-types: 3.11.0
|
||||
webpack: 5.90.1
|
||||
webpack: 5.90.3
|
||||
transitivePeerDependencies:
|
||||
- '@parcel/css'
|
||||
- '@rspack/core'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user