1"use strict";(globalThis.rspackChunkwebsite||=[]).push([[109],{72441(e,n,s){s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>u});var i=JSON.parse('{"id":"guides/docs/multi-instance","title":"Docs Multi-instance","description":"Use multiple docs plugin instances on a single Docusaurus site.","source":"@site/versioned_docs/version-3.0.1/guides/docs/docs-multi-instance.mdx","sourceDirName":"guides/docs","slug":"/docs-multi-instance","permalink":"/docs/3.0.1/docs-multi-instance","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/edit/main/website/docs/guides/docs/docs-multi-instance.mdx","tags":[],"version":"3.0.1","lastUpdatedBy":"S\xe9bastien Lorber","lastUpdatedAt":1772830092000,"frontMatter":{"id":"multi-instance","description":"Use multiple docs plugin instances on a single Docusaurus site.","slug":"/docs-multi-instance"},"sidebar":"docs","previous":{"title":"Versioning","permalink":"/docs/3.0.1/versioning"},"next":{"title":"Blog","permalink":"/docs/3.0.1/blog"}}'),t=s(61058),r=s(24801),a=s(65855),o=s(49714);let l={id:"multi-instance",description:"Use multiple docs plugin instances on a single Docusaurus site.",slug:"/docs-multi-instance"},c="Docs Multi-instance",d={},u=[{value:"Use-cases",id:"use-cases",level:2},{value:"Mobile SDKs documentation",id:"mobile-sdks-documentation",level:3},{value:"Versioned and unversioned doc",id:"versioned-and-unversioned-doc",level:3},{value:"Setup",id:"setup",level:2},{value:"Versioned paths",id:"versioned-paths",level:2},{value:"Tagging new versions",id:"tagging-new-versions",level:2},{value:"Docs navbar items",id:"docs-navbar-items",level:2}];function h(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"docs-multi-instance",children:"Docs Multi-instance"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"@docusaurus/plugin-content-docs"})," plugin can support ",(0,t.jsx)(n.a,{href:"/docs/3.0.1/using-plugins#multi-instance-plugins-and-plugin-ids",children:"multi-instance"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This feature is only useful for ",(0,t.jsx)(n.a,{href:"/docs/3.0.1/versioning",children:"versioned documentation"}),". It is recommended to be familiar with docs versioning before reading this page. If you just want ",(0,t.jsx)(n.a,{href:"/docs/3.0.1/sidebar/multiple-sidebars",children:"multiple sidebars"}),", you can do so within one plugin."]})}),"\n",(0,t.jsx)(n.h2,{id:"use-cases",children:"Use-cases"}),"\n",(0,t.jsx)(n.p,{children:"Sometimes you want a Docusaurus site to host 2 distinct sets of documentation (or more)."}),"\n",(0,t.jsx)(n.p,{children:"These documentations may even have different versioning/release lifecycles."}),"\n",(0,t.jsx)(n.h3,{id:"mobile-sdks-documentation",children:"Mobile SDKs documentation"}),"\n",(0,t.jsx)(n.p,{children:"If you build a cross-platform mobile SDK, you may have 2 documentations:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Android SDK documentation (",(0,t.jsx)(n.code,{children:"v1.0"}),", ",(0,t.jsx)(n.code,{children:"v1.1"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:["iOS SDK documentation (",(0,t.jsx)(n.code,{children:"v1.0"}),", ",(0,t.jsx)(n.code,{children:"v2.0"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"In this case, you can use a distinct docs plugin instance per mobile SDK documentation."}),"\n",(0,t.jsxs)(n.admonition,{type:"warning",children:[(0,t.jsx)(n.p,{children:"If each documentation instance is very large, you should rather create 2 distinct Docusaurus sites."}),(0,t.jsx)(n.p,{children:"If someone edits the iOS documentation, is it really useful to rebuild everything, including the whole Android documentation that did not change?"})]}),"\n",(0,t.jsx)(n.h3,{id:"versioned-and-unversioned-doc",children:"Versioned and unversioned doc"}),"\n",(0,t.jsx)(n.p,{children:'Sometimes, you want some documents to be versioned, while other documents are more "global", and it feels useless to version them.'}),"\n",(0,t.jsx)(n.p,{children:"We use this pattern on the Docusaurus website itself:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/docs",children:"/docs/*"})," section is versioned"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/community/support",children:"/community/*"})," section is unversioned"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,t.jsx)(n.p,{children:"Suppose you have 2 documentations:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Product: some versioned doc about your product"}),"\n",(0,t.jsx)(n.li,{children:"Community: some unversioned doc about the community around your product"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"In this case, you should use the same plugin t
1wice in your site configuration."}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"@docusaurus/preset-classic"})," already includes a docs plugin instance for you!"]})}),"\n",(0,t.jsx)(n.p,{children:"When using the preset:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config.js"',children:"export default {\n presets: [\n [\n '@docusaurus/preset-classic',\n {\n docs: {\n // highlight-start\n // id: 'product', // omitted => default instance\n // highlight-end\n path: 'product',\n routeBasePath: 'product',\n sidebarPath: './sidebarsProduct.js',\n // ... other options\n },\n },\n ],\n ],\n plugins: [\n [\n '@docusaurus/plugin-content-docs',\n {\n // highlight-start\n id: 'community',\n // highlight-end\n path: 'community',\n routeBasePath: 'community',\n sidebarPath: './sidebarsCommunity.js',\n // ... other options\n },\n ],\n ],\n};\n"})}),"\n",(0,t.jsx)(n.p,{children:"When not using the preset:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config.js"',children:"export default {\n plugins: [\n [\n '@docusaurus/plugin-content-docs',\n {\n // highlight-start\n // id: 'product', // omitted => default instance\n // highlight-end\n path: 'product',\n routeBasePath: 'product',\n sidebarPath: './sidebarsProduct.js',\n // ... other options\n },\n ],\n [\n '@docusaurus/plugin-content-docs',\n {\n // highlight-start\n id: 'community',\n // highlight-end\n path: 'community',\n routeBasePath: 'community',\n sidebarPath: './sidebarsCommunity.js',\n // ... other options\n },\n ],\n ],\n};\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Don't forget to assign a unique ",(0,t.jsx)(n.code,{children:"id"})," attribute to plugin instances."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["We consider that the ",(0,t.jsx)(n.code,{children:"product"}),' instance is the most important one, and make it the "default" instance by not assigning any ID.']})}),"\n",(0,t.jsx)(n.h2,{id:"versioned-paths",children:"Versioned paths"}),"\n",(0,t.jsx)(n.p,{children:"Each plugin instance will store versioned docs in a distinct folder."}),"\n",(0,t.jsx)(n.p,{children:"The default plugin instance will use these paths:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/versions.json"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/versioned_docs"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/versioned_sidebars"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The other plugin instances (with an ",(0,t.jsx)(n.code,{children:"id"})," attribute) will use these paths:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/[pluginId]_versions.json"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/[pluginId]_versioned_docs"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"website/[pluginId]_versioned_sidebars"})}),"\n"]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsxs)(n.p,{children:["You can omit the ",(0,t.jsx)(n.code,{children:"id"})," attribute (defaults to ",(0,t.jsx)(n.code,{children:"default"}),") for one of the docs plugin instances."]}),(0,t.jsx)(n.p,{children:"The instance paths will be simpler, and retro-compatible with a single-instance setup."})]}),"\n",(0,t.jsx)(n.h2,{id:"tagging-new-versions",children:"Tagging new versions"}),"\n",(0,t.jsx)(n.p,{children:"Each plugin instance will have its own CLI command to tag a new version. They will be displayed if you run:"}),"\n",(0,t.jsxs)(a.A,{groupId:"npm2yarn",children:[(0,t.jsx)(o.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run docusaurus -- --help\n"})})}),(0,t.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn docusaurus --help\n"})})}),(0,t.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pnpm run docusaurus --help\n"})})}),(0,t.jsx)(o.A,{value:"bun",label:"Bun",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bun run docusaurus --help\n"})})})]}
1),"\n",(0,t.jsx)(n.p,{children:"To version the product/default docs plugin instance:"}),"\n",(0,t.jsxs)(a.A,{groupId:"npm2yarn",children:[(0,t.jsx)(o.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run docusaurus docs:version 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn docusaurus docs:version 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pnpm run docusaurus docs:version 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"bun",label:"Bun",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bun run docusaurus docs:version 1.0.0\n"})})})]}),"\n",(0,t.jsx)(n.p,{children:"To version the non-default/community docs plugin instance:"}),"\n",(0,t.jsxs)(a.A,{groupId:"npm2yarn",children:[(0,t.jsx)(o.A,{value:"npm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run docusaurus docs:version:community 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"yarn",label:"Yarn",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn docusaurus docs:version:community 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"pnpm",label:"pnpm",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pnpm run docusaurus docs:version:community 1.0.0\n"})})}),(0,t.jsx)(o.A,{value:"bun",label:"Bun",children:(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bun run docusaurus docs:version:community 1.0.0\n"})})})]}),"\n",(0,t.jsx)(n.h2,{id:"docs-navbar-items",children:"Docs navbar items"}),"\n",(0,t.jsxs)(n.p,{children:["Each docs-related ",(0,t.jsx)(n.a,{href:"/docs/3.0.1/api/themes/configuration#navbar",children:"theme navbar items"})," take an optional ",(0,t.jsx)(n.code,{children:"docsPluginId"})," attribute."]}),"\n",(0,t.jsx)(n.p,{children:"For example, if you want to have one version dropdown for each mobile SDK (iOS and Android), you could do:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config.js"',children:"export default {\n themeConfig: {\n navbar: {\n items: [\n {\n type: 'docsVersionDropdown',\n // highlight-start\n docsPluginId: 'ios',\n // highlight-end\n },\n {\n type: 'docsVersionDropdown',\n // highlight-start\n docsPluginId: 'android',\n // highlight-end\n },\n ],\n },\n },\n};\n"})})]})}function p(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},49714(e,n,s){s.d(n,{A:()=>o});var i=s(61058);s(13706);var t=s(23372),r=s(25237);function a({children:e,className:n,hidden:s}){return(0,i.jsx)("div",{role:"tabpanel",className:(0,t.A)("tabItem_pnkT",n),hidden:s,children:e})}function o({children:e,className:n,value:s}){let{selectedValue:t,lazy:l}=(0,r.uc)(),c=s===t;return!c&&l?null:(0,i.jsx)(a,{className:n,hidden:!c,children:e})}},65855(e,n,s){s.d(n,{A:()=>h});var i=s(61058);s(13706);var t=s(23372),r=s(2445),a=s(25237),o=s(70662),l=s(73749);function c({className:e}){let{selectedValue:n,selectValue:s,tabValues:r,block:l}=(0,a.uc)(),d=[],{blockElementScrollPositionUntilNextRender:u}=(0,o.a_)(),h=e=>{let i=e.currentTarget,t=r[d.indexOf(i)].value;t!==n&&(u(i),s(t))},p=e=>{let n=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{let s=d.indexOf(e.currentTarget)+1;n=d[s]??d[0];break}case"ArrowLeft":{let s=d.indexOf(e.currentTarget)-1;n=d[s]??d[d.length-1]}}n?.focus()};return(0,i.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":l},e),children:r.map(({value:e,label:s,attributes:r})=>(0,i.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{d.push(e)},onKeyDown:p,onClick:h,...r,className:(0,t.A)("tabs__item","tabItem_AQgk",r?.className,{"tabs__item--active":n===e}),children:s??e},e))})}function d({children:e}){return(0,i.jsx)("div",{className:"margin-top--md",children:e})}function u({className:e,children:n}){return(0,i.jsxs)("div",{className:(0,t.A)(r.G.tabs.container,"tabs-container","tabList_Qoir"),children:[(0,i.jsx)(c,{className:e}),(0,i.jsx)(d,{children:n})]})}function h(e){let n=(0,l.A)(),s=(0,a.OC)(e);return(0,i.jsx)(a.O_,{value:s,children:(0,i.jsx)(u,{className:e.className,children:(0,a.vT)(e.children)})},String(n))}},25237(e,n,s){s.d(n,{OC:()=>u,O_:()=>m,uc:()=>p,vT:()=>c});var i=s(61058),t=s(13706),r=s(90577),a=s(27611),o=s(78328),l=s(87116);function c(e){return t.Children.toArray(e).filter(e=>"\n"!==e)}function d({value:e,tabValues:n}){return n.some(n=>n.value===e)}function u(e){let n,{defaultValue:s,queryString:i=!1,groupId:c}=e,u=function(e){let{values:n,children:s}=e;return(0,t.useMemo)(()=>{let e=n??t.Children.toArray(s).flatMap(e=>{if(!e)return[];if((0,t.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return[e];
1let n="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${n}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop. 2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:n,attributes:s,default:i}})=>({value:e,label:n,attributes:s,default:i})),i=(0,o.XI)(e,(e,n)=>e.value===n.value);if(i.length>0)throw Error(`Docusaurus error: Duplicate values "${i.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,s])}(e),[h,p]=(0,t.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!d({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let s=n.find(e=>e.default)??n[0];if(!s)throw Error("Unexpected error: 0 tabValues");return s.value})({defaultValue:s,tabValues:u})),[m,g]=function({queryString:e=!1,groupId:n}){let s=(0,r.W6)(),i=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,a.aZ)(i),(0,t.useCallback)(e=>{if(!i)return;let n=new URLSearchParams(s.location.search);n.set(i,e),s.replace({...s.location,search:n.toString()})},[i,s])]}({queryString:i,groupId:c}),[x,j]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[s,i]=(0,l.Dv)(n);return[s,(0,t.useCallback)(e=>{n&&i.set(e)},[n,i])]}({groupId:c}),v=d({value:n=m??x,tabValues:u})?n:null;return(0,t.useLayoutEffect)(()=>{v&&p(v)},[v]),{selectedValue:h,selectValue:(0,t.useCallback)(e=>{if(!d({value:e,tabValues:u}))throw Error(`Can't select invalid tab value=${e}`);p(e),g(e),j(e)},[g,j,u]),tabValues:u,lazy:e.lazy??!1,block:e.block??!1}}let h=(0,t.createContext)(null);function p(){let e=t.useContext(h);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function m(e){return(0,i.jsx)(h,{value:e.value,children:e.children})}},24801(e,n,s){var i=s(13706);let t={},r=i.createContext(t);function a(e){let n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(r.Provider,{value:n},e.children)}s.d(n,{R:()=>a,x:()=>o})}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.