"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[64636],{15995:(e,n,t)=>{t.d(n,{A:()=>r});var s=t(62540);t(63696);var o=t(11750);function r({children:e,hidden:n,className:t}){return(0,s.jsx)("div",{role:"tabpanel",className:(0,o.A)("tabItem_pnkT",t),hidden:n,children:e})}},27446:(e,n,t)=>{t.d(n,{A:()=>y});var s=t(62540),o=t(63696),r=t(11750),i=t(7846),a=t(49519),l=t(96439),c=t(19739),h=t(66904),d=t(79244);function u(e){var n,t;return null!==(t=null===(n=o.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,o.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))||void 0===n?void 0:n.filter(Boolean))&&void 0!==t?t:[]}function p({value:e,tabValues:n}){return n.some(n=>n.value===e)}var m=t(10709);function j(e){for(var n=1;n{let n=e.currentTarget,s=a[l.indexOf(n)].value;s!==t&&(c(n),o(s))},d=e=>{var n,t;let s=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{let t=l.indexOf(e.currentTarget)+1;s=null!==(n=l[t])&&void 0!==n?n:l[0];break}case"ArrowLeft":{let n=l.indexOf(e.currentTarget)-1;s=null!==(t=l[n])&&void 0!==t?t:l[l.length-1]}}null==s||s.focus()};return(0,s.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":n},e),children:a.map(({value:e,label:n,attributes:o})=>(0,s.jsx)("li",g(j({role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>l.push(e),onKeyDown:d,onClick:h},o),{className:(0,r.A)("tabs__item","tabItem_AQgk",null==o?void 0:o.className,{"tabs__item--active":t===e}),children:null!=n?n:e}),e))})}function f({lazy:e,children:n,selectedValue:t}){let i=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){let e=i.find(e=>e.props.value===t);return e?(0,o.cloneElement)(e,{className:(0,r.A)("margin-top--md",e.props.className)}):null}return(0,s.jsx)("div",{className:"margin-top--md",children:i.map((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==t}))})}function w(e){let n=function(e){let{defaultValue:n,queryString:t=!1,groupId:s}=e,r=function(e){let{values:n,children:t}=e;return(0,o.useMemo)(()=>{let e=null!=n?n:u(t).map(({props:{value:e,label:n,attributes:t,default:s}})=>({value:e,label:n,attributes:t,default:s}));return!function(e){let n=(0,h.XI)(e,(e,n)=>e.value===n.value);if(n.length>0)throw Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in . Every value needs to be unique.`)}(e),e},[n,t])}(e),[i,m]=(0,o.useState)(()=>(function({defaultValue:e,tabValues:n}){var t;if(0===n.length)throw Error("Docusaurus error: the component requires at least one children component");if(e){if(!p({value:e,tabValues:n}))throw Error(`Docusaurus error: The 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=null!==(t=n.find(e=>e.default))&&void 0!==t?t:n[0];if(!s)throw Error("Unexpected error: 0 tabValues");return s.value})({defaultValue:n,tabValues:r})),[j,g]=function({queryString:e=!1,groupId:n}){let t=(0,a.W6)(),s=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 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 null!=n?n:null}({queryString:e,groupId:n});return[(0,c.aZ)(s),(0,o.useCallback)(e=>{var n,o;if(!s)return;let r=new URLSearchParams(t.location.search);r.set(s,e),t.replace((n=function(e){for(var n=1;n{n&&s.set(e)},[n,s])]}({groupId:s}),w=(()=>{let e=null!=j?j:x;return p({value:e,tabValues:r})?e:null})();return(0,l.A)(()=>{w&&m(w)},[w]),{selectedValue:i,selectValue:(0,o.useCallback)(e=>{if(!p({value:e,tabValues:r}))throw Error(`Can't select invalid tab value=${e}`);m(e),g(e),f(e)},[g,f,r]),tabValues:r}}(e);return(0,s.jsxs)("div",{className:(0,r.A)("tabs-container","tabList_Qoir"),children:[(0,s.jsx)(x,j({},n,e)),(0,s.jsx)(f,j({},n,e))]})}function y(e){let n=(0,m.A)();return(0,s.jsx)(w,g(j({},e),{children:u(e.children)}),String(n))}},71407:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>p,frontMatter:()=>l,metadata:()=>s,toc:()=>d});let s=JSON.parse('{"id":"swizzling","title":"Swizzling","description":"Customize your site\'s appearance through creating your own theme components","source":"@site/docs/swizzling.mdx","sourceDirName":".","slug":"/swizzling","permalink":"/docs/swizzling","draft":false,"unlisted":false,"editUrl":"https://github.com/facebook/docusaurus/edit/main/website/docs/swizzling.mdx","tags":[],"version":"current","lastUpdatedBy":"S\xe9bastien Lorber","lastUpdatedAt":1725631629000,"frontMatter":{"description":"Customize your site\'s appearance through creating your own theme components"},"sidebar":"docs","previous":{"title":"Styling and Layout","permalink":"/docs/styling-layout"},"next":{"title":"Static Assets","permalink":"/docs/static-assets"}}');var o=t(62540),r=t(43023),i=t(27446),a=t(15995);let l={description:"Customize your site's appearance through creating your own theme components"},c="Swizzling",h={},d=[{value:"Swizzling Process",id:"swizzling-process",level:2},{value:"Overview",id:"overview",level:3},{value:"Ejecting",id:"ejecting",level:3},{value:"Wrapping",id:"wrapping",level:3},{value:"What is safe to swizzle?",id:"what-is-safe-to-swizzle",level:2},{value:"Which component should I swizzle?",id:"which-component-should-i-swizzle",level:2},{value:"Do I need to swizzle?",id:"do-i-need-to-swizzle",level:2},{value:"Wrapping your site with <Root>",id:"wrapper-your-site-with-root",level:2}];function u(e){let n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{Details:t}=n;return t||function(e,n){throw Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"swizzling",children:"Swizzling"})}),"\n",(0,o.jsx)(n.p,{children:"In this section, we will introduce how customization of layout is done in Docusaurus."}),"\n",(0,o.jsxs)(n.blockquote,{children:["\n",(0,o.jsx)(n.p,{children:"D\xe9j\xe0 vu...?"}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["This section is similar to ",(0,o.jsx)(n.a,{href:"/docs/styling-layout",children:"Styling and Layout"}),", but this time, we will customize React components themselves, rather than what they look like. We will talk about a central concept in Docusaurus: ",(0,o.jsx)(n.strong,{children:"swizzling"}),", which allows ",(0,o.jsx)(n.strong,{children:"deeper site customizations"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["In practice, swizzling permits to ",(0,o.jsx)(n.strong,{children:"swap a theme component with your own implementation"}),", and it comes in 2 patterns:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#ejecting",children:(0,o.jsx)(n.strong,{children:"Ejecting"})}),": creates a ",(0,o.jsx)(n.strong,{children:"copy"})," of the original theme component, which you can fully ",(0,o.jsx)(n.strong,{children:"customize"})]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#wrapping",children:(0,o.jsx)(n.strong,{children:"Wrapping"})}),": creates a ",(0,o.jsx)(n.strong,{children:"wrapper"})," around the original theme component, which you can ",(0,o.jsx)(n.strong,{children:"enhance"})]}),"\n"]}),"\n",(0,o.jsxs)(t,{children:[(0,o.jsx)("summary",{children:"Why is it called swizzling?"}),(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"The name comes from Objective-C and Swift-UI"}),": ",(0,o.jsx)(n.a,{href:"https://pspdfkit.com/blog/2019/swizzling-in-swift/",children:"method swizzling"})," is the process of changing the implementation of an existing selector (method)."]}),(0,o.jsx)(n.p,{children:(0,o.jsx)(n.strong,{children:"For Docusaurus, component swizzling means providing an alternative component that takes precedence over the component provided by the theme."})}),(0,o.jsxs)(n.p,{children:["You can think of it as ",(0,o.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Monkey_patch",children:"Monkey Patching"})," for React components, enabling you to override the default implementation. Gatsby has a similar concept called ",(0,o.jsx)(n.a,{href:"https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/shadowing/",children:"theme shadowing"}),"."]}),(0,o.jsxs)(n.p,{children:["To gain a deeper understanding of this, you have to understand ",(0,o.jsx)(n.a,{href:"/docs/advanced/client#theme-aliases",children:"how theme components are resolved"}),"."]})]}),"\n",(0,o.jsx)(n.h2,{id:"swizzling-process",children:"Swizzling Process"}),"\n",(0,o.jsx)(n.h3,{id:"overview",children:"Overview"}),"\n",(0,o.jsxs)(n.p,{children:["Docusaurus provides a convenient ",(0,o.jsx)(n.strong,{children:"interactive CLI"})," to swizzle components. You generally only need to remember the following command:"]}),"\n",(0,o.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,o.jsx)(a.A,{value:"npm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"npm run swizzle\n"})})}),(0,o.jsx)(a.A,{value:"yarn",label:"Yarn",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"yarn swizzle\n"})})}),(0,o.jsx)(a.A,{value:"pnpm",label:"pnpm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["It will generate a new component in your ",(0,o.jsx)(n.code,{children:"src/theme"})," directory, which should look like this example:"]}),"\n",(0,o.jsxs)(i.A,{children:[(0,o.jsx)(a.A,{value:"Ejecting",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-jsx",metastring:'title="src/theme/SomeComponent.js"',children:"import React from 'react';\n\nexport default function SomeComponent(props) {\n // You can fully customize this implementation\n // including changing the JSX, CSS and React hooks\n return (\n
\n

Some Component

\n

Some component implementation details

\n
\n );\n}\n"})})}),(0,o.jsx)(a.A,{value:"Wrapping",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-jsx",metastring:'title="src/theme/SomeComponent.js"',children:"import React from 'react';\nimport SomeComponent from '@theme-original/SomeComponent';\n\nexport default function SomeComponentWrapper(props) {\n // You can enhance the original component,\n // including adding extra props or JSX elements around it\n return (\n <>\n \n \n );\n}\n"})})})]}),"\n",(0,o.jsx)(n.p,{children:"To get an overview of all the themes and components available to swizzle, run:"}),"\n",(0,o.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,o.jsx)(a.A,{value:"npm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"npm run swizzle -- --list\n"})})}),(0,o.jsx)(a.A,{value:"yarn",label:"Yarn",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"yarn swizzle --list\n"})})}),(0,o.jsx)(a.A,{value:"pnpm",label:"pnpm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle --list\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["Use ",(0,o.jsx)(n.code,{children:"--help"})," to see all available CLI options, or refer to the reference ",(0,o.jsx)(n.a,{href:"/docs/cli#docusaurus-swizzle",children:"swizzle CLI documentation"}),"."]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["After swizzling a component, ",(0,o.jsx)(n.strong,{children:"restart your dev server"})," in order for Docusaurus to know about the new component."]})}),"\n",(0,o.jsx)(n.admonition,{title:"Prefer staying on the safe side",type:"warning",children:(0,o.jsxs)(n.p,{children:["Be sure to understand ",(0,o.jsxs)(n.a,{href:"#what-is-safe-to-swizzle",children:["which components are ",(0,o.jsx)(n.strong,{children:"safe to swizzle"})]}),". Some components are ",(0,o.jsx)(n.strong,{children:"internal implementation details"})," of a theme."]})}),"\n",(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"docusaurus swizzle"})," is only an automated way to help you swizzle the component. You can also create the ",(0,o.jsx)(n.code,{children:"src/theme/SomeComponent.js"})," file manually, and Docusaurus will ",(0,o.jsx)(n.a,{href:"/docs/advanced/client#theme-aliases",children:"resolve it"}),". There's no internal magic behind this command!"]})}),"\n",(0,o.jsx)(n.h3,{id:"ejecting",children:"Ejecting"}),"\n",(0,o.jsxs)(n.p,{children:["Ejecting a theme component is the process of ",(0,o.jsx)(n.strong,{children:"creating a copy"})," of the original theme component, which you can ",(0,o.jsx)(n.strong,{children:"fully customize and override"}),"."]}),"\n",(0,o.jsxs)(n.p,{children:["To eject a theme component, use the swizzle CLI interactively, or with the ",(0,o.jsx)(n.code,{children:"--eject"})," option:"]}),"\n",(0,o.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,o.jsx)(a.A,{value:"npm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"npm run swizzle [theme name] [component name] -- --eject\n"})})}),(0,o.jsx)(a.A,{value:"yarn",label:"Yarn",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"yarn swizzle [theme name] [component name] --eject\n"})})}),(0,o.jsx)(a.A,{value:"pnpm",label:"pnpm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle [theme name] [component name] --eject\n"})})})]}),"\n",(0,o.jsx)(n.p,{children:"An example:"}),"\n",(0,o.jsxs)(i.A,{groupId:"npm2yarn",children:[(0,o.jsx)(a.A,{value:"npm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"npm run swizzle @docusaurus/theme-classic Footer -- --eject\n"})})}),(0,o.jsx)(a.A,{value:"yarn",label:"Yarn",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"yarn swizzle @docusaurus/theme-classic Footer --eject\n"})})}),(0,o.jsx)(a.A,{value:"pnpm",label:"pnpm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle @docusaurus/theme-classic Footer --eject\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["This will copy the current ",(0,o.jsx)(n.code,{children:"