"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([[81187],{61132:(e,n,t)=>{t.d(n,{Z:()=>i});var s=t(24246),o=(t(27378),t(40624));const r={tabItem:"tabItem_pnkT"};function i({children:e,hidden:n,className:t}){return(0,s.jsx)("div",{role:"tabpanel",className:(0,o.Z)(r.tabItem,t),hidden:n,children:e})}},97555:(e,n,t)=>{t.d(n,{Z:()=>O});var s=t(24246),o=t(27378),r=t(40624),i=t(75527),a=t(3620),l=t(44479),c=t(62821),h=t(52196),d=t(53589);function u(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function p(e,n){return n=null!=n?n:{},Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):function(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);n&&(s=s.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,s)}return t}(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})),e}function m(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){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new 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 j(e){const{values:n,children:t}=e;return(0,o.useMemo)((()=>{const e=null!=n?n:function(e){return m(e).map((({props:{value:e,label:n,attributes:t,default:s}})=>({value:e,label:n,attributes:t,default:s})))}(t);return function(e){const n=(0,h.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function g({value:e,tabValues:n}){return n.some((n=>n.value===e))}function x({queryString:e=!1,groupId:n}){const t=(0,a.k6)(),s=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new 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}),r=(0,c._X)(s),i=(0,o.useCallback)((e=>{if(!s)return;const n=new URLSearchParams(t.location.search);n.set(s,e),t.replace(p(function(e){for(var n=1;nfunction({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(e){if(!g({value:e,tabValues:n}))throw new 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}var t;const s=null!==(t=n.find((e=>e.default)))&&void 0!==t?t:n[0];if(!s)throw new Error("Unexpected error: 0 tabValues");return s.value}({defaultValue:n,tabValues:r}))),[c,h]=x({queryString:t,groupId:s}),[u,p]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[t,s]=(0,d.Nk)(n);return[t,(0,o.useCallback)((e=>{n&&s.set(e)}),[n,s])]}({groupId:s}),m=(()=>{const e=null!=c?c:u;return g({value:e,tabValues:r})?e:null})();(0,l.Z)((()=>{m&&a(m)}),[m]);return{selectedValue:i,selectValue:(0,o.useCallback)((e=>{if(!g({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);a(e),h(e),p(e)}),[h,p,r]),tabValues:r}}var w=t(29088);const y={tabList:"tabList_Qoir",tabItem:"tabItem_AQgk"};function b(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function z(e){for(var n=1;n{const n=e.currentTarget,s=l.indexOf(n),r=a[s].value;r!==t&&(c(n),o(r))},d=e=>{let n=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{const s=l.indexOf(e.currentTarget)+1;var t;n=null!==(t=l[s])&&void 0!==t?t:l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;var s;n=null!==(s=l[t])&&void 0!==s?s:l[l.length-1];break}}null==n||n.focus()};return(0,s.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},e),children:a.map((({value:e,label:n,attributes:o})=>(0,s.jsx)("li",v(z({role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>l.push(e),onKeyDown:d,onClick:h},o),{className:(0,r.Z)("tabs__item",y.tabItem,null==o?void 0:o.className,{"tabs__item--active":t===e}),children:null!=n?n:e}),e)))})}function S({lazy:e,children:n,selectedValue:t}){const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=r.find((e=>e.props.value===t));return e?(0,o.cloneElement)(e,{className:"margin-top--md"}):null}return(0,s.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,o.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function I(e){const n=f(e);return(0,s.jsxs)("div",{className:(0,r.Z)("tabs-container",y.tabList),children:[(0,s.jsx)(k,z({},n,e)),(0,s.jsx)(S,z({},n,e))]})}function O(e){const n=(0,w.Z)();return(0,s.jsx)(I,v(z({},e),{children:m(e.children)}),String(n))}},30141:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=t(24246),o=t(71670),r=t(97555),i=t(61132);const a={description:"Customize your site's appearance through creating your own theme components"},l="Swizzling",c={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:!1,unlisted:!1,editUrl:"https://github.com/facebook/docusaurus/edit/main/website/docs/swizzling.mdx",tags:[],version:"current",lastUpdatedBy:"Tatsunori Uchino",lastUpdatedAt:1716830654e3,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"}},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){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"swizzling",children:"Swizzling"}),"\n",(0,s.jsx)(n.p,{children:"In this section, we will introduce how customization of layout is done in Docusaurus."}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsx)(n.p,{children:"D\xe9j\xe0 vu...?"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This section is similar to ",(0,s.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,s.jsx)(n.strong,{children:"swizzling"}),", which allows ",(0,s.jsx)(n.strong,{children:"deeper site customizations"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In practice, swizzling permits to ",(0,s.jsx)(n.strong,{children:"swap a theme component with your own implementation"}),", and it comes in 2 patterns:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#ejecting",children:(0,s.jsx)(n.strong,{children:"Ejecting"})}),": creates a ",(0,s.jsx)(n.strong,{children:"copy"})," of the original theme component, which you can fully ",(0,s.jsx)(n.strong,{children:"customize"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#wrapping",children:(0,s.jsx)(n.strong,{children:"Wrapping"})}),": creates a ",(0,s.jsx)(n.strong,{children:"wrapper"})," around the original theme component, which you can ",(0,s.jsx)(n.strong,{children:"enhance"})]}),"\n"]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:"Why is it called swizzling?"}),(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"The name comes from Objective-C and Swift-UI"}),": ",(0,s.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,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"For Docusaurus, component swizzling means providing an alternative component that takes precedence over the component provided by the theme."})}),(0,s.jsxs)(n.p,{children:["You can think of it as ",(0,s.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,s.jsx)(n.a,{href:"https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/shadowing/",children:"theme shadowing"}),"."]}),(0,s.jsxs)(n.p,{children:["To gain a deeper understanding of this, you have to understand ",(0,s.jsx)(n.a,{href:"/docs/advanced/client#theme-aliases",children:"how theme components are resolved"}),"."]})]}),"\n",(0,s.jsx)(n.h2,{id:"swizzling-process",children:"Swizzling Process"}),"\n",(0,s.jsx)(n.h3,{id:"overview",children:"Overview"}),"\n",(0,s.jsxs)(n.p,{children:["Docusaurus provides a convenient ",(0,s.jsx)(n.strong,{children:"interactive CLI"})," to swizzle components. You generally only need to remember the following command:"]}),"\n",(0,s.jsxs)(r.Z,{groupId:"npm2yarn",children:[(0,s.jsx)(i.Z,{value:"npm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run swizzle\n"})})}),(0,s.jsx)(i.Z,{value:"yarn",label:"Yarn",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"yarn swizzle\n"})})}),(0,s.jsx)(i.Z,{value:"pnpm",label:"pnpm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["It will generate a new component in your ",(0,s.jsx)(n.code,{children:"src/theme"})," directory, which should look like this example:"]}),"\n",(0,s.jsxs)(r.Z,{children:[(0,s.jsx)(i.Z,{value:"Ejecting",children:(0,s.jsx)(n.pre,{children:(0,s.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,s.jsx)(i.Z,{value:"Wrapping",children:(0,s.jsx)(n.pre,{children:(0,s.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,s.jsx)(n.p,{children:"To get an overview of all the themes and components available to swizzle, run:"}),"\n",(0,s.jsxs)(r.Z,{groupId:"npm2yarn",children:[(0,s.jsx)(i.Z,{value:"npm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run swizzle -- --list\n"})})}),(0,s.jsx)(i.Z,{value:"yarn",label:"Yarn",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"yarn swizzle --list\n"})})}),(0,s.jsx)(i.Z,{value:"pnpm",label:"pnpm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle --list\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"--help"})," to see all available CLI options, or refer to the reference ",(0,s.jsx)(n.a,{href:"/docs/cli#docusaurus-swizzle",children:"swizzle CLI documentation"}),"."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["After swizzling a component, ",(0,s.jsx)(n.strong,{children:"restart your dev server"})," in order for Docusaurus to know about the new component."]})}),"\n",(0,s.jsx)(n.admonition,{title:"Prefer staying on the safe side",type:"warning",children:(0,s.jsxs)(n.p,{children:["Be sure to understand ",(0,s.jsxs)(n.a,{href:"#what-is-safe-to-swizzle",children:["which components are ",(0,s.jsx)(n.strong,{children:"safe to swizzle"})]}),". Some components are ",(0,s.jsx)(n.strong,{children:"internal implementation details"})," of a theme."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"docusaurus swizzle"})," is only an automated way to help you swizzle the component. You can also create the ",(0,s.jsx)(n.code,{children:"src/theme/SomeComponent.js"})," file manually, and Docusaurus will ",(0,s.jsx)(n.a,{href:"/docs/advanced/client#theme-aliases",children:"resolve it"}),". There's no internal magic behind this command!"]})}),"\n",(0,s.jsx)(n.h3,{id:"ejecting",children:"Ejecting"}),"\n",(0,s.jsxs)(n.p,{children:["Ejecting a theme component is the process of ",(0,s.jsx)(n.strong,{children:"creating a copy"})," of the original theme component, which you can ",(0,s.jsx)(n.strong,{children:"fully customize and override"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["To eject a theme component, use the swizzle CLI interactively, or with the ",(0,s.jsx)(n.code,{children:"--eject"})," option:"]}),"\n",(0,s.jsxs)(r.Z,{groupId:"npm2yarn",children:[(0,s.jsx)(i.Z,{value:"npm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run swizzle [theme name] [component name] -- --eject\n"})})}),(0,s.jsx)(i.Z,{value:"yarn",label:"Yarn",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"yarn swizzle [theme name] [component name] --eject\n"})})}),(0,s.jsx)(i.Z,{value:"pnpm",label:"pnpm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle [theme name] [component name] --eject\n"})})})]}),"\n",(0,s.jsx)(n.p,{children:"An example:"}),"\n",(0,s.jsxs)(r.Z,{groupId:"npm2yarn",children:[(0,s.jsx)(i.Z,{value:"npm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run swizzle @docusaurus/theme-classic Footer -- --eject\n"})})}),(0,s.jsx)(i.Z,{value:"yarn",label:"Yarn",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"yarn swizzle @docusaurus/theme-classic Footer --eject\n"})})}),(0,s.jsx)(i.Z,{value:"pnpm",label:"pnpm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"pnpm run swizzle @docusaurus/theme-classic Footer --eject\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["This will copy the current ",(0,s.jsx)(n.code,{children:"