mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 20:17:23 +00:00
docs: update nextjs and angular guide (#4633)
* docs: nextjs angular guide * colormode
This commit is contained in:
parent
8f694accce
commit
92eeb68be9
@ -1,3 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
presets: [require.resolve("@docusaurus/core/lib/babel/preset")],
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@ It shows how to add user login to your application and fetch some data from the
|
|||||||
|
|
||||||
At the end of the guide, your application has login functionality and has access to the current user's profile.
|
At the end of the guide, your application has login functionality and has access to the current user's profile.
|
||||||
|
|
||||||
> This documentation refers to our [example](https://github.com/zitadel/zitadel-examples/tree/main/angular) in GitHub. Note that we've written ZITADEL Console in Angular, so you can also use that as a reference.
|
> This documentation refers to our [example](https://github.com/zitadel/zitadel-angular) in GitHub. Note that we've written ZITADEL Console in Angular, so you can also use that as a reference.
|
||||||
|
|
||||||
## Setup Application and Get Keys
|
## Setup Application and Get Keys
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ We recommend you use [Authorization Code](../../apis/openidoauth/grant-types#aut
|
|||||||
|
|
||||||
With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI.
|
With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI.
|
||||||
|
|
||||||
> If you are following along with the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular), set dev mode to `true` and the Redirect URIs to <http://localhost:4200/auth/callback>.
|
> If you are following along with the [example](https://github.com/zitadel/zitadel-angular), set dev mode to `true` and the Redirect URIs to <http://localhost:4200/auth/callback>.
|
||||||
|
|
||||||
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the Post Logout URIs field.
|
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the Post Logout URIs field.
|
||||||
|
|
||||||
@ -48,34 +48,8 @@ npm install angular-oauth2-oidc
|
|||||||
|
|
||||||
Add _OAuthModule_ to your Angular imports in _AppModule_ and provide the _AuthConfig_ in the providers' section. Also, ensure you import the _HTTPClientModule_.
|
Add _OAuthModule_ to your Angular imports in _AppModule_ and provide the _AuthConfig_ in the providers' section. Also, ensure you import the _HTTPClientModule_.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
...
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts
|
||||||
import { AuthConfig, OAuthModule } from 'angular-oauth2-oidc';
|
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
|
||||||
|
|
||||||
const authConfig: AuthConfig = {
|
|
||||||
scope: 'openid profile email',
|
|
||||||
responseType: 'code',
|
|
||||||
oidc: true,
|
|
||||||
clientId: 'YOUR-CLIENT-ID', // replace with your appid
|
|
||||||
issuer: 'https:/[your-domain]-[random-string].zitadel.cloud', // replace with your instance
|
|
||||||
redirectUri: 'http://localhost:4200/auth/callback',
|
|
||||||
postLogoutRedirectUri: 'http://localhost:4200/signedout', // optional
|
|
||||||
requireHttps: false // required for running locally
|
|
||||||
};
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
...
|
|
||||||
imports: [
|
|
||||||
OAuthModule.forRoot(),
|
|
||||||
HttpClientModule,
|
|
||||||
...
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: AuthConfig,
|
|
||||||
useValue: authConfig
|
|
||||||
}
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Set _openid_, _profile_ and _email_ as scope, _code_ as responseType, and oidc to _true_. Then create an authentication service to provide the functions to authenticate your user.
|
Set _openid_, _profile_ and _email_ as scope, _code_ as responseType, and oidc to _true_. Then create an authentication service to provide the functions to authenticate your user.
|
||||||
@ -88,103 +62,25 @@ ng g service services/authentication
|
|||||||
|
|
||||||
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Make sure both correspond, otherwise ZITADEL throws an error.
|
Copy the following code to your service. This code provides a function `authenticate()` which redirects the user to ZITADEL. After successful login, ZITADEL redirects the user back to the redirect URI configured in _AuthModule_ and ZITADEL Console. Make sure both correspond, otherwise ZITADEL throws an error.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import { Injectable } from "@angular/core";
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/services/authentication.service.ts
|
||||||
import { AuthConfig, OAuthService } from "angular-oauth2-oidc";
|
|
||||||
import { BehaviorSubject, from, Observable } from "rxjs";
|
|
||||||
|
|
||||||
import { StatehandlerService } from "./statehandler.service";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: "root",
|
|
||||||
})
|
|
||||||
export class AuthenticationService {
|
|
||||||
private _authenticated: boolean = false;
|
|
||||||
private readonly _authenticationChanged: BehaviorSubject<boolean> =
|
|
||||||
new BehaviorSubject(this.authenticated);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private oauthService: OAuthService,
|
|
||||||
private authConfig: AuthConfig,
|
|
||||||
private statehandler: StatehandlerService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public get authenticated(): boolean {
|
|
||||||
return this._authenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get authenticationChanged(): Observable<boolean> {
|
|
||||||
return this._authenticationChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getOIDCUser(): Observable<any> {
|
|
||||||
return from(this.oauthService.loadUserProfile());
|
|
||||||
}
|
|
||||||
|
|
||||||
public async authenticate(setState: boolean = true): Promise<boolean> {
|
|
||||||
this.oauthService.configure(this.authConfig);
|
|
||||||
|
|
||||||
this.oauthService.strictDiscoveryDocumentValidation = false;
|
|
||||||
await this.oauthService.loadDiscoveryDocumentAndTryLogin();
|
|
||||||
|
|
||||||
this._authenticated = this.oauthService.hasValidAccessToken();
|
|
||||||
|
|
||||||
if (!this.oauthService.hasValidIdToken() || !this.authenticated) {
|
|
||||||
const newState = setState
|
|
||||||
? await this.statehandler.createState().toPromise()
|
|
||||||
: undefined;
|
|
||||||
this.oauthService.initCodeFlow(newState);
|
|
||||||
}
|
|
||||||
this._authenticationChanged.next(this.authenticated);
|
|
||||||
|
|
||||||
return this.authenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public signout(): void {
|
|
||||||
this.oauthService.logOut();
|
|
||||||
this._authenticated = false;
|
|
||||||
this._authenticationChanged.next(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Our example includes a _StatehandlerService_ to redirect the user back to the route where he initially came from.
|
Our example includes a _StatehandlerService_ to redirect the user back to the route where he initially came from.
|
||||||
If you don't need such behavior, you can omit the following line from the `authenticate()` method above.
|
If you don't need such behavior, you can omit the following line from the `authenticate()` method above.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
...
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/services/authentication.service.ts#L45
|
||||||
const newState = setState ? await this.statehandler.createState().toPromise() : undefined;
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you decide to use the _StatehandlerService_, provide it in the `app.module`. Make sure it gets initialized first using Angular’s `APP_INITIALIZER`. You find the service implementation in the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular).
|
If you decide to use the _StatehandlerService_, provide it in the `app.module`. Make sure it gets initialized first using Angular’s `APP_INITIALIZER`. You find the service implementation in the [example](https://github.com/zitadel/zitadel-angular).
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts#L26-L30
|
||||||
|
```
|
||||||
|
|
||||||
const stateHandlerFn = (stateHandler: StatehandlerService) => {
|
```ts reference
|
||||||
return () => {
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/app.module.ts#L55-L78
|
||||||
return stateHandler.initStateHandler();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
...
|
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
useFactory: stateHandlerFn,
|
|
||||||
multi: true,
|
|
||||||
deps: [StatehandlerService],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: StatehandlerProcessorService,
|
|
||||||
useClass: StatehandlerProcessorServiceImpl,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: StatehandlerService,
|
|
||||||
useClass: StatehandlerServiceImpl,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add Login to Your Application
|
### Add Login to Your Application
|
||||||
@ -213,77 +109,28 @@ ng g guard guards/auth
|
|||||||
|
|
||||||
This code shows the _AuthGuard_ used in ZITADEL Console.
|
This code shows the _AuthGuard_ used in ZITADEL Console.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import { Injectable } from "@angular/core";
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/guards/auth.guard.ts
|
||||||
import {
|
|
||||||
ActivatedRouteSnapshot,
|
|
||||||
CanActivate,
|
|
||||||
RouterStateSnapshot,
|
|
||||||
UrlTree,
|
|
||||||
} from "@angular/router";
|
|
||||||
import { Observable } from "rxjs";
|
|
||||||
import { AuthenticationService } from "../services/authentication.service";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: "root",
|
|
||||||
})
|
|
||||||
export class AuthGuard implements CanActivate {
|
|
||||||
constructor(private auth: AuthenticationService) {}
|
|
||||||
|
|
||||||
canActivate(
|
|
||||||
route: ActivatedRouteSnapshot,
|
|
||||||
state: RouterStateSnapshot
|
|
||||||
):
|
|
||||||
| Observable<boolean | UrlTree>
|
|
||||||
| Promise<boolean | UrlTree>
|
|
||||||
| boolean
|
|
||||||
| UrlTree {
|
|
||||||
if (!this.auth.authenticated) {
|
|
||||||
return this.auth.authenticate();
|
|
||||||
}
|
|
||||||
return this.auth.authenticated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Add the guard to your _RouterModule_ similar to this:
|
Add the guard to your _RouterModule_ similar to this:
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
...
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/app-routing.module.ts#L9-L31
|
||||||
const routes: Routes = [
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
|
|
||||||
canActivate: [AuthGuard],
|
|
||||||
},
|
|
||||||
...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: Make sure you redirect the user from your callback URL to a guarded page, so `authenticate()` is called again and the access token is stored.
|
> Note: Make sure you redirect the user from your callback URL to a guarded page, so `authenticate()` is called again and the access token is stored.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
...
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/app-routing.module.ts#L19-L21
|
||||||
{
|
|
||||||
path: 'auth/callback',
|
|
||||||
redirectTo: 'user',
|
|
||||||
},
|
|
||||||
....
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Add Logout to Your Application
|
### Add Logout to Your Application
|
||||||
|
|
||||||
Call `auth.signout()` for logging the current user out. Note that you can also configure a logout redirect URI if you want your users to be redirected after logout.
|
Call `auth.signout()` for logging the current user out. Note that you can also configure a logout redirect URI if you want your users to be redirected after logout.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import { AuthenticationService } from "src/app/services/authentication.service";
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/components/user/user.component.ts#L20-L22
|
||||||
|
|
||||||
export class SomeComponentWithLogout {
|
|
||||||
constructor(private authService: AuthenticationService) {}
|
|
||||||
|
|
||||||
public signout(): Promise<void> {
|
|
||||||
return this.authService.signout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Show User Information
|
### Show User Information
|
||||||
@ -291,29 +138,21 @@ export class SomeComponentWithLogout {
|
|||||||
To fetch user data, ZITADEL's user info endpoint has to be called. This data contains sensitive information and artifacts related to the current user's identity and the scopes you defined in your _AuthConfig_.
|
To fetch user data, ZITADEL's user info endpoint has to be called. This data contains sensitive information and artifacts related to the current user's identity and the scopes you defined in your _AuthConfig_.
|
||||||
Our _AuthenticationService_ already includes a method called _getOIDCUser()_. You can call it wherever you need this information.
|
Our _AuthenticationService_ already includes a method called _getOIDCUser()_. You can call it wherever you need this information.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import { AuthenticationService } from 'src/app/services/authentication.service';
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/components/user/user.component.ts
|
||||||
|
|
||||||
public user$: Observable<any>;
|
|
||||||
|
|
||||||
constructor(private auth: AuthenticationService) {
|
|
||||||
this.user$ = this.auth.getOIDCUser();
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
And in your HTML file:
|
And in your HTML file:
|
||||||
|
|
||||||
```html
|
```html reference
|
||||||
<div *ngIf="user$ | async as user">
|
https://github.com/zitadel/zitadel-angular/blob/main/src/app/components/user/user.component.html
|
||||||
<p>{{user | json}}</p>
|
|
||||||
</div>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Completion
|
## Completion
|
||||||
|
|
||||||
You have successfully integrated your Angular application with ZITADEL!
|
You have successfully integrated your Angular application with ZITADEL!
|
||||||
|
|
||||||
If you get stuck, consider checking out our [example](https://github.com/zitadel/zitadel-examples/tree/main/angular) application. It includes all the mentioned functionality of this quickstart. You can simply start by cloning the repository and replacing the _AuthConfig_ in the _AppModule_ by your own configuration. If you run into issues, contact us or raise an issue on [GitHub](https://github.com/zitadel/zitadel).
|
If you get stuck, consider checking out our [example](https://github.com/zitadel/zitadel-angular) application. It includes all the mentioned functionality of this quickstart. You can simply start by cloning the repository and replacing the _AuthConfig_ in the _AppModule_ by your own configuration. If you run into issues, contact us or raise an issue on [GitHub](https://github.com/zitadel/zitadel).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ npx create-next-app --typescript
|
|||||||
yarn create next-app --typescript
|
yarn create next-app --typescript
|
||||||
```
|
```
|
||||||
|
|
||||||
# Install Authentication library
|
### Install Authentication library
|
||||||
|
|
||||||
To keep the template as easy as possible we use [next-auth](https://next-auth.js.org/) as our main authentication library. To install, run:
|
To keep the template as easy as possible we use [next-auth](https://next-auth.js.org/) as our main authentication library. To install, run:
|
||||||
|
|
||||||
@ -34,25 +34,42 @@ npm run dev
|
|||||||
|
|
||||||
then open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
then open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
# Configuration
|
## Setup Application and Get Keys
|
||||||
|
|
||||||
|
Before we can start building our application, we have to do a few configuration steps in ZITADEL Console.
|
||||||
|
You will need to provide some information about your app.
|
||||||
|
Navigate to your Project, then add a new application at the top of the page.
|
||||||
|
Select Web application type and continue.
|
||||||
|
We recommend you use [Authorization Code](../../apis/openidoauth/grant-types#authorization-code) in combination with [Proof Key for Code Exchange (PKCE)](../../apis/openidoauth/grant-types#proof-key-for-code-exchange) for all web applications.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Redirect URIs
|
||||||
|
|
||||||
|
With the Redirect URIs field, you tell ZITADEL where it is allowed to redirect users to after authentication. For development, you can set dev mode to `true` to enable insecure HTTP and redirect to a `localhost` URI.
|
||||||
|
|
||||||
|
> If you are following along with the [example](https://github.com/zitadel/zitadel-examples/tree/main/angular), set dev mode to `true` and the Redirect URIs to <http://localhost:300/api/auth/callback/zitadel>.
|
||||||
|
|
||||||
|
If you want to redirect the users back to a route on your application after they have logged out, add an optional redirect in the Post Logout URIs field.
|
||||||
|
|
||||||
|
Continue and create the application.
|
||||||
|
|
||||||
|
### Client ID
|
||||||
|
|
||||||
|
After successful app creation, a pop-up will appear, showing the app's client ID. Copy the client ID, as you will need it to configure your NextJS app.
|
||||||
|
|
||||||
|
## NextJS Setup
|
||||||
|
|
||||||
|
Now that you have your web application configured on the ZITADEL side, you can go ahead and integrate your NextJS app.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
NextAuth.js exposes a REST API which is used by your client.
|
NextAuth.js exposes a REST API which is used by your client.
|
||||||
To setup your configuration, create a file called [...nextauth].tsx in `pages/api/auth`.
|
To setup your configuration, create a file called [...nextauth].tsx in `pages/api/auth`.
|
||||||
You can directly import the ZITADEL provider from [next-auth](https://next-auth.js.org/providers/zitadel).
|
You can directly import the ZITADEL provider from [next-auth](https://next-auth.js.org/providers/zitadel).
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import NextAuth from "next-auth";
|
https://github.com/zitadel/zitadel-nextjs/blob/main/pages/api/auth/%5B...nextauth%5D.tsx
|
||||||
import ZitadelProvider from "next-auth/providers/zitadel";
|
|
||||||
|
|
||||||
export default NextAuth({
|
|
||||||
providers: [
|
|
||||||
ZitadelProvider({
|
|
||||||
issuer: process.env.ZITADEL_ISSUER,
|
|
||||||
clientId: process.env.ZITADEL_CLIENT_ID,
|
|
||||||
clientSecret: process.env.ZITADEL_CLIENT_SECRET,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can overwrite the default callbacks, just append them to the ZITADEL provider.
|
You can overwrite the default callbacks, just append them to the ZITADEL provider.
|
||||||
@ -89,81 +106,41 @@ Hit Create, then in the detail view of your application make sure to enable dev
|
|||||||
|
|
||||||
Now go to Token settings and check the checkbox for **User Info inside ID Token** to get your users name directly on authentication.
|
Now go to Token settings and check the checkbox for **User Info inside ID Token** to get your users name directly on authentication.
|
||||||
|
|
||||||
## Environment
|
### Environment
|
||||||
|
|
||||||
Create a file `.env` in the root of the project and add the following keys to it.
|
Create a file `.env` in the root of the project and add the following keys to it.
|
||||||
You can find your Issuer Url on the application detail page in console.
|
You can find your Issuer Url on the application detail page in console.
|
||||||
|
|
||||||
```
|
```env reference
|
||||||
NEXTAUTH_URL=http://localhost:3000
|
https://github.com/zitadel/zitadel-nextjs/blob/main/.env
|
||||||
ZITADEL_ISSUER=[yourIssuerUrl]
|
|
||||||
ZITADEL_CLIENT_ID=[yourClientId]
|
|
||||||
ZITADEL_CLIENT_SECRET=[randomvalue]
|
|
||||||
NEXTAUTH_SECRET=[randomvalue]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
next-auth requires a secret for all providers, so just define a random value here.
|
next-auth requires a secret for all providers, so just define a random value here.
|
||||||
|
|
||||||
# User interface
|
### User interface
|
||||||
|
|
||||||
Now we can start editing the homepage by modifying `pages/index.tsx`.
|
Now we can start editing the homepage by modifying `pages/index.tsx`. On the homepage, your authenticated user or a Signin button is shown.
|
||||||
Add this snippet your file. This code gets your auth session from next-auth, renders a Logout button if your authenticated or shows a Signup button if your not.
|
|
||||||
Note that signIn method requires the id of the provider we provided earlier, and provides a possibilty to add a callback url, Auth Next will redirect you to the specified route if logged in successfully.
|
|
||||||
|
|
||||||
```ts
|
Add the following component to render the UI elements:
|
||||||
import { signIn, signOut, useSession } from 'next-auth/client';
|
|
||||||
|
|
||||||
export default function Page() {
|
```ts reference
|
||||||
const { data: session } = useSession();
|
|
||||||
...
|
https://github.com/zitadel/zitadel-nextjs/blob/main/components/profile.tsx#L4-L38
|
||||||
{!session && <>
|
|
||||||
Not signed in <br />
|
|
||||||
<button onClick={() => signIn('zitadel', { callbackUrl: 'http://localhost:3000/profile' })}>
|
|
||||||
Sign in
|
|
||||||
</button>
|
|
||||||
</>}
|
|
||||||
{session && <>
|
|
||||||
Signed in as {session.user.email} <br />
|
|
||||||
<button onClick={() => signOut()}>Sign out</button>
|
|
||||||
</>}
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that the signIn method requires the id of our provider which is in our case `zitadel`.
|
||||||
|
|
||||||
### Session state
|
### Session state
|
||||||
|
|
||||||
To allow session state to be shared between pages - which improves performance, reduces network traffic and avoids component state changes while rendering - you can use the NextAuth.js Provider in `/pages/_app.tsx`.
|
To allow session state to be shared between pages - which improves performance, reduces network traffic and avoids component state changes while rendering - you can use the NextAuth.js Provider in `/pages/_app.tsx`.
|
||||||
Take a loot at the template `_app.tsx`.
|
Take a loot at the template `_app.tsx`.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import { SessionProvider } from "next-auth/react";
|
https://github.com/zitadel/zitadel-nextjs/blob/main/pages/_app.tsx
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }) {
|
|
||||||
return (
|
|
||||||
<SessionProvider session={pageProps.session}>
|
|
||||||
<Component {...pageProps} />
|
|
||||||
</SessionProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MyApp;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Last thing: create a `profile.tsx` in /pages which renders the callback page.
|
Last thing: create a `profile.tsx` in /pages which renders the callback page.
|
||||||
|
|
||||||
```ts
|
```ts reference
|
||||||
import Link from "next/link";
|
https://github.com/zitadel/zitadel-nextjs/blob/main/pages/profile.tsx
|
||||||
|
|
||||||
import styles from "../styles/Home.module.css";
|
|
||||||
|
|
||||||
export default function Profile() {
|
|
||||||
return (
|
|
||||||
<div className={styles.container}>
|
|
||||||
<h1>Login successful</h1>
|
|
||||||
<Link href="/">
|
|
||||||
<button>Back to Home</button>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
@ -20,13 +20,13 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
zoom: {
|
zoom: {
|
||||||
selector: '.markdown :not(em) > img',
|
selector: ".markdown :not(em) > img",
|
||||||
background: {
|
background: {
|
||||||
light: 'rgb(243, 244, 246)',
|
light: "rgb(243, 244, 246)",
|
||||||
dark: 'rgb(55, 59, 82)'
|
dark: "rgb(55, 59, 82)",
|
||||||
},
|
},
|
||||||
// options you can specify via https://github.com/francoischalifour/medium-zoom#usage
|
// options you can specify via https://github.com/francoischalifour/medium-zoom#usage
|
||||||
config: {}
|
config: {},
|
||||||
},
|
},
|
||||||
navbar: {
|
navbar: {
|
||||||
// title: 'ZITADEL',
|
// title: 'ZITADEL',
|
||||||
@ -119,7 +119,6 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
title: "Legal",
|
title: "Legal",
|
||||||
items: [
|
items: [
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "Terms and Conditions",
|
label: "Terms and Conditions",
|
||||||
href: "/docs/legal/terms-of-service",
|
href: "/docs/legal/terms-of-service",
|
||||||
@ -152,22 +151,26 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
label: "Docs v1 (deprecated)",
|
label: "Docs v1 (deprecated)",
|
||||||
href: "https://docs-v1.zitadel.com/",
|
href: "https://docs-v1.zitadel.com/",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
copyright: `Copyright © ${new Date().getFullYear()} ZITADEL Docs - Built with Docusaurus.`,
|
copyright: `Copyright © ${new Date().getFullYear()} ZITADEL Docs - Built with Docusaurus.`,
|
||||||
},
|
},
|
||||||
algolia: {
|
algolia: {
|
||||||
appId: "8H6ZKXENLO",
|
appId: "8H6ZKXENLO",
|
||||||
apiKey: "124fe1c102a184bc6fc70c75dc84f96f",
|
apiKey: "124fe1c102a184bc6fc70c75dc84f96f",
|
||||||
indexName: 'zitadel',
|
indexName: "zitadel",
|
||||||
selector: 'div#'
|
selector: "div#",
|
||||||
},
|
},
|
||||||
prism: {
|
prism: {
|
||||||
additionalLanguages: ["csharp", "dart", "groovy", "regex"],
|
additionalLanguages: ["csharp", "dart", "groovy", "regex"],
|
||||||
},
|
},
|
||||||
|
colorMode: {
|
||||||
|
defaultMode: "dark",
|
||||||
|
disableSwitch: false,
|
||||||
|
respectPrefersColorScheme: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
presets: [
|
presets: [
|
||||||
[
|
[
|
||||||
@ -187,4 +190,5 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
plugins: [require.resolve("docusaurus-plugin-image-zoom")],
|
plugins: [require.resolve("docusaurus-plugin-image-zoom")],
|
||||||
|
themes: ["@saucelabs/theme-github-codeblock"],
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
"@leichtgewicht/ip-codec": "2.0.4",
|
"@leichtgewicht/ip-codec": "2.0.4",
|
||||||
"@mdx-js/mdx": "1.6.22",
|
"@mdx-js/mdx": "1.6.22",
|
||||||
"@mdx-js/react": "^1.6.22",
|
"@mdx-js/react": "^1.6.22",
|
||||||
|
"@saucelabs/theme-github-codeblock": "^0.1.1",
|
||||||
"@slorber/static-site-generator-webpack-plugin": "4.0.4",
|
"@slorber/static-site-generator-webpack-plugin": "4.0.4",
|
||||||
"@svgr/core": "6.2.1",
|
"@svgr/core": "6.2.1",
|
||||||
"@svgr/hast-util-to-babel-ast": "6.2.1",
|
"@svgr/hast-util-to-babel-ast": "6.2.1",
|
||||||
@ -159,6 +160,7 @@
|
|||||||
"stylehacks": "5.1.0",
|
"stylehacks": "5.1.0",
|
||||||
"terser-webpack-plugin": "5.3.1",
|
"terser-webpack-plugin": "5.3.1",
|
||||||
"type-fest": "2.12.2",
|
"type-fest": "2.12.2",
|
||||||
|
"url": "^0.11.0",
|
||||||
"wait-on": "6.0.1",
|
"wait-on": "6.0.1",
|
||||||
"webpack-bundle-analyzer": "4.5.0",
|
"webpack-bundle-analyzer": "4.5.0",
|
||||||
"webpack-dev-middleware": "5.3.1",
|
"webpack-dev-middleware": "5.3.1",
|
||||||
|
@ -131,6 +131,10 @@
|
|||||||
--ifm-pagination-nav-color-hover: #000000;
|
--ifm-pagination-nav-color-hover: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.get-started {
|
.get-started {
|
||||||
border-radius: 50vw;
|
border-radius: 50vw;
|
||||||
}
|
}
|
||||||
|
BIN
docs/static/img/nextjs/app-create.png
vendored
Normal file
BIN
docs/static/img/nextjs/app-create.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 259 KiB |
@ -2007,6 +2007,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
|
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
|
||||||
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
|
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
|
||||||
|
|
||||||
|
"@saucelabs/theme-github-codeblock@^0.1.1":
|
||||||
|
version "0.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@saucelabs/theme-github-codeblock/-/theme-github-codeblock-0.1.1.tgz#d2caa3fbf56c38ae2fe974871f1188226bb57d92"
|
||||||
|
integrity sha512-iHzODYjcUAYI4eJzLrNCw/Iq9SWxCKB/cMgEKHjRmNMb2NKch1dsI2ZSCg8lNedIPmOaRfqHT29hLyMoc/5Wpg==
|
||||||
|
|
||||||
"@sideway/address@^4.1.3":
|
"@sideway/address@^4.1.3":
|
||||||
version "4.1.4"
|
version "4.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
|
||||||
@ -7140,6 +7145,11 @@ pump@^3.0.0:
|
|||||||
end-of-stream "^1.1.0"
|
end-of-stream "^1.1.0"
|
||||||
once "^1.3.1"
|
once "^1.3.1"
|
||||||
|
|
||||||
|
punycode@1.3.2:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||||
|
integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
|
||||||
|
|
||||||
punycode@^1.3.2:
|
punycode@^1.3.2:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||||
@ -7169,6 +7179,11 @@ qs@6.10.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
side-channel "^1.0.4"
|
side-channel "^1.0.4"
|
||||||
|
|
||||||
|
querystring@0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||||
|
integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==
|
||||||
|
|
||||||
queue-microtask@^1.2.2:
|
queue-microtask@^1.2.2:
|
||||||
version "1.2.3"
|
version "1.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
@ -8515,6 +8530,14 @@ url-parse-lax@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prepend-http "^2.0.0"
|
prepend-http "^2.0.0"
|
||||||
|
|
||||||
|
url@^0.11.0:
|
||||||
|
version "0.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||||
|
integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==
|
||||||
|
dependencies:
|
||||||
|
punycode "1.3.2"
|
||||||
|
querystring "0.2.0"
|
||||||
|
|
||||||
use-composed-ref@^1.3.0:
|
use-composed-ref@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda"
|
resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user