mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
docs: Improve README for local development and standardize tab usage (#11865)
## Problem statement - `<Tabs>` were not rendered in docs - Missing steps in README for local dev ## How it was solved - Enhance the README to better describe local development setup and clean up formatting. - Standardize the use of tabs across various components for consistency. ## Additional info To not cause merge conflicts with https://github.com/zitadel/zitadel/pull/11729 changes in `/self-hosting/manage/configure/configure.mdx` were skipped
This commit is contained in:
+47
-13
@@ -8,6 +8,12 @@ Ensure you have followed the [root quick start](../../CONTRIBUTING.md#quick-star
|
||||
|
||||
### Local Development
|
||||
|
||||
Ensure all dependencies are installed:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Start the development server:
|
||||
|
||||
```bash
|
||||
@@ -34,17 +40,50 @@ Key scripts for documentation workflows:
|
||||
|
||||
### Validation
|
||||
|
||||
* **Code Quality**: Run `pnpm lint` to check for syntax and style issues in JS/TS/MDX files.
|
||||
* **Content Integrity**: Run `pnpm check:links` to validate content structure, including:
|
||||
* **Code Quality**: Run `pnpm nx run @zitadel/docs:lint` to check for syntax and style issues in JS/TS/MDX files.
|
||||
* **Content Integrity**: Run `pnpm nx run @zitadel/docs:check-links` to validate content structure, including:
|
||||
* Broken internal links
|
||||
* Missing required front-matter (e.g., `title`)
|
||||
* Image references
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
#### Issue: Nx configuration not found or "nx" command not found
|
||||
|
||||
If you see errors like:
|
||||
|
||||
```bash
|
||||
NX Cannot find configuration for task @zitadel/zitadel:@zitadel/docs:generate
|
||||
|
||||
Pass --verbose to see the stacktrace.
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
pnpm nx run @zitadel/docs:dev
|
||||
ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL Command "nx" not found
|
||||
|
||||
Did you mean "pnpm nx"?
|
||||
```
|
||||
|
||||
**Root cause**: Your dependency cache or `node_modules` is out of sync.
|
||||
|
||||
**Solution**: Run these commands from the repository root in order:
|
||||
|
||||
1. **Clear node_modules**: `rm -rf node_modules` — removes the installed dependency folder
|
||||
2. **Clear pnpm cache**: `pnpm cache delete` — clears pnpm's internal package cache
|
||||
3. **Reinstall dependencies**: `pnpm install` — reinstalls all dependencies fresh
|
||||
4. **Test the setup**: `pnpm nx run @zitadel/docs:generate` — verifies everything works
|
||||
|
||||
This resolves 99% of setup-related issues.
|
||||
|
||||
## Contributing
|
||||
|
||||
### Build Process
|
||||
|
||||
The docs build process automatically handling the following steps via `generate`:
|
||||
The docs build process automatically handles the following steps via `generate`:
|
||||
|
||||
1. Downloads required protoc plugins.
|
||||
2. Generates gRPC documentation from proto files.
|
||||
3. Generates API documentation from OpenAPI specs.
|
||||
@@ -52,10 +91,10 @@ The docs build process automatically handling the following steps via `generate`
|
||||
|
||||
### Style Guide
|
||||
|
||||
- **Variables**: Use environment variables in code snippets where possible.
|
||||
- **Embedded Content**: Use `_filename.mdx` for content embedded in other pages (not indexed individually).
|
||||
- **Code Embedding**: Use the `file` property in code blocks to embed code from the repo.
|
||||
- **Voice**: Use active voice and sentence case for titles.
|
||||
* **Variables**: Use environment variables in code snippets where possible.
|
||||
* **Embedded Content**: Use `_filename.mdx` for content embedded in other pages (not indexed individually).
|
||||
* **Code Embedding**: Use the `file` property in code blocks to embed code from the repo.
|
||||
* **Voice**: Use active voice and sentence case for titles.
|
||||
|
||||
Refer to the [Google Developer Style Guide](https://developers.google.com/style) for general guidelines.
|
||||
|
||||
@@ -64,10 +103,10 @@ Refer to the [Google Developer Style Guide](https://developers.google.com/style)
|
||||
All documentation content is located in the `content` directory. Note that the system strictly accepts **only `.mdx` files**.
|
||||
|
||||
To add a new page:
|
||||
|
||||
1. Create a `.mdx` file in the appropriate subdirectory of [`content`](./content).
|
||||
2. Register the new page in the sidebar settings at [`lib/sidebar-data.ts`](./lib/sidebar-data.ts) to make it accessible in the navigation.
|
||||
|
||||
|
||||
### Pull Requests
|
||||
|
||||
Use `docs(<scope>): <short summary>` for PR titles.
|
||||
@@ -75,9 +114,4 @@ Pass quality checks before submitting:
|
||||
|
||||
```bash
|
||||
pnpm nx run @zitadel/docs:build
|
||||
pnpm nx run @zitadel/docs:check:links
|
||||
```
|
||||
|
||||
You can also run specific steps individually:
|
||||
* `pnpm fetch:remote-content`
|
||||
* `pnpm generate:api-reference`
|
||||
|
||||
@@ -63,13 +63,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="token-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'client_secret_post', value: 'client_secret_post'},
|
||||
{label: 'none (PKCE)', value: 'none'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','client_secret_post','none (PKCE)','private_key_jwt']}
|
||||
>
|
||||
<Tab value="client_secret_basic">
|
||||
no additional parameters required
|
||||
@@ -77,7 +72,7 @@ no additional parameters required
|
||||
<Tab value="client_secret_post">
|
||||
no additional parameters required
|
||||
</Tab>
|
||||
<Tab value="none">
|
||||
<Tab value="none (PKCE)">
|
||||
|
||||
| Parameter | Description |
|
||||
| --------------------- | ----------------------------------------------------- |
|
||||
@@ -192,13 +187,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="token-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'client_secret_post', value: 'client_secret_post'},
|
||||
{label: 'none (PKCE)', value: 'none'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','client_secret_post','none (PKCE)','private_key_jwt']}
|
||||
>
|
||||
<Tab value="client_secret_basic">
|
||||
|
||||
@@ -215,7 +205,7 @@ Send your `client_id` and `client_secret` as parameters in the body:
|
||||
| client_secret | client_secret of the application |
|
||||
|
||||
</Tab>
|
||||
<Tab value="none">
|
||||
<Tab value="none (PKCE)">
|
||||
|
||||
Send your `client_id` and `code_verifier` for us to recompute the `code_challenge` of the authorization request.
|
||||
|
||||
@@ -292,13 +282,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="token-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'client_secret_post', value: 'client_secret_post'},
|
||||
{label: 'none (PKCE)', value: 'none'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','client_secret_post','none (PKCE)','private_key_jwt']}
|
||||
>
|
||||
<Tab value="client_secret_basic">
|
||||
|
||||
@@ -315,7 +300,7 @@ Send your `client_id` and `client_secret` as parameters in the body:
|
||||
| client_secret | client_secret of the application |
|
||||
|
||||
</Tab>
|
||||
<Tab value="none">
|
||||
<Tab value="none (PKCE)">
|
||||
|
||||
Send your `client_id` as parameter in the body. No authentication is required.
|
||||
|
||||
@@ -402,13 +387,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="token-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'client_secret_post', value: 'client_secret_post'},
|
||||
{label: 'none', value: 'none'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','client_secret_post','none (PKCE)','private_key_jwt']}
|
||||
>
|
||||
|
||||
<Tab value="client_secret_basic">
|
||||
@@ -426,7 +406,7 @@ Send your `client_id` and `client_secret` as parameters in the body:
|
||||
| client_secret | client_secret of the application |
|
||||
|
||||
</Tab>
|
||||
<Tab value="none">
|
||||
<Tab value="none (PKCE)">
|
||||
|
||||
Send your `client_id` as parameter in the body. No authentication is required.
|
||||
|
||||
@@ -478,11 +458,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="introspect-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','private_key_jwt']}
|
||||
>
|
||||
<Tab value="client_secret_basic">
|
||||
|
||||
@@ -586,13 +563,8 @@ Depending on your authorization method you will have to provide additional param
|
||||
|
||||
<Tabs
|
||||
groupId="token-auth-methods"
|
||||
defaultValue="client_secret_basic"
|
||||
values={[
|
||||
{label: 'client_secret_basic', value: 'client_secret_basic'},
|
||||
{label: 'client_secret_post', value: 'client_secret_post'},
|
||||
{label: 'none (PKCE)', value: 'none'},
|
||||
{label: 'private_key_jwt', value: 'private_key_jwt'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['client_secret_basic','client_secret_post','none (PKCE)','private_key_jwt']}
|
||||
>
|
||||
<Tab value="client_secret_basic">
|
||||
|
||||
@@ -609,7 +581,7 @@ Send your `client_id` and `client_secret` as parameters in the body:
|
||||
| client_secret | client_secret of the application |
|
||||
|
||||
</Tab>
|
||||
<Tab value="none">
|
||||
<Tab value="none (PKCE)">
|
||||
|
||||
Send your `client_id` as parameters in the body:
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ You will need to implement a listener that can receive HTTP requests.
|
||||
For this example, we will use a simple Go HTTP server that will print the received request to standard output.
|
||||
As mentioned before, this validation can and should be applied to any target implementation.
|
||||
|
||||
<Tabs>
|
||||
<Tabs defaultIndex={0} items={['JSON', 'JWT', 'JWE']}>
|
||||
<Tab value="JSON">
|
||||
<DynamicCodeBlock lang="go" code={JsonGo} />
|
||||
</Tab>
|
||||
|
||||
@@ -168,8 +168,12 @@ You can also activate the v2 login for your apps, so users are redirected to `/u
|
||||
|
||||
**Customizing the new login:** The easiest way to actually customizing it is to fork the https://github.com/zitadel/zitadel repo and use the [Deploy with Vercel button](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#login-deploy) to run your login code on Vercel.
|
||||
|
||||
<Tabs queryString="deployment">
|
||||
<Tab value="zitadel_cloud" label="Activate Zitadel Cloud V2 Login" default="true">
|
||||
<Tabs
|
||||
groupId="deployment"
|
||||
defaultIndex={0}
|
||||
items={['Activate Zitadel Cloud V2 Login', 'Vercel Custom Login Deployment']}
|
||||
>
|
||||
<Tab value="Activate Zitadel Cloud V2 Login">
|
||||
|
||||
Zitadel Cloud provides the V2 login at the fixed path `/ui/v2/login`.
|
||||
<PreventLockout components={props.components} />
|
||||
@@ -181,7 +185,7 @@ You can also activate the v2 login for your apps, so users are redirected to `/u
|
||||
2. Enable the [loginV2 feature](/reference/api/feature/zitadel.feature.v2.FeatureService.SetInstanceFeatures) on the instance. Leave the base URI empty to use the default. If you enable this feature, the login will be used for every application configured in your Zitadel instance. (Example: https://your-zitadel-instance.zitadel.cloud/ui/v2/login)
|
||||
|
||||
</Tab>
|
||||
<Tab value="vercel_custom" label="Vercel Custom Login Deployment">
|
||||
<Tab value="Vercel Custom Login Deployment">
|
||||
|
||||
The simplest way to deploy the new login for yourself is by using the [Deploy with Vercel button](https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#login-deploy) to deploy the login directly to your Vercel.
|
||||
|
||||
|
||||
@@ -10,20 +10,16 @@ export default function AuthMethods(props) {
|
||||
<div>
|
||||
<Tabs
|
||||
groupId="auth-type"
|
||||
default="pkce"
|
||||
values={[
|
||||
{ label: "PKCE", value: "pkce" },
|
||||
{ label: "Basic Auth", value: "basic" },
|
||||
{ label: "JWT with Private Key", value: "jwtpk" },
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={["PKCE","Basic Auth","JWT with Private Key"]}
|
||||
>
|
||||
<Tab value="pkce">
|
||||
<Tab value="PKCE">
|
||||
<PKCE components={props.components} />
|
||||
</Tab>
|
||||
<Tab value="basic">
|
||||
<Tab value="Basic Auth">
|
||||
<Basic components={props.components} />
|
||||
</Tab>
|
||||
<Tab value="jwtpk">
|
||||
<Tab value="JWT with Private Key">
|
||||
<JWTPrivateKey components={props.components} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -31,26 +27,23 @@ export default function AuthMethods(props) {
|
||||
) : props.selected == "native" ? (
|
||||
<Tabs
|
||||
groupId="auth-type"
|
||||
default="pkce"
|
||||
values={[{ label: "PKCE", value: "pkce" }]}
|
||||
defaultIndex={0}
|
||||
items={["PKCE"]}
|
||||
>
|
||||
<Tab value="pkce">
|
||||
<Tab value="PKCE">
|
||||
<PKCE components={props.components} Native />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
) : props.selected == "spa" ? (
|
||||
<Tabs
|
||||
groupId="auth-type"
|
||||
default="pkce"
|
||||
values={[
|
||||
{ label: "PKCE", value: "pkce" },
|
||||
{ label: "Implicit", value: "implicit" },
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={["PKCE","Implicit"]}
|
||||
>
|
||||
<Tab value="pkce">
|
||||
<Tab value="PKCE">
|
||||
<PKCE components={props.components} />
|
||||
</Tab>
|
||||
<Tab value="implicit">
|
||||
<Tab value="Implicit">
|
||||
<Implicit components={props.components} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -53,14 +53,10 @@ This will start a wizard asking you for an application name and a type.
|
||||
|
||||
<Tabs
|
||||
groupId="app-type"
|
||||
default="web"
|
||||
values={[
|
||||
{'label': 'Web Application', 'value': 'web'},
|
||||
{'label': 'Native Application', 'value': 'native'},
|
||||
{'label': 'Single Page Application', 'value': 'spa'},
|
||||
]}
|
||||
defaultIndex={0}
|
||||
items={['Web Application','Native Application','Single Page Application']}
|
||||
>
|
||||
<Tab value="web">
|
||||
<Tab value="Web Application">
|
||||
|
||||
#### Authentication method
|
||||
|
||||
@@ -73,7 +69,7 @@ Please change the authentication method here as well, if you did so in the wizar
|
||||
<AuthMethods components={props.components} selected="web" />
|
||||
</Tab>
|
||||
|
||||
<Tab value="native">
|
||||
<Tab value="Native Application">
|
||||
|
||||
#### Authentication method
|
||||
|
||||
@@ -82,7 +78,7 @@ When selecting Native the authentication method always needs to be PKCE.
|
||||
<AuthMethods components={props.components} selected="native" />
|
||||
</Tab>
|
||||
|
||||
<Tab value="spa">
|
||||
<Tab value="Single Page Application">
|
||||
|
||||
#### Authentication method
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ If you started with Zitadel before version 3, you might have the "Human User [de
|
||||
In this case please enable the Feature Flag "Use V2 Api in Management Console for User creation" in the Default Settings.
|
||||
</Callout>
|
||||
|
||||
<Tabs>
|
||||
<Tab value="human" label="Human User" default>
|
||||
<Tabs groupId="create-user-types" defaultIndex={0} items={['Human User', 'Human User [deprecated]', 'Service Account']}>
|
||||
<Tab value="Human User">
|
||||
<img src="/docs/img/guides/console/invitehuman.png" width="680px" alt="Invite Human" />
|
||||
|
||||
When creating a new user you have different options.
|
||||
@@ -21,7 +21,7 @@ In this case please enable the Feature Flag "Use V2 Api in Management Console fo
|
||||
- **Set an initial password for the user**: The user will receive an email and be able to setup an authentication method (e.g Password, Passkey, External SSO)
|
||||
|
||||
</Tab>
|
||||
<Tab value="human_deprecated" label="Human User [deprecated]">
|
||||
<Tab value="Human User [deprecated]">
|
||||
<img src="/docs/img/guides/console/addhuman.png" width="680px" alt="Add Human" />
|
||||
|
||||
After a user is created, by default, an initialization mail with a code is sent to the registered email. This code then has to be verified on first login.
|
||||
@@ -29,7 +29,7 @@ In this case please enable the Feature Flag "Use V2 Api in Management Console fo
|
||||
If no password is set initially, the initialization mail prompting the user to set his password is sent.
|
||||
|
||||
</Tab>
|
||||
<Tab value="service" label="Service Account">
|
||||
<Tab value="Service Account">
|
||||
<img
|
||||
src="/docs/img/guides/console/addmachine.png"
|
||||
width="540px"
|
||||
|
||||
@@ -39,8 +39,8 @@ A provider with HTTP type will send the messages and the data to a pre-defined w
|
||||
|
||||
### Configuring a HTTP provider
|
||||
|
||||
<Tabs>
|
||||
<Tab value="sms" label="SMS" default>
|
||||
<Tabs groupId="http-provider-configuration" defaultIndex={0} items={['SMS', 'Email']}>
|
||||
<Tab value="SMS">
|
||||
|
||||
First [add a new SMS Provider of type HTTP](/reference/api/admin/zitadel.admin.v1.AdminService.AddSMSProviderHTTP) to create a new HTTP provider that can be used to send SMS messages:
|
||||
|
||||
@@ -74,7 +74,7 @@ A provider with HTTP type will send the messages and the data to a pre-defined w
|
||||
See full API reference for [SMS Providers](/reference/api/admin) for more details.
|
||||
|
||||
</Tab>
|
||||
<Tab value="email" label="Email">
|
||||
<Tab value="Email">
|
||||
|
||||
First [add a new Email Provider of type HTTP](/reference/api/admin/zitadel.admin.v1.AdminService.AddEmailProviderHTTP) to create a new HTTP provider that can be used to send Email messages:
|
||||
|
||||
|
||||
@@ -169,11 +169,11 @@ Topics of the onboarding term may include
|
||||
- Migration
|
||||
- Security Best Practices & Go-Live Checkup
|
||||
|
||||
<Tabs>
|
||||
<Tab value="in" label="Topics in scope">
|
||||
<Tabs groupId="covered-topics" defaultIndex={1} items={['Topics in scope', 'Topics out of scope']}>
|
||||
<Tab value="Topics in scope">
|
||||
<ul>
|
||||
<li>Instance Settings</li>
|
||||
<li>Walk-though all features</li>
|
||||
<li>Walk-through all features</li>
|
||||
<li>Users / Manuals</li>
|
||||
<li>Authentication & Management APIs</li>
|
||||
<li>Validation of tokens</li>
|
||||
@@ -189,7 +189,7 @@ Topics of the onboarding term may include
|
||||
<li>Functional testing of the ZITADEL instance</li>
|
||||
</ul>
|
||||
</Tab>
|
||||
<Tab value="out" label="Topics out of scope" default>
|
||||
<Tab value="Topics out of scope">
|
||||
<ul>
|
||||
<li>Performance testing</li>
|
||||
<li>Setting up or maintaining backup storage</li>
|
||||
|
||||
Reference in New Issue
Block a user