Customization Guide
Customization Guide
Section titled “Customization Guide”This page is retained for compatibility. Canonical docs:
- User configuration guide: ../../../user/luthor/presets-and-configuration.md
- Extensive editor guide: ../../../user/luthor/extensive-editor.md
- Developer architecture: ../../../developer/luthor/architecture.md
- Developer source map: ../../../developer/luthor/source-file-reference.md
This guide still includes practical customization patterns.
1) Layout Manipulation
Section titled “1) Layout Manipulation”Horizontally center toolbar buttons
Section titled “Horizontally center toolbar buttons”Toolbar accepts a classNames object, so you can provide your own class hooks and center sections with CSS.
import { Toolbar } from "@lyfie/luthor";
<Toolbar commands={commands} hasExtension={hasExtension} activeStates={activeStates} isDark={isDark} toggleTheme={toggleTheme} onCommandPaletteOpen={() => commands.showCommandPalette()} classNames={{ toolbar: "my-toolbar", section: "my-toolbar-section", }}/>.my-toolbar { justify-content: center;}
.my-toolbar-section { justify-content: center;}Override mode tab labels
Section titled “Override mode tab labels”ModeTabs supports label overrides:
import { ModeTabs } from "@lyfie/luthor";
<ModeTabs mode={mode} onModeChange={setMode} labels={{ visual: "Editor", html: "Source (HTML)", markdown: "Source (MD)", }}/>2) Theming (colors + styles)
Section titled “2) Theming (colors + styles)”The default extensive/core style layer uses CSS variables. You can override them via wrapper selectors.
.my-editor[data-editor-theme="light"] { --luthor-bg: #ffffff; --luthor-fg: #111827; --luthor-border: #d1d5db; --luthor-accent: #111827;}
.my-editor[data-editor-theme="dark"] { --luthor-bg: #0a0a0a; --luthor-fg: #f5f5f5; --luthor-border: #2a2a2a; --luthor-accent: #f5f5f5;}Use your custom class on the editor wrapper:
<ExtensiveEditor className="my-editor" />3) Composition: build your own preset from core
Section titled “3) Composition: build your own preset from core”You can reuse core modules and wire a custom editor shell:
Toolbarfor top actions.FloatingToolbarviacreateFloatingToolbarExtension+setFloatingToolbarContext.CommandPalettepluscommandsToCommandPaletteItemsandregisterKeyboardShortcuts.ModeTabs+SourceViewfor visual/source layout switching.createPresetEditorConfigfor consistent classNames/placeholder wiring in custom preset definitions.
Example composition flow
Section titled “Example composition flow”- Create an extension list (choose any subset).
- Create editor system provider from headless.
- Use
Toolbar+CommandPalettein your editor shell. - Feed command palette items from
commandsToCommandPaletteItems(commands). - Register keyboard shortcuts with
registerKeyboardShortcuts(commands). - Share theme/active state with floating toolbar bridge using
setFloatingToolbarContext(...).
This gives preset authors full control over feature mix while reusing a stable, typed core implementation.
4) Font Select (whitelist + loading strategy)
Section titled “4) Font Select (whitelist + loading strategy)”fontFamilyExtension supports a controlled font whitelist and optional CSS loading.
import { fontFamilyExtension } from "@lyfie/luthor-headless";
const configuredFontExtension = fontFamilyExtension.configure({ options: [ { value: "default", label: "Default", fontFamily: "inherit" }, { value: "inter", label: "Inter", fontFamily: "'Inter', 'Segoe UI', Arial, sans-serif", cssImportUrl: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap", }, ], cssLoadStrategy: "on-demand", // "none" | "preload-all"});optionsis the source of truth for selectable fonts.cssLoadStrategy: "on-demand"injectscssImportUrlonly when a font is used.cssLoadStrategy: "preload-all"eagerly loads all configured font CSS at startup.