boltdocs 2.6.1 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/client/index.cjs +1 -1
  2. package/dist/client/index.d.cts +32 -16
  3. package/dist/client/index.d.ts +32 -16
  4. package/dist/client/index.js +1 -1
  5. package/dist/node/cli-entry.cjs +1 -1
  6. package/dist/node/cli-entry.mjs +1 -1
  7. package/dist/node/index.cjs +1 -1
  8. package/dist/node/index.d.cts +11 -2
  9. package/dist/node/index.d.mts +11 -2
  10. package/dist/node/index.mjs +1 -1
  11. package/dist/node-Bogvkxao.mjs +101 -0
  12. package/dist/node-CXaog6St.cjs +101 -0
  13. package/dist/{package-DukYeKmD.mjs → package-Bqbn1AYK.mjs} +1 -1
  14. package/dist/{package-c99Cs7mD.cjs → package-CFP44vfn.cjs} +1 -1
  15. package/dist/{search-dialog-DMK5OpgH.cjs → search-dialog-CV3eJzMm.cjs} +1 -1
  16. package/dist/{search-dialog-3lvKsbVG.js → search-dialog-DNTomKgu.js} +1 -1
  17. package/dist/use-search-CS3gH19M.js +6 -0
  18. package/dist/use-search-DBpJZQuw.cjs +6 -0
  19. package/package.json +1 -1
  20. package/src/client/components/ui-base/head.tsx +10 -3
  21. package/src/client/hooks/use-i18n.ts +4 -3
  22. package/src/client/hooks/use-localized-to.ts +1 -4
  23. package/src/client/hooks/use-routes.ts +4 -4
  24. package/src/client/hooks/use-sidebar.ts +3 -0
  25. package/src/client/hooks/use-version.ts +19 -6
  26. package/src/client/index.ts +1 -0
  27. package/src/client/ssg/boltdocs-shell.tsx +46 -14
  28. package/src/client/ssg/create-routes.tsx +56 -12
  29. package/src/client/store/boltdocs-context.tsx +24 -5
  30. package/src/shared/types.ts +18 -2
  31. package/dist/node-CWN8U_p8.mjs +0 -88
  32. package/dist/node-D5iosYXv.cjs +0 -88
  33. package/dist/use-search-C9bxCqfF.js +0 -6
  34. package/dist/use-search-DcfZSunO.cjs +0 -6
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Boltdocs - https://boltdocs.vercel.app
3
+ * Copyright (c) 2026 Jesus Alcala
4
+ * Licensed under the MIT License.
5
+ */
6
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let l=require(`react-router-dom`),u=require(`react`),d=require(`react/jsx-runtime`),f=require(`react-aria-components`);f=c(f);let p=require(`lucide-react`),m=require(`clsx`),h=require(`tailwind-merge`),g=require(`flexsearch`),_=require(`virtual:boltdocs-search`);_=c(_);const v=Symbol.for(`__BDOCS_BOLTDOCS_CONTEXT__`),y=Symbol.for(`__BDOCS_BOLTDOCS_INSTANCE__`),b=globalThis[v]||(globalThis[v]=(0,u.createContext)(void 0));function x({children:e,initialLocale:t=``,initialVersion:n=``}){let r=(typeof window>`u`||window.location.pathname.split(`/`).filter(Boolean),{locale:t,version:n}),[i,a]=(0,u.useState)(r.locale),[o,s]=(0,u.useState)(r.version),[c,l]=(0,u.useState)(!1),f=(0,u.useMemo)(()=>({currentLocale:i,currentVersion:o,setLocale:e=>a(e||``),setVersion:e=>s(e||``),hasHydrated:c,setHasHydrated:l}),[i,o,c]);return typeof globalThis<`u`&&(globalThis[y]=f),(0,d.jsx)(b.Provider,{value:f,children:e})}function S(){let e=(0,u.use)(b);if(!e&&typeof globalThis<`u`&&globalThis[y])return globalThis[y];if(!e)throw Error(`useBoltdocsContext must be used within a BoltdocsProvider`);return e}const C=Symbol.for(`__BDOCS_CONFIG_CONTEXT__`),w=Symbol.for(`__BDOCS_CONFIG_INSTANCE__`),T=globalThis[C]||(globalThis[C]=(0,u.createContext)(null));function E(){let e=(0,u.use)(T);if(!e&&typeof globalThis<`u`&&globalThis[w])return globalThis[w];if(!e)throw Error(`useConfig must be used within a ConfigProvider`);return e}function D(...e){return(0,h.twMerge)((0,m.clsx)(e))}function O(e){let{size:t=20,...n}=e;return{...n,width:t,height:t}}const k=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,...O(e),children:[(0,d.jsx)(`title`,{children:`GitHub`}),(0,d.jsx)(`path`,{d:`M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12`})]}),A=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,...O(e),children:[(0,d.jsx)(`title`,{children:`Discord`}),(0,d.jsx)(`path`,{d:`M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z`})]}),j=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,...O(e),children:[(0,d.jsx)(`title`,{children:`X`}),(0,d.jsx)(`path`,{d:`M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z`})]}),M=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,...O(e),children:[(0,d.jsx)(`title`,{children:`Bluesky`}),(0,d.jsx)(`path`,{d:`M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026`})]}),ee=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`TypeScript`}),(0,d.jsx)(`path`,{fill:`#2563EB`,d:`M3.234 9.093V7.318h8.363v1.775H8.479V17.5H6.352V9.093H3.234zm15.263 1.153c-.04-.4-.21-.712-.512-.934-.301-.222-.71-.333-1.228-.333-.351 0-.648.05-.89.149-.242.096-.427.23-.557.403a.969.969 0 0 0-.189.586.838.838 0 0 0 .115.477c.086.136.204.254.353.353.149.097.321.181.517.254.195.07.404.13.626.179l.915.219c.444.1.852.232 1.223.397.371.166.693.37.965.612.271.242.482.527.631.855.152.328.23.704.234 1.129-.004.623-.163 1.163-.478 1.62-.311.454-.762.807-1.352 1.06-.587.248-1.294.372-2.123.372-.822 0-1.538-.126-2.147-.378-.607-.252-1.081-.624-1.422-1.118-.338-.497-.516-1.112-.532-1.845h2.083c.023.342.12.627.293.855.176.226.41.397.701.513a2.8 2.8 0 0 0 1 .168c.364 0 .68-.053.949-.159a1.45 1.45 0 0 0 .631-.442c.15-.189.224-.406.224-.651a.846.846 0 0 0-.204-.577c-.132-.156-.328-.288-.586-.398a5.964 5.964 0 0 0-.94-.298l-1.109-.278c-.858-.21-1.536-.536-2.033-.98-.497-.444-.744-1.042-.74-1.795-.004-.616.16-1.155.491-1.615.335-.461.794-.82 1.377-1.08.584-.258 1.247-.387 1.99-.387.755 0 1.414.13 1.978.388.567.258 1.007.618 1.322 1.079.315.46.477.994.488 1.6h-2.064z`})]}),te=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`JavaScript`}),(0,d.jsx)(`path`,{fill:`#F59E0B`,d:`M8.383 7.318h2.127v7.1c0 .656-.147 1.226-.442 1.71a2.924 2.924 0 01-1.218 1.118c-.52.262-1.125.393-1.815.393-.613 0-1.17-.107-1.67-.323a2.67 2.67 0 01-1.183-.994c-.292-.448-.436-1.01-.433-1.686h2.143c.006.269.061.5.164.691.106.19.25.335.432.438.186.1.405.15.657.15.265 0 .488-.057.67-.17.186-.116.327-.285.423-.507.096-.222.145-.496.145-.82v-7.1zm9.43 2.928c-.04-.4-.21-.712-.511-.934-.302-.222-.711-.333-1.228-.333-.352 0-.648.05-.89.149-.242.096-.428.23-.557.403a.969.969 0 00-.19.586.838.838 0 00.115.477c.087.136.204.254.353.353.15.097.322.181.517.254.196.07.405.13.627.179l.915.219c.444.1.851.232 1.223.397.37.166.692.37.964.612s.482.527.631.855a2.7 2.7 0 01.234 1.129c-.003.623-.162 1.163-.477 1.62-.312.454-.763.807-1.353 1.06-.586.248-1.294.372-2.122.372-.822 0-1.538-.126-2.148-.378-.607-.252-1.08-.624-1.422-1.118-.338-.497-.515-1.112-.532-1.845h2.083c.023.342.121.627.293.855.176.226.41.397.702.513.295.112.628.168.999.168.364 0 .68-.053.95-.159.271-.106.482-.253.63-.442.15-.189.224-.406.224-.651a.846.846 0 00-.203-.577c-.133-.156-.329-.288-.587-.398a5.964 5.964 0 00-.94-.298l-1.108-.278c-.859-.21-1.537-.536-2.034-.98-.497-.444-.744-1.042-.74-1.795-.004-.616.16-1.155.492-1.615.334-.461.793-.82 1.377-1.08.583-.258 1.246-.387 1.989-.387.755 0 1.415.13 1.978.388.567.258 1.008.618 1.323 1.079.314.46.477.994.487 1.6h-2.063z`})]}),N=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`JSON`}),(0,d.jsx)(`path`,{fill:`#F59E0B`,d:`M4.778 6.667A2.667 2.667 0 017.444 4a.889.889 0 010 1.778.889.889 0 00-.888.889v3.5c0 .701-.273 1.35-.73 1.833.457.483.73 1.132.73 1.832v3.501c0 .491.398.89.888.89a.889.889 0 010 1.777 2.667 2.667 0 01-2.666-2.667v-3.5a.889.889 0 00-.674-.863l-.43-.108a.889.889 0 010-1.724l.43-.108a.889.889 0 00.674-.862V6.667zm14.222 0A2.667 2.667 0 0016.333 4a.889.889 0 000 1.778c.491 0 .89.398.89.889v3.5c0 .701.272 1.35.729 1.833a2.664 2.664 0 00-.73 1.832v3.501a.889.889 0 01-.889.89.889.889 0 000 1.777A2.667 2.667 0 0019 17.333v-3.5c0-.408.278-.764.673-.863l.431-.108a.889.889 0 000-1.724l-.43-.108a.889.889 0 01-.674-.862V6.667z`})]}),P=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`CSS`}),(0,d.jsx)(`path`,{fill:`#0EA5E9`,d:`M4.778 6.667A2.667 2.667 0 017.444 4a.889.889 0 010 1.778.889.889 0 00-.888.889v3.5c0 .701-.273 1.35-.73 1.833.457.483.73 1.132.73 1.832v3.501c0 .491.398.89.888.89a.889.889 0 010 1.777 2.667 2.667 0 01-2.666-2.667v-3.5a.889.889 0 00-.674-.863l-.43-.108a.889.889 0 010-1.724l.43-.108a.889.889 0 00.674-.862V6.667zm14.222 0A2.667 2.667 0 0016.333 4a.889.889 0 000 1.778c.491 0 .89.398.89.889v3.5c0 .701.272 1.35.729 1.833a2.664 2.664 0 00-.73 1.832v3.501a.889.889 0 01-.889.89.889.889 0 000 1.777A2.667 2.667 0 0019 17.333v-3.5c0-.408.278-.764.673-.863l.431-.108a.889.889 0 000-1.724l-.43-.108a.889.889 0 01-.674-.862V6.667z`})]}),F=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`HTML`}),(0,d.jsx)(`path`,{fill:`#EA580C`,d:`M4.778 6.667A2.667 2.667 0 017.444 4a.889.889 0 010 1.778.889.889 0 00-.888.889v3.5c0 .701-.273 1.35-.73 1.833.457.483.73 1.132.73 1.832v3.501c0 .491.398.89.888.89a.889.889 0 010 1.777 2.667 2.667 0 01-2.666-2.667v-3.5a.889.889 0 00-.674-.863l-.43-.108a.889.889 0 010-1.724l.43-.108a.889.889 0 00.674-.862V6.667zm14.222 0A2.667 2.667 0 0016.333 4a.889.889 0 000 1.778c.491 0 .89.398.89.889v3.5c0 .701.272 1.35.729 1.833a2.664 2.664 0 00-.73 1.832v3.501a.889.889 0 01-.889.89.889.889 0 000 1.777A2.667 2.667 0 0019 17.333v-3.5c0-.408.278-.764.673-.863l.431-.108a.889.889 0 000-1.724l-.43-.108a.889.889 0 01-.674-.862V6.667z`})]}),I=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`React`}),(0,d.jsx)(`path`,{fill:`#0E8ADC`,d:`M12 13.677a1.677 1.677 0 100-3.354 1.677 1.677 0 000 3.354z`}),(0,d.jsx)(`path`,{stroke:`#0E8ADC`,d:`M12 15.436c4.97 0 9-1.538 9-3.436s-4.03-3.436-9-3.436S3 10.102 3 12s4.03 3.436 9 3.436z`}),(0,d.jsx)(`path`,{stroke:`#0E8ADC`,d:`M9.024 13.718c2.485 4.305 5.832 7.025 7.476 6.076 1.644-.949.961-5.208-1.524-9.512C12.491 5.977 9.144 3.257 7.5 4.206c-1.644.949-.961 5.208 1.524 9.512z`}),(0,d.jsx)(`path`,{stroke:`#0E8ADC`,d:`M9.024 10.282c-2.485 4.304-3.168 8.563-1.524 9.512 1.644.95 4.99-1.771 7.476-6.076 2.485-4.304 3.168-8.563 1.524-9.512-1.644-.95-4.99 1.771-7.476 6.076z`})]}),L=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`Markdown`}),(0,d.jsx)(`path`,{fill:`#60A5FA`,d:`M3 15.714V8h2.323l2.322 2.836L9.968 8h2.322v7.714H9.968V11.29l-2.323 2.836-2.322-2.836v4.424H3zm14.516 0l-3.484-3.743h2.323V8h2.322v3.97H21l-3.484 3.744z`})]}),R=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 25 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`Shell`}),(0,d.jsx)(`path`,{stroke:`#14B8A6`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,d:`M4.336 17l6-6-6-6M12.336 19h8`})]}),z=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`YAML`}),(0,d.jsx)(`path`,{fill:`#A78BFA`,d:`M6.533 5.864h2.755l2.654 5.011h.113l2.654-5.011h2.756l-4.245 7.522V17.5h-2.443v-4.114L6.533 5.864z`})]}),B=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 25 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`Rust`}),(0,d.jsx)(`path`,{fill:`#EA580C`,fillRule:`evenodd`,d:`M12.58 2.136a.287.287 0 00-.488 0l-.526.85a8.974 8.974 0 00-.232.022l-.683-.73a.287.287 0 00-.478.096l-.35.935c-.075.021-.15.044-.224.067l-.812-.583a.287.287 0 00-.45.187l-.162.989a9.088 9.088 0 00-.204.11l-.913-.417a.287.287 0 00-.406.272l.036 1.005a9.099 9.099 0 00-.175.144l-.98-.231a.287.287 0 00-.345.345l.231.98a9.125 9.125 0 00-.144.175L4.27 6.316a.287.287 0 00-.271.406l.416.913a9.036 9.036 0 00-.11.203L3.317 8a.287.287 0 00-.187.45l.584.813a8.953 8.953 0 00-.068.223l-.935.35a.287.287 0 00-.095.479l.73.682a8.966 8.966 0 00-.023.233l-.85.526a.287.287 0 000 .488l.85.526c.007.078.014.156.023.233l-.73.682a.287.287 0 00.095.479l.935.35.068.223-.584.812a.287.287 0 00.187.451l.99.162c.035.068.072.135.109.203l-.416.913a.287.287 0 00.271.406l1.006-.036c.047.059.095.117.143.174l-.23.981a.287.287 0 00.344.345l.981-.23c.057.048.115.095.174.142l-.036 1.006a.287.287 0 00.406.272l.914-.417c.067.038.135.074.203.11l.161.99a.287.287 0 00.451.186l.813-.584c.074.024.148.046.223.068l.35.935a.287.287 0 00.478.095l.683-.73c.077.01.154.017.232.023l.526.85a.287.287 0 00.489 0l.526-.85c.078-.006.155-.014.232-.023l.682.73a.287.287 0 00.479-.095l.35-.935c.075-.022.15-.044.223-.068l.813.584a.287.287 0 00.45-.187l.162-.99a8.77 8.77 0 00.203-.109l.913.417a.287.287 0 00.406-.272l-.035-1.006c.058-.047.116-.094.174-.143l.98.231a.287.287 0 00.346-.345l-.231-.98.143-.175 1.006.036a.287.287 0 00.271-.406l-.416-.913a9.4 9.4 0 00.109-.203l.99-.162a.287.287 0 00.187-.45l-.584-.813a8.43 8.43 0 00.067-.223l.935-.35a.287.287 0 00.096-.479l-.73-.682c.009-.077.016-.155.023-.233l.85-.526a.287.287 0 000-.488l-.85-.526a8.844 8.844 0 00-.023-.233l.73-.682a.287.287 0 00-.096-.479l-.934-.35a9.246 9.246 0 00-.068-.223l.584-.812A.287.287 0 0021.357 8l-.99-.162a8.92 8.92 0 00-.11-.203l.417-.913a.287.287 0 00-.271-.406l-1.006.036a9.178 9.178 0 00-.143-.174l.23-.981a.287.287 0 00-.345-.345l-.98.23a9.43 9.43 0 00-.174-.142l.035-1.006a.287.287 0 00-.405-.272l-.914.417a9.11 9.11 0 00-.203-.11l-.162-.99a.287.287 0 00-.45-.186l-.813.584a9.088 9.088 0 00-.223-.068l-.35-.935a.287.287 0 00-.479-.095l-.682.73a9.062 9.062 0 00-.232-.023l-.526-.85zm-.257 1.62a.592.592 0 01.578.596.595.595 0 11-.578-.595zm1.363.98A7.324 7.324 0 0118.7 8.309l-.702 1.585a.547.547 0 00.275.717l1.352.6c.041.422.047.847.015 1.27h-.752c-.075 0-.106.05-.106.123v.344c0 .812-.457.99-.859 1.034-.383.044-.806-.161-.86-.394-.22-1.24-.583-1.526-1.152-1.975l-.041-.033c.736-.467 1.502-1.158 1.502-2.08 0-.998-.683-1.625-1.148-1.934-.655-.43-1.379-.516-1.574-.516H6.88a7.324 7.324 0 014.098-2.312l.916.96a.54.54 0 00.766.018l1.026-.978zm-8.46 4.407a.595.595 0 11-.034 1.19.595.595 0 01.034-1.19zm14.192.026a.595.595 0 11-.035 1.19.595.595 0 01.035-1.19zm-13.07.096h1.037v4.678H5.291a7.324 7.324 0 01-.237-2.797l1.282-.57a.542.542 0 00.276-.716l-.264-.595zm4.33.05h2.47c.128 0 .901.147.901.727 0 .48-.593.653-1.081.653h-2.293l.002-1.38zm0 3.36h1.892c.172 0 .924.05 1.164 1.011.026.104.064.291.107.503.078.389.174.861.247 1.06.113.345.57 1.034 1.058 1.034h3.089c-.207.277-.433.54-.677.785l-1.258-.27a.544.544 0 00-.645.417l-.298 1.394a7.323 7.323 0 01-6.108-.03l-.298-1.392a.542.542 0 00-.643-.418l-1.23.264a7.32 7.32 0 01-.636-.75h5.984c.067 0 .113-.011.113-.074v-2.117c0-.061-.046-.075-.113-.075h-1.75l.001-1.341zm-2.763 4.848a.595.595 0 11-.034 1.19.595.595 0 01.034-1.19zm8.814.027a.596.596 0 11-.035 1.19.596.596 0 01.035-1.19z`,clipRule:`evenodd`})]}),V=e=>(0,d.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,fill:`none`,viewBox:`0 0 24 24`,...O(e),children:[(0,d.jsx)(`title`,{children:`Rust`}),(0,d.jsx)(`path`,{fill:`#F87171`,d:`M4.778 6.667A2.667 2.667 0 017.444 4a.889.889 0 010 1.778.889.889 0 00-.888.889v3.5c0 .701-.273 1.35-.73 1.833.457.483.73 1.132.73 1.832v3.501c0 .491.398.89.888.89a.889.889 0 010 1.777 2.667 2.667 0 01-2.666-2.667v-3.5a.889.889 0 00-.674-.863l-.43-.108a.889.889 0 010-1.724l.43-.108a.889.889 0 00.674-.862V6.667zm14.222 0A2.667 2.667 0 0016.333 4a.889.889 0 000 1.778c.491 0 .89.398.89.889v3.5c0 .701.272 1.35.729 1.833a2.664 2.664 0 00-.73 1.832v3.501a.889.889 0 01-.889.89.889.889 0 000 1.777A2.667 2.667 0 0019 17.333v-3.5c0-.408.278-.764.673-.863l.431-.108a.889.889 0 000-1.724l-.43-.108a.889.889 0 01-.674-.862V6.667z`})]}),H=(0,u.createContext)({routes:[]});function U(){return(0,u.useContext)(H)}function W({routes:e,children:t}){return(0,d.jsx)(H.Provider,{value:{routes:e},children:t})}function G(){let{routes:e}=U(),t=E(),n=(0,l.useLocation)(),{hasHydrated:r,currentLocale:i,currentVersion:a}=S(),o=e=>e.endsWith(`/`)&&e.length>1?e.slice(0,-1):e,s=o(n.pathname),c=e?.find?.(e=>o(e.path)===s),u=t.i18n?c?.locale||(r?i:void 0)||t.i18n.defaultLocale:void 0,d=t.versions?c?.version||(r?a:void 0)||t.versions.defaultVersion:void 0,f=e?.filter?.(n=>{let r=t.i18n?(n.locale||t.i18n.defaultLocale)===u:!0,i=t.versions?(n.version||t.versions.defaultVersion)===d:!0;if(!(r&&i))return!1;let a=t.i18n;if(a){let t=!!c?.locale,r=!!n.locale;if(e?.some?.(e=>e!==n&&e.filePath===n.filePath&&e.version===n.version&&(e.locale||a.defaultLocale)===(n.locale||a.defaultLocale))&&t!==r)return!1}return!0}),p=t.i18n?.localeConfigs?.[u]?.label||t.i18n?.locales[u]||u,m=t.versions?.versions?.find?.(e=>e.path===d)?.label||d;return{routes:f,allRoutes:e,currentRoute:c,currentLocale:u,currentLocaleLabel:p,availableLocales:t.i18n?Object.entries(t.i18n.locales).map(([e,n])=>({key:e,label:t.i18n?.localeConfigs?.[e]?.label||n,isCurrent:e===u})):[],currentVersion:d,currentVersionLabel:m,availableVersions:t.versions?t.versions.versions.map(e=>({key:e.path,label:e.label,isCurrent:e.path===d})):[],config:t}}function K(e){let t=E(),{currentLocale:n,currentVersion:r}=G();if(!t||typeof e!=`string`||e.startsWith(`http`)||e.startsWith(`//`))return e;let i=t.i18n,a=t.versions;if(!i&&!a)return e;let o=e.startsWith(`/docs`),s=e.split(`/`).filter(Boolean),c=0;s[c]===`docs`&&c++,a&&s.length>c&&a.versions.find(e=>e.path===s[c])&&c++,i&&s.length>c&&i.locales[s[c]]&&c++;let l=s.slice(c),u=[];o&&(u.push(`docs`),a&&r&&u.push(r)),i&&n&&u.push(n),u.push(...l);let d=`/${u.join(`/`)}`;return d.length>1&&d.endsWith(`/`)?d.slice(0,-1):d||`/`}const q=(0,u.forwardRef)((e,t)=>{let{href:n,prefetch:r=`hover`,onMouseEnter:i,onFocus:a,...o}=e,s=K(n??``),c=e=>{i?.(e)},l=e=>{a?.(e)};return(0,d.jsx)(f.Link,{...o,ref:t,href:s,onMouseEnter:c,onFocus:l})});q.displayName=`Link`;const J=(0,u.forwardRef)((e,t)=>{let{href:n,end:r=!1,className:i,children:a,...o}=e,s=(0,l.useLocation)(),c=K(n??``),u=r?s.pathname===c:s.pathname.startsWith(c),f=typeof i==`function`?i({isActive:u}):D(i,u&&`active`),p=typeof a==`function`?a({isActive:u}):a;return(0,d.jsx)(q,{...o,ref:t,href:n,className:f,children:p})});J.displayName=`NavLink`;const Y=({children:e,className:t,...n})=>(0,d.jsx)(`header`,{className:D(`boltdocs-navbar sticky top-0 z-50 w-full border-b border-border-subtle bg-bg-main/80 backdrop-blur-md`,t),...n,children:e}),X=({children:e,className:t})=>(0,d.jsx)(`div`,{className:D(`mx-auto flex lg:h-navbar max-w-(--breakpoint-3xl) items-center justify-between px-4 md:px-6`,t),children:e}),Z=({children:e,className:t})=>(0,d.jsx)(`div`,{className:D(`flex flex-1 items-center justify-start gap-4 min-w-0`,t),children:e}),ne=({children:e,className:t})=>(0,d.jsx)(`div`,{className:D(`flex flex-1 items-center justify-end gap-2 md:gap-4 min-w-0`,t),children:e}),re=({children:e,className:t})=>(0,d.jsx)(`div`,{className:D(`hidden lg:flex flex-1 justify-center items-center gap-4 px-4 min-w-0 w-full`,t),children:e}),ie=({src:e,alt:t,width:n=24,height:r=24,className:i})=>(0,d.jsx)(q,{href:`/`,className:D(`flex items-center gap-2 shrink-0 outline-none`,i),children:e?(0,d.jsx)(`img`,{src:e,alt:t,width:n,height:r,className:`h-6 w-6 object-contain`}):null}),ae=({children:e,className:t})=>(0,d.jsx)(q,{href:`/`,children:(0,d.jsx)(`span`,{className:D(`text-lg font-bold tracking-tight hidden sm:inline-block`,t),children:e})}),oe=({children:e,className:t})=>(0,d.jsx)(`nav`,{className:D(`hidden md:flex items-center gap-6 text-sm font-medium`,t),children:e}),se=({label:e,href:t,active:n,to:r,className:i})=>(0,d.jsxs)(q,{href:t,target:r===`external`?`_blank`:void 0,className:D(`transition-colors outline-none font-medium focus-visible:ring-2 focus-visible:ring-primary-500/30 rounded-sm`,{"text-primary-500":n,"text-text-muted hover:text-text-main":!n},i),children:[e,r===`external`&&(0,d.jsx)(`span`,{className:`ml-1 inline-block`,children:(0,d.jsx)(p.ExternalLink,{size:12})})]}),Q=({className:e,onPress:t})=>{let[n,r]=(0,u.useState)(!1),i=n&&/Mac|iPod|iPhone|iPad/.test(navigator.platform);return(0,u.useEffect)(()=>{r(!0)},[]),(0,d.jsxs)(f.Button,{onPress:t,className:D(`flex items-center gap-2 rounded-full border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-muted outline-none cursor-pointer`,`transition-all duration-200 hover:border-border-strong hover:text-text-main hover:bg-bg-muted hover:shadow-sm active:scale-[0.98]`,`focus-visible:ring-2 focus-visible:ring-primary-500/30`,`w-full max-w-[720px] justify-between`,e),children:[(0,d.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,d.jsx)(p.Search,{size:16}),(0,d.jsx)(`span`,{className:`hidden sm:inline-block`,children:`Search docs...`})]}),(0,d.jsxs)(`div`,{className:`hidden sm:flex items-center gap-1 pointer-events-none select-none`,children:[(0,d.jsx)(`kbd`,{className:`flex h-5 items-center justify-center rounded border border-border-subtle bg-bg-main px-1.5 font-mono text-[10px] font-medium`,children:i?`⌘`:`Ctrl`}),(0,d.jsx)(`kbd`,{className:`flex h-5 w-5 items-center justify-center rounded border border-border-subtle bg-bg-main font-mono text-[10px] font-medium`,children:`K`})]})]})},ce=({className:e,theme:t,onThemeChange:n})=>(0,d.jsx)(f.ToggleButton,{isSelected:t===`dark`,onChange:n,className:D(`rounded-md p-2 text-text-muted outline-none cursor-pointer`,`transition-all duration-300 hover:bg-bg-surface hover:text-text-main hover:rotate-12 active:scale-90`,`focus-visible:ring-2 focus-visible:ring-primary-500/30`,e),"aria-label":`Toggle theme`,children:t===`dark`?(0,d.jsx)(p.Sun,{size:20}):(0,d.jsx)(p.Moon,{size:20})}),le=({name:e})=>{if(e===`github`)return(0,d.jsx)(k,{});if(e===`discord`)return(0,d.jsx)(A,{});if(e===`x`)return(0,d.jsx)(j,{});if(e===`bluesky`)return(0,d.jsx)(M,{})};Y.Root=Y,Y.Left=Z,Y.Right=ne,Y.Center=re,Y.Logo=ie,Y.Title=ae,Y.Links=oe,Y.Link=se,Y.SearchTrigger=Q,Y.Theme=ce,Y.Socials=({icon:e,link:t,className:n})=>(0,d.jsx)(q,{href:t,target:`_blank`,rel:`noopener noreferrer`,className:D(`rounded-md p-2 text-text-muted outline-none transition-colors`,`hover:bg-bg-surface hover:text-text-main`,`focus-visible:ring-2 focus-visible:ring-primary-500/30`,n),children:(0,d.jsx)(le,{name:e})}),Y.Split=({className:e})=>(0,d.jsx)(f.Separator,{orientation:`vertical`,className:D(`h-6 w-px bg-border-subtle mx-1`,e)}),Y.Content=X;const $=({children:e,isOpen:t,onOpenChange:n,className:r})=>(0,d.jsx)(f.ModalOverlay,{isOpen:t,onOpenChange:n,isDismissable:!0,className:D(`fixed inset-0 z-100 bg-black/40 backdrop-blur-sm px-4 py-4 sm:py-20`,`entering:animate-in entering:fade-in exiting:animate-out exiting:fade-out`),children:(0,d.jsx)(f.Modal,{className:D(`mx-auto w-full max-w-2xl overflow-hidden rounded-xl border border-border-subtle bg-bg-surface shadow-2xl ring-1 ring-black/5 outline-none`,`entering:animate-in entering:fade-in entering:zoom-in-95 exiting:animate-out exiting:fade-out exiting:zoom-out-95`,r),children:(0,d.jsx)(f.Dialog,{className:`flex flex-col max-h-[70vh] focus:outline-none`,children:e})})});$.Root=$,$.Autocomplete=({children:e,className:t,onSelectionChange:n,...r})=>{let i=f.Autocomplete;return(0,d.jsx)(`div`,{className:t,children:(0,d.jsx)(i,{...r,onSelectionChange:n,className:`flex flex-col min-h-0`,children:e})})},$.Input=({className:e,...t})=>(0,d.jsxs)(f.SearchField,{className:`flex items-center gap-3 border-b border-border-subtle px-4 py-4`,autoFocus:!0,children:[(0,d.jsx)(p.Search,{className:`h-5 w-5 text-text-muted`}),(0,d.jsx)(f.Input,{...t,className:D(`w-full bg-transparent text-lg text-text-main placeholder-text-muted outline-none`,e),placeholder:`Search documentation...`}),(0,d.jsx)(`div`,{className:`flex items-center gap-1.5 rounded-md border border-border-subtle bg-bg-main px-1.5 py-1 text-[10px] font-medium text-text-muted`,children:(0,d.jsx)(`kbd`,{className:`font-sans`,children:`ESC`})})]}),$.List=({children:e,className:t,...n})=>(0,d.jsx)(f.ListBox,{...n,className:D(`flex-1 overflow-y-auto p-2 outline-none`,t),children:e}),$.Item=Object.assign(({children:e,className:t,...n})=>(0,d.jsx)(f.ListBoxItem,{...n,className:D(`group flex items-center gap-3 rounded-lg p-3 text-left outline-none cursor-pointer transition-colors`,`text-text-muted hover:bg-bg-main hover:text-text-main focus:bg-primary-500 focus:text-white selected:bg-primary-500 selected:text-white`,t),children:t=>(0,d.jsxs)(d.Fragment,{children:[e,(t.isFocused||t.isSelected)&&(0,d.jsxs)(`div`,{className:`ml-auto opacity-50 flex items-center gap-1`,children:[(0,d.jsx)(`span`,{className:`text-[10px]`,children:`Select`}),(0,d.jsx)(p.CornerDownLeft,{size:10})]})]})}),{Icon:({isHeading:e,className:t})=>(0,d.jsx)(`div`,{className:D(`shrink-0`,t),children:e?(0,d.jsx)(p.Hash,{size:18}):(0,d.jsx)(p.FileText,{size:18})}),Title:({children:e,className:t})=>(0,d.jsx)(`span`,{className:D(`block font-medium truncate flex-1 text-sm`,t),children:e}),Bio:({children:e,className:t})=>(0,d.jsx)(`span`,{className:D(`ml-2 text-xs opacity-70 truncate hidden sm:inline group-focus:opacity-100`,t),children:e})});function ue(e){let{currentLocale:t,currentVersion:n}=G(),[r,i]=(0,u.useState)(!1),[a,o]=(0,u.useState)(``),[s,c]=(0,u.useState)(null);return(0,u.useEffect)(()=>{if(!r||s)return;let e=new g.Index({preset:`match`,tokenize:`full`,resolution:9,cache:!0});for(let t of _.default)e.add(t.id,`${t.title} ${t.content}`);c(e)},[r,s]),{isOpen:r,setIsOpen:i,query:a,setQuery:o,list:(0,u.useMemo)(()=>{if(!a)return e.filter(e=>{let r=!t||e.locale===t,i=!n||e.version===n;return r&&i}).slice(0,10).map(e=>({id:e.path,title:e.title,path:e.path,bio:e.description||``,groupTitle:e.groupTitle}));if(!s)return[];let r=s.search(a,{limit:20,suggest:!0}),i=[],o=new Set;for(let e of r){let r=_.default.find(t=>t.id===e);if(!r)continue;let a=!t||r.locale===t,s=!n||r.version===n;!a||!s||o.has(r.url)||(o.add(r.url),i.push({id:r.url,title:r.title,path:r.url,bio:r.display,groupTitle:r.display.split(` > `)[0],isHeading:r.url.includes(`#`)}))}return i.slice(0,10)},[a,s,t,n,e]),input:{value:a,onChange:e=>o(e.target.value)}}}Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return te}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return ee}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boltdocs",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "A lightweight documentation generator for React projects.",
5
5
  "main": "dist/node/index.mjs",
