diff --git a/website/docs/customize/blueprints/v1/structure.md b/website/docs/customize/blueprints/v1/structure.md
index fd819bca8aa2..4ec53968568c 100644
--- a/website/docs/customize/blueprints/v1/structure.md
+++ b/website/docs/customize/blueprints/v1/structure.md
@@ -1,10 +1,34 @@
+import Collapse from "@site/src/components/Collapse";
+
# File structure
Blueprints are YAML files, which can use some additional tags to ease blueprint creation.
## Schema
-The blueprint schema is available under `https://goauthentik.io/blueprints/schema.json`. It is also possible to target a specific version's blueprint schema by using `https://version-2023-4.goauthentik.io/blueprints/schema.json`.
+The blueprint schema is available under
+[`https://goauthentik.io/blueprints/schema.json`](https://goauthentik.io/blueprints/schema.json). It
+is also possible to target a specific version's blueprint schema by using
+[`https://version-2023-4.goauthentik.io/blueprints/schema.json`](https://version-2023-4.goauthentik.io/blueprints/schema.json).
+
+
+- [Version 2022-8](https://version-2022-8.goauthentik.io/blueprints/schema.json)
+- [Version 2022-9](https://version-2022-9.goauthentik.io/blueprints/schema.json)
+- [Version 2022-10](https://version-2022-10.goauthentik.io/blueprints/schema.json)
+- [Version 2022-11](https://version-2022-11.goauthentik.io/blueprints/schema.json)
+- [Version 2022-12](https://version-2022-12.goauthentik.io/blueprints/schema.json)
+- [Version 2023-1](https://version-2023-1.goauthentik.io/blueprints/schema.json)
+- [Version 2023-2](https://version-2023-2.goauthentik.io/blueprints/schema.json)
+- [Version 2023-3](https://version-2023-3.goauthentik.io/blueprints/schema.json)
+- [Version 2023-4](https://version-2023-4.goauthentik.io/blueprints/schema.json)
+- [Version 2023-5](https://version-2023-5.goauthentik.io/blueprints/schema.json)
+- [Version 2023-6](https://version-2023-6.goauthentik.io/blueprints/schema.json)
+- [Version 2023-8](https://version-2023-8.goauthentik.io/blueprints/schema.json)
+- [Version 2023-10](https://version-2023-10.goauthentik.io/blueprints/schema.json)
+- [Version 2024-2](https://version-2024-2.goauthentik.io/blueprints/schema.json)
+- [Version 2024-4](https://version-2024-4.goauthentik.io/blueprints/schema.json)
+- [Version 2024-6](https://version-2024-6.goauthentik.io/blueprints/schema.json)
+
To use the schema with Visual Studio code and the YAML extension, add this comment at the top of your blueprint files:
diff --git a/website/package.json b/website/package.json
index 397b142987e0..a95362c01732 100644
--- a/website/package.json
+++ b/website/package.json
@@ -4,7 +4,7 @@
"private": true,
"license": "MIT",
"scripts": {
- "build": "cp ../docker-compose.yml static/docker-compose.yml && cp ../schema.yml static/schema.yaml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
+ "build": "node scripts/list-blueprint-schemas.mjs && cp ../docker-compose.yml static/docker-compose.yml && cp ../schema.yml static/schema.yaml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
"build-bundled": "cp ../schema.yml static/schema.yaml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
"deploy": "docusaurus deploy",
"docusaurus": "docusaurus",
diff --git a/website/scripts/list-blueprint-schemas.mjs b/website/scripts/list-blueprint-schemas.mjs
new file mode 100644
index 000000000000..ae5e49ee4947
--- /dev/null
+++ b/website/scripts/list-blueprint-schemas.mjs
@@ -0,0 +1,72 @@
+import { execSync } from "child_process";
+import { fileURLToPath } from "url";
+import { readFileSync, writeFileSync } from "fs";
+import path from "path";
+
+const __dirname = fileURLToPath(new URL(".", import.meta.url));
+const structureFilePath = path.join(
+ __dirname,
+ "../docs/customize/blueprints/v1/structure.md",
+);
+
+const cmd = ["git", "ls-remote", "--tags", "origin"].join(" ");
+const tagblob = execSync(cmd, { encoding: "utf8" });
+const itsadate = /\d{4}\.\d{1,2}\.\d{1,2}$/;
+const sortfn = (d1, d2) => {
+ const [y1, m1, y2, m2] = [d1[0], d1[1], d2[0], d2[1]].map((s) =>
+ parseInt(s, 10),
+ );
+ return y1 < y2 ? 1 : y1 > y2 ? -1 : m1 < m2 ? 1 : m1 > m2 ? -1 : 0;
+};
+
+const taglines = tagblob
+ .split("\n")
+ .filter((line) => itsadate.test(line))
+ .map((line) =>
+ line
+ .split("\t")[1]
+ .replace("refs/tags/version/", "")
+ .replace(/\.\d{1,2}$/, "")
+ .split("."),
+ )
+ .toSorted(sortfn)
+ .map(([a, b]) => `${a}-${b}`)
+ .reduce((acc, a) => (acc.includes(a) ? acc : [...acc, a]), []);
+
+const results = await Promise.allSettled(
+ taglines.map((version) =>
+ fetch(
+ `https://version-${version}.goauthentik.io/blueprints/schema.json`,
+ {
+ method: "HEAD",
+ },
+ ),
+ ),
+);
+
+const version = /version-(\d{4}-\d{1,2})/;
+
+const valid = results
+ .filter(
+ (result) =>
+ result.status === "fulfilled" && result.value.status === 200,
+ )
+ .map((result) => result.value.url)
+ .map((url) => {
+ const thedate = version.exec(url)[1];
+ return `- [Version ${thedate.replace("-", ".")}](${url})`;
+ });
+
+const structurefile = readFileSync(structureFilePath, "utf-8");
+const schemablock =
+ /.*?<\/Collapse>/m;
+
+writeFileSync(
+ structureFilePath,
+ structurefile.replace(
+ schemablock,
+ `
+${valid.join("\n")}
+`,
+ ),
+);
diff --git a/website/src/components/Collapse.tsx b/website/src/components/Collapse.tsx
new file mode 100644
index 000000000000..e56c9d2536fd
--- /dev/null
+++ b/website/src/components/Collapse.tsx
@@ -0,0 +1,15 @@
+import Details from "@theme/MDXComponents/Details";
+
+export default function Collapse(props: {
+ children: React.ReactNode;
+ title?: string;
+}) {
+ const { children, title = "Collapse" } = props;
+
+ return (
+
+ {title}
+ {children}
+
+ );
+}