diff --git a/package-lock.json b/package-lock.json index 4b1c496eb..6c8f108de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24760,6 +24760,12 @@ "node": ">=6" } }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, "node_modules/glob": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", @@ -25201,6 +25207,32 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -25228,6 +25260,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -33575,6 +33620,41 @@ "regjsparser": "bin/parser" } }, + "node_modules/rehype-autolink-headings": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz", + "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -39129,6 +39209,8 @@ "react": "^19.1.4", "react-dom": "^19.1.4", "react-markdown": "^10.1.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-slug": "^6.0.0", "wrangler": "^4.59.1" }, "devDependencies": { diff --git a/packages/website/package.json b/packages/website/package.json index 69a584cd0..fe7f722a8 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -20,6 +20,8 @@ "react": "^19.1.4", "react-dom": "^19.1.4", "react-markdown": "^10.1.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-slug": "^6.0.0", "wrangler": "^4.59.1" }, "devDependencies": { diff --git a/packages/website/src/docs-rehype.ts b/packages/website/src/docs-rehype.ts new file mode 100644 index 000000000..37128d9af --- /dev/null +++ b/packages/website/src/docs-rehype.ts @@ -0,0 +1,20 @@ +import rehypeAutolinkHeadings from "rehype-autolink-headings"; +import rehypeSlug from "rehype-slug"; +import type { PluggableList } from "unified"; + +export const docsRehypePlugins: PluggableList = [ + rehypeSlug, + [ + rehypeAutolinkHeadings, + { + behavior: "prepend", + properties: { className: "heading-anchor", ariaLabel: "Link to this section" }, + content: { + type: "element", + tagName: "span", + properties: { className: "heading-anchor-icon", ariaHidden: "true" }, + children: [{ type: "text", value: "#" }], + }, + }, + ], +]; diff --git a/packages/website/src/routes/docs/$.tsx b/packages/website/src/routes/docs/$.tsx index a538ad311..b0a056b9e 100644 --- a/packages/website/src/routes/docs/$.tsx +++ b/packages/website/src/routes/docs/$.tsx @@ -1,6 +1,7 @@ import { createFileRoute } from "@tanstack/react-router"; import ReactMarkdown from "react-markdown"; import { getDoc } from "~/docs"; +import { docsRehypePlugins } from "~/docs-rehype"; import { pageMeta } from "~/meta"; export const Route = createFileRoute("/docs/$")({ @@ -24,5 +25,5 @@ function DocsPage() { return
Doc not found.
; } - returnDoc not found.
; - return