6
6
  "module": "dist/node/index.mjs",
@@ -1,11 +1,19 @@
1
1
  import { useLocation } from 'react-router-dom'
2
- import { Helmet } from 'react-helmet-async'
2
+ import type { ComponentType, ReactNode } from 'react'
3
+ import * as ReactHelmetAsync from 'react-helmet-async'
3
4
  import { useConfig } from '../../app/config-context'
4
5
 
6
+ type HelmetModule = {
7
+ Helmet?: ComponentType<{ children?: ReactNode }>
8
+ default?: { Helmet?: ComponentType<{ children?: ReactNode }> }
9
+ }
10
+ const helmetModule = ReactHelmetAsync as unknown as HelmetModule
11
+ const Helmet = helmetModule.Helmet || helmetModule.default?.Helmet || (({ children }) => <>{children}</>)
12
+
5
13
  interface HeadProps {
6
14
  siteTitle: string
7
15
  siteDescription?: string
8
- routes: Array<{ path: string; title: string; description?: string; seo?: Record<string, any> }>
16
+ routes: Array<{ path: string; title: string; description?: string; seo?: Record<string, unknown> }>
9
17
  }
10
18
 
11
19
  export function Head({ siteTitle, siteDescription, routes }: HeadProps) {
@@ -29,7 +37,6 @@ export function Head({ siteTitle, siteDescription, routes }: HeadProps) {
29
37
  const ogImage = seo['og:image'] || defaultOgImage
30
38
 
31
39
  return (
32
- // @ts-ignore
33
40
  <Helmet>
34
41
  <title>{finalTitle}</title>
35
42
  <meta name="description" content={pageDescription} />
@@ -2,19 +2,20 @@ import { useNavigate } from 'react-router-dom'
2
2
  import { getBaseFilePath } from '../utils/get-base-file-path'
3
3
  import { useRoutes } from './use-routes'
4
4
  import { useBoltdocsContext } from '../store/boltdocs-context'
5
+ import type { BoltdocsLocale } from '../../shared/types'
5
6
 
6
7
  export interface LocaleOption {
7
- key: string
8
+ key: BoltdocsLocale
8
9
  label: string
9
10
  value: string
10
11
  isCurrent: boolean
11
12
  }
12
13
 
13
14
  export interface UseI18nReturn {
14
- currentLocale: string | undefined
15
+ currentLocale: BoltdocsLocale | undefined
15
16
  currentLocaleLabel: string | undefined
16
17
  availableLocales: LocaleOption[]
17
- handleLocaleChange: (locale: string) => void
18
+ handleLocaleChange: (locale: BoltdocsLocale) => void
18
19
  }
19
20
 
20
21
  /**
@@ -54,10 +54,7 @@ export function useLocalizedTo(to: RouterLinkProps['to']) {
54
54
  }
55
55
 
56
56
  if (i18n && activeLocale) {
57
- // Only prefix if it's NOT the default locale (cleaner URLs)
58
- if (activeLocale !== i18n.defaultLocale) {
59
- resultParts.push(activeLocale)
60
- }
57
+ resultParts.push(activeLocale)
61
58
  }
62
59
 
63
60
  resultParts.push(...routeContent)
@@ -95,7 +95,7 @@ export function useRoutes() {
95
95
  ? Object.entries(config.i18n.locales).map(([key, defaultLabel]) => {
96
96
  const localeConfig = config.i18n?.localeConfigs?.[key]
97
97
  return {
98
- key,
98
+ key: key as import('../../shared/types').BoltdocsLocale,
99
99
  label: localeConfig?.label || defaultLabel,
100
100
  isCurrent: key === currentLocale,
101
101
  }
@@ -104,7 +104,7 @@ export function useRoutes() {
104
104
 
105
105
  const availableVersions = config.versions
106
106
  ? config.versions.versions.map((v) => ({
107
- key: v.path,
107
+ key: v.path as import('../../shared/types').BoltdocsVersion,
108
108
  label: v.label,
109
109
  isCurrent: v.path === currentVersion,
110
110
  }))
@@ -114,10 +114,10 @@ export function useRoutes() {
114
114
  routes,
115
115
  allRoutes,
116
116
  currentRoute,
117
- currentLocale,
117
+ currentLocale: currentLocale as import('../../shared/types').BoltdocsLocale,
118
118
  currentLocaleLabel,
119
119
  availableLocales,
120
- currentVersion,
120
+ currentVersion: currentVersion as import('../../shared/types').BoltdocsVersion,
121
121
  currentVersionLabel,
122
122
  availableVersions,
123
123
  config,
@@ -26,6 +26,9 @@ export function useSidebar(routes: ComponentRoute[]) {
26
26
  >()
27
27
 
28
28
  for (const route of filteredRoutes) {
29
+ // Skip home pages or external pages from the sidebar if they are not explicitly grouped
30
+ if (!route.filePath && !route.group) continue
31
+
29
32
  if (!route.group) {
30
33
  ungrouped.push(route)
31
34
  } else {
@@ -2,19 +2,20 @@ import { useNavigate } from 'react-router-dom'
2
2
  import { getBaseFilePath } from '../utils/get-base-file-path'
3
3
  import { useRoutes } from './use-routes'
4
4
  import { useBoltdocsContext } from '../store/boltdocs-context'
5
+ import type { BoltdocsVersion } from '../../shared/types'
5
6
 
6
7
  export interface VersionOption {
7
- key: string
8
+ key: BoltdocsVersion
8
9
  label: string
9
10
  value: string
10
11
  isCurrent: boolean
11
12
  }
12
13
 
13
14
  export interface UseVersionReturn {
14
- currentVersion: string | undefined
15
+ currentVersion: BoltdocsVersion | undefined
15
16
  currentVersionLabel: string | undefined
16
17
  availableVersions: VersionOption[]
17
- handleVersionChange: (version: string) => void
18
+ handleVersionChange: (version: BoltdocsVersion) => void
18
19
  }
19
20
 
20
21
  /**
@@ -34,9 +35,21 @@ export function useVersion(): UseVersionReturn {
34
35
  // Update store
35
36
  setVersion(version)
36
37
 
37
- let targetPath = `/docs/${version}`
38
+ // If we are on the home page or a path that doesn't belong to the documentation,
39
+ // we stay on the current page.
40
+ const localePaths = config.i18n ? Object.keys(config.i18n.locales).map(l => `/${l}`) : []
41
+ const isHome = !currentRoute ||
42
+ currentRoute.path === '/' ||
43
+ currentRoute.path === config.base ||
44
+ currentRoute.path === '' ||
45
+ localePaths.includes(currentRoute.path)
46
+
47
+ if (isHome) {
48
+ return
49
+ }
38
50
 
39
51
  if (currentRoute) {
52
+ let targetPath = `/docs/${version}`
40
53
  const baseFile = getBaseFilePath(
41
54
  currentRoute.filePath,
42
55
  currentRoute.version,
@@ -63,9 +76,9 @@ export function useVersion(): UseVersionReturn {
63
76
  ? versionIndexRoute.path
64
77
  : `/docs/${version}${currentLocale ? `/${currentLocale}` : ''}`
65
78
  }
79
+
80
+ navigate(targetPath)
66
81
  }
67
-
68
- navigate(targetPath)
69
82
  }
70
83
 
71
84
  const availableVersions = routeContext.availableVersions.map((v) => ({
@@ -2,6 +2,7 @@ export type {
2
2
  ComponentRoute,
3
3
  LayoutProps,
4
4
  } from './types'
5
+ export type { BoltdocsLocale, BoltdocsVersion, BoltdocsTypes } from '../shared/types'
5
6
  export * from './ssg'
6
7
  export { useConfig } from './app/config-context'
7
8
  export { useTheme } from './app/theme-context'
@@ -1,10 +1,11 @@
1
1
  import { useEffect, useMemo } from 'react'
2
+ import type { ComponentType, ReactNode } from 'react'
2
3
  import { Outlet, useLocation, useNavigate } from 'react-router-dom'
3
4
  import { RouterProvider } from 'react-aria-components'
4
5
  import { BoltdocsProvider, useBoltdocsContext } from '../store/boltdocs-context'
5
6
  import { ThemeProvider } from '../app/theme-context'
6
7
  import { MdxComponentsProvider } from '../app/mdx-components-context'
7
- import { HelmetProvider } from 'react-helmet-async'
8
+ import * as ReactHelmetAsync from 'react-helmet-async'
8
9
  import { ConfigContext } from '../app/config-context'
9
10
  import { ScrollHandler } from '../app/scroll-handler'
10
11
  import { mdxComponentsDefault } from '../app/mdx-component'
@@ -14,6 +15,16 @@ import type { ComponentRoute } from '../types'
14
15
 
15
16
  import virtualCustomComponents from 'virtual:boltdocs-mdx-components'
16
17
 
18
+ type HelmetProviderModule = {
19
+ HelmetProvider?: ComponentType<{ children?: ReactNode }>
20
+ default?: { HelmetProvider?: ComponentType<{ children?: ReactNode }> }
21
+ }
22
+ const helmetProviderModule = ReactHelmetAsync as unknown as HelmetProviderModule
23
+ const HelmetProvider =
24
+ helmetProviderModule.HelmetProvider
25
+ || helmetProviderModule.default?.HelmetProvider
26
+ || (({ children }) => <>{children}</>)
27
+
17
28
  /**
18
29
  * Updates the HTML lang and dir attributes based on the current locale configuration.
19
30
  */
@@ -60,12 +71,15 @@ function StoreSync({ config }: { config: BoltdocsConfig }) {
60
71
  }
61
72
 
62
73
  // 2. Locale detection
63
- if (
64
- config.i18n &&
65
- parts.length > cIdx &&
66
- config.i18n.locales[parts[cIdx]]
67
- ) {
68
- detectedLocale = parts[cIdx]
74
+ if (config.i18n && parts.length > cIdx) {
75
+ const potentialLocale = parts[cIdx]
76
+ const isLocale = Array.isArray(config.i18n.locales)
77
+ ? config.i18n.locales.includes(potentialLocale)
78
+ : !!config.i18n.locales[potentialLocale]
79
+
80
+ if (isLocale) {
81
+ detectedLocale = potentialLocale
82
+ }
69
83
  } else if (config.i18n && parts.length === 0) {
70
84
  detectedLocale = currentLocale || config.i18n.defaultLocale
71
85
  }
@@ -103,25 +117,43 @@ export function BoltdocsShell({
103
117
  )
104
118
 
105
119
  const navigate = useNavigate()
120
+ const { pathname } = useLocation()
121
+
122
+ const currentPath = useMemo(() => {
123
+ const p = pathname || '/'
124
+ return p.endsWith('/') && p.length > 1 ? p.slice(0, -1) : p
125
+ }, [pathname])
126
+
127
+ const currentRoute = useMemo(() =>
128
+ routes.find((r) => {
129
+ const rp = r.path === '' ? '/' : r.path
130
+ const normalize = (path: string) => path.endsWith('/') && path.length > 1 ? path.slice(0, -1) : path
131
+ return normalize(rp) === currentPath
132
+ }),
133
+ [routes, currentPath]
134
+ )
106
135
 
107
136
  return (
108
137
  <HelmetProvider>
109
- <BoltdocsProvider>
138
+ <RoutesProvider routes={routes}>
110
139
  <ThemeProvider>
111
140
  <MdxComponentsProvider components={allComponents}>
112
141
  <ConfigContext.Provider value={config}>
113
- <RoutesProvider routes={routes}>
114
- <RouterProvider navigate={navigate}>
115
- <ScrollHandler />
142
+ <RouterProvider navigate={navigate}>
143
+ <ScrollHandler />
144
+ <BoltdocsProvider
145
+ initialLocale={currentRoute?.locale}
146
+ initialVersion={currentRoute?.version}
147
+ >
116
148
  <StoreSync config={config} />
117
149
  <I18nUpdater config={config} />
118
150
  <Outlet />
119
- </RouterProvider>
120
- </RoutesProvider>
151
+ </BoltdocsProvider>
152
+ </RouterProvider>
121
153
  </ConfigContext.Provider>
122
154
  </MdxComponentsProvider>
123
155
  </ThemeProvider>
124
- </BoltdocsProvider>
156
+ </RoutesProvider>
125
157
  </HelmetProvider>
126
158
  )
127
159
  }
@@ -23,11 +23,21 @@ function findModuleKey(
23
23
  filePath: string,
24
24
  ): string | undefined {
25
25
  const normalizedFilePath = filePath.replace(/\\/g, '/')
26
- return Object.keys(modules).find(
27
- (key) =>
28
- key.endsWith(`/${normalizedFilePath}`) ||
29
- key.endsWith(normalizedFilePath),
30
- )
26
+ const keys = Object.keys(modules)
27
+ if (keys.length === 0) return undefined
28
+
29
+ // Detect docs directory from keys (e.g., "/docs/...")
30
+ const firstKey = keys[0].replace(/\\/g, '/')
31
+ const parts = firstKey.split('/').filter(Boolean)
32
+ const docsDirName = parts[0] || 'docs'
33
+
34
+ const targetKey = `/${docsDirName}/${normalizedFilePath}`
35
+ const targetKeyAlt = `./${docsDirName}/${normalizedFilePath}`
36
+
37
+ return keys.find((key) => {
38
+ const k = key.replace(/\\/g, '/')
39
+ return k === targetKey || k === targetKeyAlt || k.endsWith(targetKey)
40
+ })
31
41
  }
32
42
 
33
43
  export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
@@ -53,6 +63,8 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
53
63
  return `${b}${p}` || '/'
54
64
  }
55
65
 
66
+ const allMetadata: ComponentRoute[] = [...routesData]
67
+
56
68
  // 1. Documentation routes
57
69
  const docRoutes: RouteRecord[] = routesData.map((route) => {
58
70
  const moduleKey = findModuleKey(mdxModules, route.filePath)
@@ -86,16 +98,24 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
86
98
 
87
99
  // 2. Home page route
88
100
  if (HomePage) {
89
- const homePaths = [withBase('/')]
101
+ const homeConfigs = [{ path: withBase('/'), locale: config.i18n?.defaultLocale }]
90
102
  if (config.i18n) {
91
103
  Object.keys(config.i18n.locales).forEach((locale) => {
92
- homePaths.push(withBase(`/${locale}`))
104
+ homeConfigs.push({ path: withBase(`/${locale}`), locale })
93
105
  })
94
106
  }
95
107
 
96
- homePaths.forEach((path) => {
108
+ homeConfigs.forEach(({ path, locale }) => {
97
109
  // Avoid duplicate routes if documentation also maps to '/'
98
110
  if (!children.find((r) => r.path === path)) {
111
+ allMetadata.push({
112
+ path,
113
+ locale,
114
+ title: 'Home',
115
+ filePath: '',
116
+ headings: [],
117
+ } as any)
118
+
99
119
  children.push({
100
120
  path,
101
121
  element: (
@@ -103,6 +123,10 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
103
123
  <HomePage />
104
124
  </EffectiveExternalLayout>
105
125
  ),
126
+ loader: async () => ({
127
+ path,
128
+ locale,
129
+ }),
106
130
  getStaticPaths: () => [path],
107
131
  })
108
132
  }
@@ -114,6 +138,14 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
114
138
  Object.entries(externalPages).forEach(([rawPath, ExtComponent]) => {
115
139
  const path = withBase(rawPath)
116
140
  if (!children.find((r) => r.path === path)) {
141
+ allMetadata.push({
142
+ path,
143
+ locale: config.i18n?.defaultLocale,
144
+ title: rawPath,
145
+ filePath: '',
146
+ headings: [],
147
+ } as any)
148
+
117
149
  children.push({
118
150
  path,
119
151
  element: (
@@ -121,6 +153,10 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
121
153
  <ExtComponent />
122
154
  </EffectiveExternalLayout>
123
155
  ),
156
+ loader: async () => ({
157
+ path,
158
+ locale: config.i18n?.defaultLocale,
159
+ }),
124
160
  getStaticPaths: () => [path],
125
161
  })
126
162
 
@@ -131,6 +167,14 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
131
167
  `/${locale}${rawPath === '/' ? '' : rawPath}`,
132
168
  )
133
169
  if (!children.find((r) => r.path === localePath)) {
170
+ allMetadata.push({
171
+ path: localePath,
172
+ locale,
173
+ title: rawPath,
174
+ filePath: '',
175
+ headings: [],
176
+ } as any)
177
+
134
178
  children.push({
135
179
  path: localePath,
136
180
  element: (
@@ -138,6 +182,10 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
138
182
  <ExtComponent />
139
183
  </EffectiveExternalLayout>
140
184
  ),
185
+ loader: async () => ({
186
+ path: localePath,
187
+ locale,
188
+ }),
141
189
  getStaticPaths: () => [localePath],
142
190
  })
143
191
  }
@@ -157,10 +205,6 @@ export function createRoutes(options: CreateRoutesOptions): RouteRecord[] {
157
205
  ),
158
206
  })
159
207
 
160
- // --- 5. Construct Metadata for UI Providers ---
161
- // We need to pass the full metadata to BoltdocsShell so that Sidebar/Tabs can work.
162
- const allMetadata: ComponentRoute[] = [...routesData]
163
-
164
208
  // Wrap everything in the Boltdocs shell (providers)
165
209
  return [
166
210
  {
@@ -18,17 +18,36 @@ const BoltdocsContext =
18
18
  BoltdocsState | undefined
19
19
  >(undefined))
20
20
 
21
- export function BoltdocsProvider({ children }: { children: React.ReactNode }) {
22
- const [locale, setLocale] = useState('')
23
- const [version, setVersion] = useState('')
21
+ export function BoltdocsProvider({
22
+ children,
23
+ initialLocale = '',
24
+ initialVersion = '',
25
+ }: {
26
+ children: React.ReactNode
27
+ initialLocale?: string
28
+ initialVersion?: string
29
+ }) {
30
+ const getInitialState = () => {
31
+ if (typeof window === 'undefined')
32
+ return { locale: initialLocale, version: initialVersion }
33
+ const parts = window.location.pathname.split('/').filter(Boolean)
34
+ let locale = initialLocale
35
+ let version = initialVersion
36
+ // ...
37
+ return { locale, version }
38
+ }
39
+
40
+ const initialState = getInitialState()
41
+ const [locale, setLocale] = useState(initialState.locale)
42
+ const [version, setVersion] = useState(initialState.version)
24
43
  const [hasHydrated, setHasHydrated] = useState(false)
25
44
 
26
45
  const value = useMemo(
27
46
  () => ({
28
47
  currentLocale: locale,
29
48
  currentVersion: version,
30
- setLocale,
31
- setVersion,
49
+ setLocale: (l: string) => setLocale(l || ''),
50
+ setVersion: (v: string) => setVersion(v || ''),
32
51
  hasHydrated,
33
52
  setHasHydrated,
34
53
  }),
@@ -35,7 +35,7 @@ export interface BoltdocsThemeConfig {
35
35
  href: string
36
36
  }>
37
37
  sidebar?: Record<string, Array<{ text: string; link: string }>>
38
- sidebarGroups?: Record<string, { title?: string; icon?: string }>
38
+ sidebarGroups?: Record<string, { title?: string | Record<string, string>; icon?: string }>
39
39
  socialLinks?: BoltdocsSocialLink[]
40
40
  footer?: BoltdocsFooterConfig
41
41
  breadcrumbs?: boolean
@@ -95,7 +95,7 @@ export interface BoltdocsLocaleConfig {
95
95
  */
96
96
  export interface BoltdocsI18nConfig {
97
97
  defaultLocale: string
98
- locales: Record<string, string>
98
+ locales: string[] | Record<string, string>
99
99
  localeConfigs?: Record<string, BoltdocsLocaleConfig>
100
100
  }
101
101
 
@@ -169,3 +169,19 @@ export interface BoltdocsConfig {
169
169
  seo?: BoltdocsSeoConfig
170
170
  vite?: any // Avoid pulling in entire Vite types here
171
171
  }
172
+
173
+ /**
174
+ * Global namespace for Boltdocs types that can be augmented by generated code.
175
+ * This allows for strictly typed locales and versions based on the project configuration.
176
+ */
177
+ declare global {
178
+ namespace Boltdocs {
179
+ interface Types {}
180
+ }
181
+ }
182
+
183
+ export type BoltdocsTypes = Boltdocs.Types
184
+
185
+ export type BoltdocsLocale = Boltdocs.Types extends { Locale: infer L } ? L : string
186
+ export type BoltdocsVersion = Boltdocs.Types extends { Version: infer V } ? V : string
187
+