Skip to content

RFC: Improve theming DX (swizzle) #6114

@slorber

Description

@slorber

As part of #6113, we want to improve the swizzle DX

The docusaurus swizzle command works fine but still has some major DX problems.

These are various proposals that we can work on before 2.0.

Not all these features are mandatory for v2, but for me the minimum is:

  • Refactor code
  • Refactor doc
  • docusaurus theme wrap
  • docusaurus theme override
  • Refactor getSwizzleComponentList

Code

The swizzle CLI command code is not the best part of our codebase, it is quite hard to read, not very well tested and easy to read

Proposal: as part of the current RFC, we should rewrite everything in a better way, designing a whole new DX at the same time. It should be easier than modifying the current code.

Naming

swizzle is a term that is a bit confusing. At least to me, and already saw other feedback

As a non-native English speaker, I've discovered this term in Docusaurus for the first time and had to translate it to understand what it means. Today, I'm still not sure that this translation is even correct 😅 (I translate it as melt or re-arrange 🤷‍♂️ )

Proposal: rename to docusaurus theme override or docusaurus theme copy

Documentation

The swizzle doc is part of the advanced guides, interleaved with other docs such as how to author a theme. It does not feel right to me.

We should have a dedicated place that group all the possible ways to customize a Docusaurus site in a single place: using CSS file, environment variables, swizzle...

Proposal: probably move that doc to https://docusaurus.io/docs/styling-layout#styling-approaches

wrap

docusaurus swizzle is something that you should rather use as a last resort, as you copy internal source code in your own project.

A better pattern is to use wrap a component so that you can add some logic before/after the original component.

import OriginalFooter from "@theme-original/Footer";
import React from "react";

export default function Footer(props) {
  return (
    <>
      <div>Before footer</div>
      <OriginalFooter {...props} />
    </>
  );
}

This reduces the API surface maintained by the user, ensuring retro-compatibility as long as the public API of the component (props) does not change.

Proposal: docusaurus theme wrap command. Eventually maintain

getSwizzleComponentList

This theme lifecycle is not flexible enough to convey what is our public theme API surface.

For example:

  • some components might be safe to wrap but not to override (some layout items...)
  • some components might be safe to wrap and override (icons...)

If swizzle is renamed to docusaurus theme override, this lifecycle name should also be updated.

It may be useful to provide more than 2 levels of safety? 🤔 (safe, warn, unsafe?)

When adding a new theme component, a test should ensure that we never forget to declare the level of safety for wrap/override, to prevent having an unclear public API surface.

Proposal: this needs a complete redesign. We can safely remove the existing getSwizzleComponentList, it is optional and probably not used by many community plugins anyway.

diff

When overriding theme components, we should have a way to easily inspect how our local implementation has changed compared to the upstream theme implementation.

Proposal: docusaurus theme diff to see a diff of all overridden files, with options for all at once or focusing on a single file

Problem: how to clearly identify comps that override from comps that wrap?

upgrade

Can we provide tooling so that on Docusaurus upgrades, users that override our theme are able to patch their local files?

Already mentioned in #5734 (comment)

It could work like this:

  • on docusaurus theme override, store the current version (let's say 2.3.1) in the copied file (user is expected to keep this comment)
  • on docusaurus theme upgrade: use current version (2.4.8) create a theme file diff between 2.4.8 & 2.3.1 => apply this diff to the copied file + upgrade comment to 2.4.8

Other proposed solution here: #5734

Proposal: docusaurus theme upgrade

Problem: it might be complex to build, probably not a top priority atm 🤷‍♂️

Upgrade Helper website

Users should be able to easily inspect the changes we did in our themes.

React-Native has such a helper website, allowing to see changes across 2 versions: https://react-native-community.github.io/upgrade-helper/?from=0.62.0&to=0.67.0-rc.0

When publishing changelogs and major release blog posts, we could allow our community to browse changes easily with a simple link. Users could understand faster if the upgrade requires theme changes.

Proposal: build a helper website to browse a diff online, with some useful filters (theme/plugin...)

Problem: duplicate of the diff command? Which one is the most important to build first, with the best ROI?

debug

Having a CLI command to easily inspect what are the unsafe overrides of a theme that are currently in use might be useful (particularly when we might change what is safe/unsafe over time).

This cli could do multiple things:

  • print a diff of unsafe overridden files
  • show various recommendations like replacing an override by wrap...
  • provide more useful features later

Proposal: docusaurus theme debug, docusaurus theme inspect, docusaurus theme doctor...

Problem: naming? builds on top of other features: later?


Let me know what you think, this is just a draft for now and all these proposals are very incomplete in term of design.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apprenticeIssues that are good candidates to be handled by a Docusaurus apprentice / traineeproposalThis issue is a proposal, usually non-trivial change

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions