"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([["80934"],{59967:function(e,n,t){t.r(n),t.d(n,{metadata:()=>s,contentTitle:()=>c,default:()=>p,assets:()=>h,toc:()=>d,frontMatter:()=>l});var 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":1735224247000,"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"}}'),o=t("85893"),r=t("80980"),i=t("46291"),a=t("67860");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.a)(),...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.Z,{groupId:"npm2yarn",children:[(0,o.jsx)(a.Z,{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.Z,{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.Z,{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.Z,{children:[(0,o.jsx)(a.Z,{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.Z,{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.Z,{groupId:"npm2yarn",children:[(0,o.jsx)(a.Z,{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.Z,{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.Z,{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,{title:"Removing Unneeded Swizzled Components",type:"tip",children:(0,o.jsxs)(n.p,{children:["If you decide that a previously swizzled component is no longer necessary, you can simply remove its file(s) from the ",(0,o.jsx)(n.code,{children:"src/theme"})," directory. After removing the component, make sure to restart your development server to ensure the changes are properly reflected."]})}),"\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.Z,{groupId:"npm2yarn",children:[(0,o.jsx)(a.Z,{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.Z,{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.Z,{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.Z,{groupId:"npm2yarn",children:[(0,o.jsx)(a.Z,{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.Z,{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.Z,{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:"