docs: fix broken GitHub code-reference blocks after fumadocs migration (#12213)

# Which Problems Are Solved

Pages in `apps/docs` that embed source from GitHub via the Docusaurus
convention

````
```js reference

https://github.com/zitadel/actions/blob/main/examples/org_metadata_claim.js
```
````

stopped working after the migration from Docusaurus to fumadocs. The old
`docusaurus-theme-github-codeblock` plugin used to fetch the file and
render it; fumadocs has no support for that meta, so the page rendered
the raw URL as plain code-block text. Visible at
`/docs/apis/actions/code-examples` and 16 other pages.

# How the Problems Are Solved

- Converted every ```` ```<lang> reference\n<URL>\n``` ```` block (46
total across 17 `.mdx` files) to the native fumadocs JSX form:
`<GithubCodeBlock url="<URL>" />`. The existing `<details>`/`<summary>`
collapsibles around blocks are kept — they're an authoring choice, not
part of the rendering bug.
- Updated `apps/docs/components/github-code-block.tsx` to render via
`DynamicCodeBlock` from `fumadocs-ui/components/dynamic-codeblock`
(proper shiki highlighting) instead of raw `CodeBlock` + `Pre` (which
produced unhighlighted output). Also fixed language detection so a URL
hash like `#L10-L20` no longer pollutes the language token.
- Registered `GithubCodeBlock` globally in
`apps/docs/mdx-components.tsx`, matching how every other shared
component (`APIPage`, `Callout`, `Tab/Tabs`, `Step/Steps`, `Admonition`,
`TerminologyUpdate`) is exposed. MDX files no longer need a local
`import`.

# Additional Changes

- Normalized the two MDX files that were already using the JSX form
(`examples/secure-api/python-django.mdx`,
`examples/secure-api/java-spring.mdx`): removed their now-redundant
local `import { GithubCodeBlock }` and rewrote 9 long-form
`<GithubCodeBlock url="..."></GithubCodeBlock>` tags to self-closing for
consistency.

# Additional Context

Verified locally with `pnpm --filter @zitadel/docs dev`:

- `/docs/apis/actions/code-examples` — 20 shiki-highlighted code blocks
rendered inside the `<details>` collapsibles (was 0).
- `/docs/apis/openidoauth/claims` — line-range hashes (`#L9-L11`)
honored.
- `/docs/examples/login/flutter` — mixed languages (xml/dart/html)
detected and highlighted.
- `/docs/guides/integrate/external-audit-log` — edge case of fenced
reference indented inside a numbered list also converted and rendered.

Greps:
- `^[ \t]*\`\`\`[a-zA-Z0-9]+ reference` in `apps/docs/content/**/*.mdx`
→ 0 matches.
- `<GithubCodeBlock url="` in `apps/docs/content/**/*.mdx` → 55 matches.
- `from '@/components/github-code-block'` in
`apps/docs/content/**/*.mdx` → 0 matches.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
Florian Forster
2026-05-28 11:02:44 -07:00
committed by GitHub
co-authored by Claude Opus 4.7
parent c73e58489b
commit f4f43f5248
21 changed files with 103 additions and 186 deletions
+6 -18
View File
@@ -86,9 +86,7 @@ flutter pub add oidc_default_store
Navigate to your `AndroidManifest.xml` at `<projectRoot>/android/app/src/main/AndroidManifest.xml` and add the following activity with your custom scheme.
```xml reference
https://github.com/zitadel/zitadel_flutter/blob/main/android/app/src/main/AndroidManifest.xml#L29-L38
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/android/app/src/main/AndroidManifest.xml#L29-L38" />
Furthermore, for `secure_storage`, you need to set the minimum SDK version to 18
in `<projectRoot>/android/app/src/build.gradle`.
@@ -99,16 +97,12 @@ To reduce the commented default code, we will modify the `main.dart` file.
First, the `MyApp` class: it remains a stateless widget:
```dart reference
https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L14-L28
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L14-L28" />
Second, the `MyHomePage` class will remain a stateful widget with
its title, we don't change any code here.
```dart reference
https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L30-L37
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L30-L37" />
What we'll change now, is the `_MyHomePageState` class to enable
authentication via ZITADEL and remove the counter button of the starter application. We'll show the username of the authenticated user.
@@ -126,16 +120,12 @@ Then the builder method, which does show the login button if you're not
authenticated, a loading bar if the login process is going on and
your name if you are authenticated:
```dart reference
https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L119-L159
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L119-L159" />
And finally the `_authenticate` method which calls the authorization endpoint,
then fetches the user info and stores the tokens into the secure storage.
```dart reference
https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L45-L117
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/lib/main.dart#L45-L117" />
Note that we have to use our http redirect URL for web applications or otherwise use our custom scheme for Android and iOS devices.
To setup other platforms, read the documentation of the [Flutter Web Auth](https://pub.dev/packages/flutter_web_auth_2).
@@ -143,9 +133,7 @@ To setup other platforms, read the documentation of the [Flutter Web Auth](https
To ensure our application catches the callback URL, you have to create a `auth.html` file in the `/web`
folder with the following content:
```html reference
https://github.com/zitadel/zitadel_flutter/blob/main/web/auth.html
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel_flutter/blob/main/web/auth.html" />
Now, you can run your application for iOS and Android devices with
+3 -9
View File
@@ -61,9 +61,7 @@ go get -u github.com/zitadel/zitadel-go/v3
Create a new go file with the content below. This will create an application with a home and profile page.
```go reference
https://github.com/zitadel/zitadel-go/blob/next/example/app/app.go
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel-go/blob/next/example/app/app.go" />
This will basically set up everything. So let's look at some parts of the code.
@@ -108,17 +106,13 @@ Now create two HTML files in the new `templates` folder and copy the content of
The home page will display a short welcome message and allow the user to manually start the login process.
```go reference
https://github.com/zitadel/zitadel-go/blob/next/example/app/templates/home.html
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel-go/blob/next/example/app/templates/home.html" />
**profile.html**
The profile page will display the Userinfo from the authentication context and allow the user to logout.
```go reference
https://github.com/zitadel/zitadel-go/blob/next/example/app/templates/profile.html
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel-go/blob/next/example/app/templates/profile.html" />
### Start your application
+1 -3
View File
@@ -94,9 +94,7 @@ If authorization is required, the token must not be expired and the API has to b
For tests, we will use a Personal Access Token.
```go reference
https://github.com/zitadel/zitadel-go/blob/next/example/api/http/main.go
```
<GithubCodeBlock url="https://github.com/zitadel/zitadel-go/blob/next/example/api/http/main.go" />
You will need to provide some values for the program to run:
- `domain`: Your ZITADEL Custom Domain, e.g. https://my-domain.zitadel.cloud
@@ -3,7 +3,6 @@ title: Secure Java Spring Boot API Application with ZITADEL
description: "Secure Java Spring Boot APIs using OAuth 2.0 Token Introspection with ZITADEL."
sidebar_label: Java Spring Boot
---
import { GithubCodeBlock } from '@/components/github-code-block';
This integration guide shows you how to integrate **ZITADEL** into your Java Spring Boot API. It demonstrates how to secure your API using
OAuth 2 Token Introspection.
@@ -45,7 +44,7 @@ into Spring Security `authiorities`, which can be used later on to determine the
So in your application, create a `support/zitadel` package and in there the `CustomAuthorityOpaqueTokenIntrospector.java`:
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/support/zitadel/CustomAuthorityOpaqueTokenIntrospector.java"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/support/zitadel/CustomAuthorityOpaqueTokenIntrospector.java" />
### Application server settings
@@ -55,11 +54,11 @@ In a new `config` package, create the `WebSecurityConfig.java`.
This class will take care of the authorization by require the calls on `/api/tasks` to be authorized. Any other endpoint will be public by default.
It will also use the just created CustomAuthorityOpaqueTokenIntrospector for the introspection call:
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/config/WebSecurityConfig.java"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/config/WebSecurityConfig.java" />
For the authorization (and the server in general) to work, the application needs some settings, so please provide the following to your `application.yml` (resources folder):
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/resources/application.yml"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/resources/application.yml" />
Note that the `introspection-uri`, `client-id` and `client-secret` are only placeholders. You can either change them in here using the values provided by ZITADEL
or pass them later on as arguments when starting the application.
@@ -75,7 +74,7 @@ If authorization is required, the token must not be expired and the API has to b
For tests we will use a Personal Access Token or the [Java Spring web example](../login/java-spring).
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/api/ExampleController.java"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/zitadel-java/blob/main/api/src/main/java/demo/app/api/ExampleController.java" />
## Test API
@@ -8,7 +8,6 @@ import AppJWT from '../imports/_app_jwt.mdx';
import ServiceAccountJWT from '../imports/_serviceaccount_jwt.mdx';
import ServiceAccountRole from '../imports/_serviceaccount_role.mdx';
import SetupPython from '../imports/_setup_python.mdx';
import { GithubCodeBlock } from '@/components/github-code-block';
This integration guide demonstrates the recommended way to incorporate ZITADEL into your Django Python application.
It explains how to check the token validity in the API and how to check for permissions.
@@ -63,7 +62,7 @@ For this example we need the following dependencies:
For the dependencies we need a requirements.txt-file with the following content:
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/requirements.txt"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/requirements.txt" />
Then install all dependencies with:
```bash
@@ -81,7 +80,7 @@ django-admin startproject myapi .
There is info needed for the introspection calls, which we put into the settings.py:
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/settings.py#L125-L133"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/settings.py#L125-L133" />
and create a ".env"-file in the root folder with the settings as an example:
```bash
@@ -103,16 +102,16 @@ API_PRIVATE_KEY_FILE_PATH = '/tmp/example/250719519163548112.json'
To validate the tokens, we need a validator which can be called in the event of API-calls.
validator.py:
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/validator.py"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/validator.py" />
### Requests and URLs
We define 3 different endpoints which differ in terms of requirements.
views.py:
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/views.py"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/views.py" />
To handle endpoints the urls have to be added to the urls.py:
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/urls.py"></GithubCodeBlock>
<GithubCodeBlock url="https://github.com/zitadel/example-python-django-oauth/blob/main/myapi/urls.py" />
### DB