docs: fix code block styling by migrating to native fumadocs-ui components (#11646)

# Which Problems Are Solved

- Docs code blocks that display imported files (YAML configs, Go
examples) render as unstyled plain text with no syntax highlighting,
unlike fenced code blocks which go through `rehypeCode`/Shiki

# How the Problems Are Solved

- Deleted `components/docusaurus/code-block.tsx` entirely — no custom
wrapper is needed anymore
- Replaced all usages with `DynamicCodeBlock` from
`fumadocs-ui/components/dynamic-codeblock` directly in MDX files; it
handles SSR pre-rendering through the same Shiki pipeline as all other
code blocks
- Raw file content (YAML, Go) is imported as strings via webpack's
existing `asset/source` rule already configured in `next.config.mjs` —
no new infrastructure required
- In `_proxy_guide_tls_mode.mdx`, the `Commands` JSX component was
refactored from concatenated JSX array children to a single template
literal string, which is what `DynamicCodeBlock` (and any string-based
highlighter) requires
- All changes applied to both non-versioned docs and versioned snapshots
(v4.10, v4.11)

# Additional Changes

None.

# Additional Context

- Affected MDX files: YAML config files under
`self-hosting/manage/configure/`, reverse-proxy guides,
`self-hosting/deploy/compose.mdx`, and the actions
`testing-request-signature.mdx` guide

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>code block style is weird</issue_title>
> <issue_description>### Preflight Checklist
> 
> - [x] I could not find a solution in the existing issues, docs, nor
discussions
> - [x] I have joined the [ZITADEL chat](https://zitadel.com/chat)
> 
> ### Describe the docs your are missing or that are wrong
> 
> This hurts my eyes:
> 
> <img width="867" height="525" alt="Image"
src="https://github.com/user-attachments/assets/b7b66d92-56e1-4e0a-8dba-3cab448930fe"
/>
> 
> ### Additional Context
> 
> _No response_</issue_description>
> 
> <agent_instructions>the user reported a weirdly styled code block in
the docs page where we used to display yaml files. Investigate the docs
and fix the styling</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@fforootd</author><body>
> haha, ok that is certainly weird, let me look at
that.</body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes zitadel/zitadel#11645

<!-- START COPILOT CODING AGENT TIPS -->

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: fforootd <[email protected]>
Co-authored-by: Florian Forster <[email protected]>
This commit is contained in:
Copilot
2026-02-20 06:46:32 +05:30
committed by GitHub
co-authored by copilot-swe-agent[bot] <198982749+[email protected]> fforootd Florian Forster
parent e25220bfab
commit 545e2665f3
8 changed files with 65 additions and 83 deletions
@@ -1,14 +0,0 @@
import React from 'react';
export default function CodeBlock({ children, language, title, className, showLineNumbers: _showLineNumbers }: any) {
return (
<div className="my-4">
{title && <div className="bg-secondary text-secondary-foreground px-4 py-2 text-sm font-medium rounded-t-md">{title}</div>}
<pre className={`p-4 overflow-x-auto bg-secondary/50 rounded-b-md ${title ? 'rounded-t-none' : 'rounded-md'} ${className || ''}`}>
<code className={language ? `language-${language}` : ''}>
{children}
</code>
</pre>
</div>
);
}
@@ -2,10 +2,10 @@
title: Verify Payload Integrity
---
import JSONCode from "./go/json.go";
import JWTCode from "./go/jwt.go";
import JWECode from "./go/jwe.go";
import CodeBlock from "@/components/docusaurus/code-block";
import JsonGo from './go/json.go';
import JwtGo from './go/jwt.go';
import JweGo from './go/jwe.go';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
This guide shows you how to verify the integrity of the received data on your target.
There are three options available, which will be demonstrated in the following sections.
@@ -133,13 +133,13 @@ As mentioned before, this validation can and should be applied to any target imp
<Tabs>
<Tab value="JSON">
<CodeBlock language="go">{JSONCode}</CodeBlock>
<DynamicCodeBlock lang="go" code={JsonGo} />
</Tab>
<Tab value="JWT">
<CodeBlock language="go">{JWTCode}</CodeBlock>
<DynamicCodeBlock lang="go" code={JwtGo} />
</Tab>
<Tab value="JWE">
<CodeBlock language="go">{JWECode}</CodeBlock>
<DynamicCodeBlock lang="go" code={JweGo} />
</Tab>
</Tabs>
@@ -3,10 +3,10 @@ title: Set up Zitadel with Docker Compose
sidebar_label: Docker Compose
---
import CodeBlock from '@/components/docusaurus/code-block';
import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx';
import DockerCompose from './docker-compose.yaml';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
import DockerComposeSource from "./docker-compose.yaml"
import Disclaimer from './_disclaimer.mdx'
import DefaultUser from './_defaultuser.mdx'
import Next from './_next.mdx'
@@ -54,7 +54,7 @@ The comments give context to the used variables and show examples for commonly u
<details>
<summary>docker-compose.yaml</summary>
<CodeBlock language="yaml">{DockerComposeSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={DockerCompose} />
</details>
Here are some natural steps forward to go from the current setup to production:
@@ -2,12 +2,11 @@
title: Download the docker compose example configuration.
---
import CodeBlock from '@/components/docusaurus/code-block';
import DockerComposeSource from "./docker-compose.yaml"
import ExampleZITADELConfigSource from "./example-zitadel-config.yaml"
import ExampleZITADELSecretsSource from "./example-zitadel-secrets.yaml"
import ExampleZITADELInitStepsSource from "./example-zitadel-init-steps.yaml"
import DockerComposeYaml from './docker-compose.yaml';
import ExampleZitadelConfig from './example-zitadel-config.yaml';
import ExampleZitadelSecrets from './example-zitadel-secrets.yaml';
import ExampleZitadelInitSteps from './example-zitadel-init-steps.yaml';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
The docker compose example mounts the example zitadel configuration files to the ZITADEL container.
@@ -15,36 +14,36 @@ By executing the commands below, you will download the following files:
<details>
<summary>docker-compose.yaml</summary>
<CodeBlock language="yaml">{DockerComposeSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={DockerComposeYaml} />
</details>
<details>
<summary>example-zitadel-config.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELConfigSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelConfig} />
</details>
<details>
<summary>example-zitadel-secrets.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELSecretsSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelSecrets} />
</details>
<details>
<summary>example-zitadel-init-steps.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELInitStepsSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelInitSteps} />
</details>
```bash
# Download the docker compose example configuration.
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/docker-compose.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/docker-compose.yaml
# Download and adjust the example configuration file containing standard configuration.
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-config.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-config.yaml
# Download and adjust the example configuration file containing secret configuration.
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-secrets.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-secrets.yaml
# Download and adjust the example configuration file containing database initialization configuration.
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-init-steps.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-init-steps.yaml
# A single ZITADEL instance always needs the same 32 bytes long masterkey
# Generate one to a file if you haven't done so already and pass it as environment variable
@@ -2,11 +2,10 @@
title: Download and adjust the example configuration file containing standard configuration
---
import CodeBlock from '@/components/docusaurus/code-block';
import ExampleZITADELConfigSource from "./example-zitadel-config.yaml"
import ExampleZITADELSecretsSource from "./example-zitadel-secrets.yaml"
import ExampleZITADELInitStepsSource from "./example-zitadel-init-steps.yaml"
import ExampleZitadelConfig from './example-zitadel-config.yaml';
import ExampleZitadelSecrets from './example-zitadel-secrets.yaml';
import ExampleZitadelInitSteps from './example-zitadel-init-steps.yaml';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
### Configure by Files
@@ -14,28 +13,28 @@ By executing the commands below, you will download the following files:
<details>
<summary>example-zitadel-config.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELConfigSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelConfig} />
</details>
<details>
<summary>example-zitadel-secrets.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELSecretsSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelSecrets} />
</details>
<details>
<summary>example-zitadel-init-steps.yaml</summary>
<CodeBlock language="yaml">{ExampleZITADELInitStepsSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={ExampleZitadelInitSteps} />
</details>
```bash
# Download and adjust the example configuration file containing standard configuration
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-config.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-config.yaml
# Download and adjust the example configuration file containing secret configuration
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-secrets.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-secrets.yaml
# Download and adjust the example configuration file containing database initialization configuration
wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/configure/example-zitadel-init-steps.yaml
wget https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/configure/example-zitadel-init-steps.yaml
# A single ZITADEL instance always needs the same 32 characters long masterkey
# If you haven't done so already, you can generate a new one
@@ -7,10 +7,10 @@ import LinuxUnix from "./_linuxunix.mdx";
import Compose from "./_compose.mdx";
import Helm from "./_helm.mdx";
import Login from "./_login.mdx";
import CodeBlock from "@/components/docusaurus/code-block";
import DefaultsYamlSource from "../../../../../../cmd/defaults.yaml";
import StepsYamlSource from "../../../../../../cmd/setup/steps.yaml";
import SkipSuperUserDatabaseQueries from "./example-skip-superuser-queries.yaml";
import DefaultsYaml from '../../../../../../cmd/defaults.yaml';
import StepsYaml from '../../../../../../cmd/setup/steps.yaml';
import SkipSuperUserQueries from './example-skip-superuser-queries.yaml';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
This guide assumes you are familiar with [running ZITADEL using the least amount of configuration possible](/self-hosting/deploy/overview).
@@ -27,7 +27,7 @@ For overwriting the default configuration for the first instance created by zita
<details>
<summary>defaults.yaml</summary>
<CodeBlock language="yaml">{DefaultsYamlSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={DefaultsYaml} />
</details>
### Database initialization file
@@ -42,7 +42,7 @@ By using the FirstInstance section, you can overwrite the [DefaultInstance confi
<details>
<summary>steps.yaml</summary>
<CodeBlock language="yaml">{StepsYamlSource}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={StepsYaml} />
</details>
### Pre-existing Database and User
@@ -54,7 +54,7 @@ To skip the checks, you must ensure the database objects (database, user, grant)
<details>
<summary>skip-superuser-queries-config.yaml</summary>
<CodeBlock language="yaml">{SkipSuperUserDatabaseQueries}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={SkipSuperUserQueries} />
</details>
### Multiple configuration files
@@ -1,16 +1,16 @@
import CodeBlock from '@/components/docusaurus/code-block';
import ComposeYaml from "./docker-compose.yaml";
import BaseDockerCompose from './docker-compose.yaml';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
<>With these examples, you create and run a minimal {props.link} configuration for Zitadel with <a href="https://docs.docker.com/compose">Docker Compose</a>.
Whereas the guide focuses on the configuration for {props.name}, you can inspect the settings for the Zitadel API, the Zitadel login and the database in the base Docker Compose file.</>
<details>
<summary>base docker-compose.yaml</summary>
<CodeBlock language="yaml">{ComposeYaml}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={BaseDockerCompose} />
</details>
<>For running {props.name}, you will extend the base Docker Compose file with the {props.name} specific Docker Compose file.</>
<details>
<summary>specific docker-compose.yaml</summary>
<CodeBlock language="yaml">{props.compose}</CodeBlock>
<DynamicCodeBlock lang="yaml" code={props.compose} />
</details>
@@ -1,4 +1,4 @@
import CodeBlock from '@/components/docusaurus/code-block';
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
export const Description = ({mode, name}) => {
let desc
@@ -37,24 +37,25 @@ export const Commands = ({mode, name, lower, configfilename}) => {
// We only need that flag for TLS connections with the self-signed cert
connInsecureFlag = ""
}
const code = [
'# Download the configuration files.',
'export ZITADEL_CONFIG_FILES=https://raw.githubusercontent.com/zitadel/zitadel/main/apps/docs/content/self-hosting/manage/reverseproxy',
'wget ${ZITADEL_CONFIG_FILES}/docker-compose.yaml -O docker-compose-base.yaml --quiet',
`wget \${ZITADEL_CONFIG_FILES}/${lower}/docker-compose.yaml -O docker-compose-${lower}.yaml --quiet`,
`wget \${ZITADEL_CONFIG_FILES}/${lower}/${configfilename} -O ${configfilename} --quiet`,
...(genCert ? ['', genCert.trimEnd()] : []),
'',
`# Run the database, and ${name}.`,
`docker compose --file docker-compose-base.yaml --file docker-compose-${lower}.yaml up --detach --wait db zitadel-init zitadel-${mode}-tls login-${mode}-tls proxy-${mode}-tls`,
'',
'# Test that gRPC and HTTP APIs work. Empty brackets like {} means success.',
'# Make sure you have the grpcurl cli installed on your machine https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#installation',
`grpcurl ${connInsecureFlag}${grpcPlainTextFlag}127.0.0.1.sslip.io:${connPort} zitadel.admin.v1.AdminService/Healthz`,
`curl ${connInsecureFlag}${connScheme}://127.0.0.1.sslip.io:${connPort}/admin/v1/healthz`,
].join('\n')
return (
<div>
<CodeBlock language="bash">
{'# Download the configuration files.'}{'\n'}
{'export ZITADEL_CONFIG_FILES=https://raw.githubusercontent.com/zitadel/zitadel/main/docs/self-hosting/manage/reverseproxy\n'}
{'wget ${ZITADEL_CONFIG_FILES}/docker-compose.yaml -O docker-compose-base.yaml --quiet \n'}
{'wget ${ZITADEL_CONFIG_FILES}/'}{lower}{'/docker-compose.yaml -O docker-compose-'}{lower}{'.yaml --quiet \n'}
{'wget ${ZITADEL_CONFIG_FILES}/'}{lower}{'/'}{configfilename}{' -O '}{configfilename}{' --quiet \n'}
{'\n'}
{genCert}
{'# Run the database, and '}{name}{'.'}{'\n'}
{'docker compose --file docker-compose-base.yaml --file docker-compose-'}{lower}{'.yaml up --detach --wait db zitadel-init zitadel-'}{mode}{'-tls login-'}{mode}{'-tls proxy-'}{mode}{'-tls'}{'\n'}
{'\n'}
{'# Test that gRPC and HTTP APIs work. Empty brackets like {} means success.\n'}
{'# Make sure you have the grpcurl cli installed on your machine https://github.com/fullstorydev/grpcurl?tab=readme-ov-file#installation\n'}
{'grpcurl '}{connInsecureFlag}{grpcPlainTextFlag}{'127.0.0.1.sslip.io:'}{connPort}{' zitadel.admin.v1.AdminService/Healthz\n'}
{'curl '}{connInsecureFlag}{connScheme}{'://127.0.0.1.sslip.io:'}{connPort}{'/admin/v1/healthz\n'}
</CodeBlock>
<div className="mt-4">
<DynamicCodeBlock lang="bash" code={code} />
</div>
)
}
@@ -72,7 +73,7 @@ export const LoginURL = ({mode}) => {
<details open>
<summary>{props.configfilename}</summary>
<CodeBlock >{props.configfilecontent}</CodeBlock>
<DynamicCodeBlock lang={props.lower === 'nginx' ? 'nginx' : props.lower === 'httpd' ? 'conf' : props.lower === 'caddy' ? 'caddy' : 'yaml'} code={props.configfilecontent} />
</details>
<Commands mode={props.mode} name={props.providername} lower={props.lower} configfilename={props.configfilename}/>
@@ -84,7 +85,4 @@ export const LoginURL = ({mode}) => {
If the management console loads normally, you know that the HTTP and gRPC-Web and gRPC APIs are working correctly.
<CodeBlock language="bash">
{'# You can now stop the database, the Zitadel API, the Zitadel login and '}{props.providername}{'.'}{'\n'}
{'docker compose --file docker-compose-base.yaml --file docker-compose-'}{props.lower}{'.yaml down'}{'\n'}
</CodeBlock>
<DynamicCodeBlock lang="bash" code={`# You can now stop the database, the Zitadel API, the Zitadel login and ${props.providername}.\ndocker compose --file docker-compose-base.yaml --file docker-compose-${props.lower}.yaml down`} />