diff --git a/docs/blog/2026-09-02-thunderid-1-0.mdx b/docs/blog/2026-09-02-thunderid-1-0.mdx
index e1d2497a2c..9646865ad6 100644
--- a/docs/blog/2026-09-02-thunderid-1-0.mdx
+++ b/docs/blog/2026-09-02-thunderid-1-0.mdx
@@ -110,7 +110,7 @@ Configuration has its own tooling. A CLI covers installation through day-to-day
## Get involved
- is open source, and the work around it is open too. Design discussions happen in public before anything is built. Proposals, decisions, and the reasoning behind them are all in the open. The [Community guide](/docs/v1.0.x/community/overview) covers how to get started, whether that is filing an issue, joining a discussion, or opening a pull request.
+ is open source, and the work around it is open too. Design discussions happen in public before anything is built. Proposals, decisions, and the reasoning behind them are all in the open. The [Community guide](../../docs/community/overview) covers how to get started, whether that is filing an issue, joining a discussion, or opening a pull request.
One kind of feedback we especially want right now. If you are integrating and something is harder than it should be, tell us. First integrations surface friction that nobody on the inside can see anymore.
@@ -118,10 +118,10 @@ One kind of feedback we especially want right now. If you are integrating can be used to secure:
-- **Applications**: follow the [Securing B2C Application guide](/docs/v1.0.x/use-cases/b2c/try-it-out)
-- **AI agents**: follow the [Securing AI Agents guide](/docs/v1.0.x/use-cases/ai-agents/try-it-out)
-- **MCP**: follow the [Securing MCP guide](/docs/v1.0.x/use-cases/ai-agents/mcp-authorization/try-it-out)
+- **Applications**: follow the [Securing B2C Application guide](../../docs/use-cases/b2c/try-it-out)
+- **AI agents**: follow the [Securing AI Agents guide](../../docs/use-cases/ai-agents/try-it-out)
+- **MCP**: follow the [Securing MCP guide](../../docs/use-cases/ai-agents/mcp-authorization/try-it-out)
-To learn more about the requirements and solution patterns behind these scenarios, see the [Use cases](/docs/v1.0.x/use-cases/overview) section. Visit [Get ](/docs/v1.0.x/getting-started/get-thunderid) for installation methods.
+To learn more about the requirements and solution patterns behind these scenarios, see the [Use cases](../../docs/use-cases/overview) section. Visit [Get ](../../docs/getting-started/get-thunderid) for installation methods.
1.0 is out. Go run it, break it, and tell us what you find.
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index fc24eb4f25..3317548033 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -167,6 +167,22 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
personaPlugin,
'./plugins/docusaurus-plugin-llms-txt',
'./plugins/docusaurus-plugin-markdown-export',
+ [
+ '@docusaurus/plugin-client-redirects',
+ {
+ // v1.0.x moved from /docs/v1.0.x/ to the bare /docs/ root (it is the
+ // lastVersion). Redirect the old versioned URLs to their new root path so
+ // existing links keep working. GitHub Pages can't do server 301s, so these
+ // are generated as static client-side redirect stubs. The current/"Next"
+ // docs are untouched (still at /docs/next/).
+ createRedirects(existingPath: string): string[] | undefined {
+ if (existingPath.startsWith('/docs/') && !existingPath.startsWith('/docs/next/')) {
+ return [existingPath.replace('/docs/', '/docs/v1.0.x/')];
+ }
+ return undefined;
+ },
+ },
+ ],
],
presets: [
@@ -191,10 +207,10 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
},
'v1.0.x': {
label: 'v1.0.x',
- // Explicit URL segment so the stable release lives at /docs/v1.0.x/
- // instead of the bare doc root. The version tracks the 1.0 minor line
- // (1.0.0, 1.0.1, ...), so patch releases reuse these docs.
- path: 'v1.0.x',
+ // No `path` override, so as the lastVersion it is served at the bare doc
+ // root (/docs) as the latest release. The version tracks the 1.0 minor
+ // line (1.0.0, 1.0.1, ...), so patch releases reuse these docs. The
+ // current/"Next" docs stay at /docs/next as a preview.
// Current stable release: not archived, so no "unmaintained" banner.
banner: 'none',
// No "Version: v1.0.x" pill at the top of every doc page.
diff --git a/docs/package.json b/docs/package.json
index 9a1d1edf65..97802f3187 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -45,6 +45,7 @@
"dependencies": {
"@docsearch/docusaurus-adapter": "catalog:",
"@docusaurus/core": "3.9.2",
+ "@docusaurus/plugin-client-redirects": "3.9.2",
"@docusaurus/plugin-content-blog": "3.9.2",
"@docusaurus/plugin-content-docs": "3.9.2",
"@docusaurus/preset-classic": "3.9.2",
diff --git a/docs/plugins/docusaurus-plugin-llms-txt.js b/docs/plugins/docusaurus-plugin-llms-txt.js
index 76c073b228..2de202bab7 100644
--- a/docs/plugins/docusaurus-plugin-llms-txt.js
+++ b/docs/plugins/docusaurus-plugin-llms-txt.js
@@ -189,14 +189,16 @@ module.exports = function pluginLlmsTxt(context, options = {}) {
fs.writeFileSync(path.join(outDir, fileName), content);
written++;
- // Also write llms.txt inside the versioned docs path so
- // /docs/next/llms.txt resolves alongside the docs it describes.
- // Derive the docs route base from the first doc's permalink (e.g. "/docs/next/foo"
- // → "docs") rather than hardcoding "docs", so custom routeBasePath configs work.
- const firstPermalink = version.docs?.[0]?.permalink ?? '';
- const docsRouteBase = firstPermalink.split('/').filter(Boolean)[0] || 'docs';
- const versionUrlPath = version.versionName === 'current' ? 'next' : version.versionName;
- const versionedLlmsPath = path.join(outDir, docsRouteBase, versionUrlPath, 'llms.txt');
+ // Also write llms.txt inside the version's own docs path so /docs/llms.txt
+ // (last version at the root) and /docs/next/llms.txt resolve alongside the docs
+ // they describe. Use the version's resolved base path (version.path, e.g. "/docs"
+ // or "/docs/next") so it follows lastVersion and custom routeBasePath instead of
+ // assuming the URL segment equals the version name.
+ const baseUrl = siteConfig.baseUrl || '/';
+ const versionBase = version.path.startsWith(baseUrl)
+ ? version.path.slice(baseUrl.length)
+ : version.path.replace(/^\//, '');
+ const versionedLlmsPath = path.join(outDir, versionBase, 'llms.txt');
fs.mkdirSync(path.dirname(versionedLlmsPath), {recursive: true});
fs.writeFileSync(versionedLlmsPath, content);
written++;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7d656c1cad..05d15abe07 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -454,6 +454,9 @@ importers:
'@docusaurus/core':
specifier: 3.9.2
version: 3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)
+ '@docusaurus/plugin-client-redirects':
+ specifier: 3.9.2
+ version: 3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)
'@docusaurus/plugin-content-blog':
specifier: 3.9.2
version: 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3))(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)
@@ -4918,6 +4921,13 @@ packages:
react: '*'
react-dom: '*'
+ '@docusaurus/plugin-client-redirects@3.9.2':
+ resolution: {integrity: sha512-lUgMArI9vyOYMzLRBUILcg9vcPTCyyI2aiuXq/4npcMVqOr6GfmwtmBYWSbNMlIUM0147smm4WhpXD0KFboffw==}
+ engines: {node: '>=20.0'}
+ peerDependencies:
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+
'@docusaurus/plugin-content-blog@3.9.2':
resolution: {integrity: sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==}
engines: {node: '>=20.0'}
@@ -6865,7 +6875,7 @@ packages:
'@babel/plugin-transform-runtime': ^7.29.0 || ^8.0.0-rc.1
'@babel/runtime': ^7.27.0 || ^8.0.0-rc.1
rolldown: ^1.0.0-rc.5
- vite: '>=8.0.16'
+ vite: 8.0.16
peerDependenciesMeta:
'@babel/plugin-transform-runtime':
optional: true
@@ -9606,11 +9616,13 @@ packages:
eslint@9.0.0:
resolution: {integrity: sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
eslint@9.39.4:
resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
peerDependencies:
jiti: '*'
@@ -9621,6 +9633,7 @@ packages:
eslint@9.39.5:
resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true
peerDependencies:
jiti: '*'
@@ -16203,6 +16216,43 @@ snapshots:
- uglify-js
- webpack-cli
+ '@docusaurus/plugin-client-redirects@3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)':
+ dependencies:
+ '@docusaurus/core': 3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)
+ '@docusaurus/logger': 3.9.2
+ '@docusaurus/utils': 3.9.2(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(uglify-js@3.19.3)
+ '@docusaurus/utils-common': 3.9.2(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(uglify-js@3.19.3)
+ '@docusaurus/utils-validation': 3.9.2(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(uglify-js@3.19.3)
+ eta: 2.2.0
+ fs-extra: 11.3.5
+ lodash: 4.18.1
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ tslib: 2.8.1
+ transitivePeerDependencies:
+ - '@docusaurus/faster'
+ - '@mdx-js/react'
+ - '@minify-html/node'
+ - '@parcel/css'
+ - '@rspack/core'
+ - '@swc/core'
+ - '@swc/css'
+ - '@swc/html'
+ - bufferutil
+ - clean-css
+ - cssnano
+ - csso
+ - debug
+ - esbuild
+ - html-minifier-terser
+ - lightningcss
+ - postcss
+ - supports-color
+ - typescript
+ - uglify-js
+ - utf-8-validate
+ - webpack-cli
+
'@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3))(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)':
dependencies:
'@docusaurus/core': 3.9.2(@mdx-js/react@3.0.0(@types/react@19.2.14)(react@19.2.3))(@swc/core@1.15.33(@swc/helpers@0.5.21))(clean-css@5.3.3)(cssnano@6.1.2(postcss@8.5.23))(csso@5.0.5)(debug@4.4.3(supports-color@10.2.2))(esbuild@0.28.1)(html-minifier-terser@7.2.0)(lightningcss@1.32.0)(postcss@8.5.23)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(supports-color@10.2.2)(typescript@5.9.3)(uglify-js@3.19.3)