Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# @zitadel/react Example
# @zitadel/react Quickstart SPA
<p align="center">
<img src="https://raw.githubusercontent.com/zitadel/zitadel/refs/heads/main/docs/static/logos/zitadel-logo-dark%402x.png" alt="Zitadel Logo" max-height="200px" width="auto" />
</p>

Authenticate your [ZITADEL](https://zitadel.com) users within your React applications.

Expand Down Expand Up @@ -71,3 +74,49 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

## Setup Instructions

1. **Log into the Zitadel Customer Portal**
Go to the [Zitadel Customer Portal](https://zitadel.com/admin/dashboard)

2. **Create an Instance**
- Choose a region and create your new instance.

3. **Create a Project**
- Inside your instance, go to Projects -> Create New Project

![App Screenshot](assets/new_project.png)

4. **Create an Application**
- New **"User Agent"**
- Select **"PKCE"**
- Enable **"Development Mode"**
- Configure your **Redirect URI** and **Post Logout URI** (`http://localhost:3000` for local testing)
- Click **"Continue"** and **"Create"**
- Copy the **"Client ID"**

![App Screenshot](assets/new_application.png)

5. **Change your token type to `JWT` in your application settings**

![App Screenshot](assets/token_settings.png)

6. **Configure `ZitadelConfig`**
Open `src/App.tsx` and replace the placeholder values with your application info:

```js
const config: ZitadelConfig = {
authority: "https://CUSTOM_DOMAIN",
client_id: "YOUR_CLIENT_ID",
redirect_uri: "http://localhost:3000/callback",
post_logout_redirect_uri: "http://localhost:3000",
response_type: 'code',
scope: 'openid profile email'
};
```

7. **Run the application**
```bash
yarn start
```
Binary file added assets/new_application.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/new_project.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/token_settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@zitadel/react": "link:./lib",
"bootstrap": "^5.3.8",
"oidc-client-ts": "^2.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.3",
"react-scripts": "5.0.1",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0",
"oidc-client-ts": "^2.4.0"
"web-vitals": "^2.1.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
53 changes: 15 additions & 38 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -1,43 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.

Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css"
integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous" />
<title>Zitadel React Quickstart SPA</title>
<link rel="icon" type="image/x-icon" href="https://zitadel.com/docs/img/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap" rel="stylesheet">
</head>

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</html>
79 changes: 33 additions & 46 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,56 +1,43 @@
.App {
text-align: center;
body {
font-family: 'Lato', sans-serif;
}

.App-logo {
height: 40vmin;
pointer-events: none;
.login-btn {
background-color: #5469D4;
border-color: #5469D4;
color: white;
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
.logout-btn {
background-color:white;
border-color:#d4dae0;
color: #CD3D56;
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
.login-btn:hover,
.login-btn:focus,
.login-btn:active {
background-color: #5469D4 !important;
border-color: #5469D4 !important;
color: white !important;
}

.App-link {
color: #61dafb;
.logout-btn:hover,
.logout-btn:focus,
.logout-btn:active {
background-color: white !important;
border-color: #d4dae0 !important;
color: #CD3D56 !important;
}

button {
padding: 0.5rem 1rem;
background: white;
color: black;
border-radius: 0.5rem;
font-weight: 500;
border: 1px solid #333333;
}

.user {
font-size: 1rem;
}

.user .description {
font-size: 1rem;
margin-bottom: 1rem;
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.jwt-box {
font-family: 'Courier New', Courier, monospace;
white-space: pre-wrap;
background-color: #f8f9fa;
/* Bootstrap light */
padding: 1rem;
border-radius: 0.5rem;
border: 1px solid #dee2e6;
max-width: 100%;
overflow-x: auto;
}
43 changes: 21 additions & 22 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import React, { useEffect, useState } from "react";
import logo from "./logo.svg";
import { useEffect, useState } from "react";
import "./App.css";
import { createZitadelAuth, ZitadelConfig } from "@zitadel/react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Navbar from "./components/Navbar";

import Login from "./components/Login";
import Callback from "./components/Callback";
import JWTContainer from "./components/JWTContainer";

function App() {

const config: ZitadelConfig = {
authority: "",
client_id: "",
authority: "https://CUSTOM_DOMAIN",
client_id: "YOUR_CLIENT_ID",
redirect_uri: "http://localhost:3000/callback",
post_logout_redirect_uri: "http://localhost:3000",
response_type: 'code',
scope: 'openid profile email'
};

const zitadel = createZitadelAuth(config);
Expand All @@ -19,46 +25,39 @@ function App() {
zitadel.authorize();
}

function signout() {
function logout() {
zitadel.signout();
}

const [authenticated, setAuthenticated] = useState<boolean | null>(null);
const [accessToken, setAccessToken] = useState<string | null>(null);
const [idToken, setIdToken] = useState<string | null>(null);

useEffect(() => {
zitadel.userManager.getUser().then((user) => {
if (user) {
setAuthenticated(true);
setAccessToken(user.access_token ?? null);
setIdToken(user.id_token ?? null);
} else {
setAuthenticated(false);
setAccessToken(null);
setIdToken(null);
}
});
}, [zitadel]);

return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Welcome to ZITADEL React</p>

<BrowserRouter>
<Navbar />
<Login authenticated={authenticated} handleLogin={login} handleLogout={logout} />
<JWTContainer accessToken={accessToken} idToken={idToken} />
<Routes>
<Route
path="/"
element={
<Login authenticated={authenticated} handleLogin={login} />
}
/>
<Route
path="/callback"
element={
<Callback
authenticated={authenticated}
setAuth={setAuthenticated}
handleLogout={signout}
userManager={zitadel.userManager}
/>
}
element={<Callback setAuth={setAuthenticated} userManager={zitadel.userManager} />}
/>
</Routes>
</BrowserRouter>
Expand Down
Loading