Skip to main content

Enabling and configuring plugins

This page walks through the day-to-day operations on plugins: enabling, disabling, configuring, and dealing with side-effects.

The Plugins page

Open Plugins in the sidebar. The page has two tabs:

Plugins tab — toggleable

Lists every regular plugin (built-in and external). Each card shows:

  • Name + version + author
  • Description — what the plugin does
  • Status badge — Enabled (blue) or Disabled (grey)
  • Action buttons:
    • Enable / Disable toggle
    • Configure (only when the plugin has a settings page)
    • Learn more (only when the plugin ships a README — opens a modal)
    • Uninstall (red, only on external plugins and externalised built-ins)

Must-use tab — always-on

Lists every must-use (mu) plugin. Same card layout but:

  • A Must-use badge replaces the toggle
  • No Enable/Disable button
  • No Uninstall button
  • Configure / Learn more remain available

Enabling a plugin

For toggleable plugins:

  1. Plugins tab → find the plugin's card → click Enable.
  2. Firestore updates settings.enabledPlugins[<id>] = true.
  3. The settings subscription fires; applyPluginRegistration re-runs.
  4. The plugin's register(api) callback runs, registering its filters/actions/blocks/cards.
  5. UI side-effects appear immediately:
    • New blocks show up in the editor's / inserter (next time you open it)
    • Dashboard cards appear (next time you visit Dashboard)
    • Settings tab appears (in the Settings sidebar)
    • Sidebar entries (some plugins add nav items) appear

Existing published HTML is not retroactively updated to include the plugin's output (e.g. enabling core-seo doesn't add Twitter Card tags to already-published pages). To apply retroactively:

Themes → Regenerate site → All HTML pages — re-renders every published page through the publisher with all currently-enabled plugins active.

Disabling a plugin

Click Disable on an enabled plugin's card. Same flow:

  1. Firestore updates settings.enabledPlugins[<id>] = false.
  2. Registry rebuilds without the plugin's hooks/blocks/cards.
  3. UI side-effects disappear immediately.

Plugin config is preserved in Firestore (settings.pluginConfigs.<id>). Re-enabling restores the previous config. To clear the config you'd need to manually delete the field via the Firebase Console, or use a plugin-specific "Reset" button if its settings page provides one.

Same caveat: existing published HTML keeps the plugin's prior output until you regenerate.

Why disabling doesn't strip published HTML

The publisher invokes plugin filters during the rendering of each page. Once a page is rendered and uploaded, the plugin's contribution is baked into the static HTML. Disabling the plugin only affects future renders.

This is the same behaviour as WordPress plugins that filter the_content() — disabling doesn't retroactively remove their changes from already-rendered cached pages.

The fix is the same: regenerate. Themes → Regenerate site with the appropriate scope.

Configuring a plugin

When a plugin has a settings page:

  1. Configure button on its card → routes to /admin/#/settings/plugin/<id>
  2. Or navigate via Settings in the sidebar — the settings layout has a tab strip with one entry per enabled plugin (and per active theme) that has a settings page.

The settings page UI is plugin-defined. Each plugin renders whatever form / controls it needs. The framework provides:

  • The current config (merged with defaultConfig from the manifest)
  • A save(next) callback that writes to settings.pluginConfigs.<plugin-id> in Firestore
  • The plugin's i18n namespace (useTranslation("<plugin-id>")) so labels translate

A typical settings page has:

  • Form fields for each option
  • A Save button at the bottom
  • Optionally a Save & regenerate button (e.g. flexweg-sitemaps — regenerating sitemaps is the typical reason you'd save sitemap settings)
  • Validation messages inline

Dealing with regen targets

Some plugins register a regeneration target with the publisher — a button in the Themes → Regenerate site dropdown that invokes the plugin's regen logic. For example:

  • flexweg-sitemaps → "Regenerate sitemaps + robots.txt"
  • flexweg-rss → "Regenerate RSS feeds"
  • flexweg-search → "Regenerate search index"
  • flexweg-archives → "Regenerate archive pages"

When you make a setting change that affects the plugin's output (e.g. enabling Google News in flexweg-sitemaps), running the plugin's regen target rebuilds the affected files immediately without re-rendering every HTML page.

When a plugin breaks

If a plugin's register(api) callback throws, the registry catches the error and logs it. The plugin doesn't register, but other plugins continue to work and the admin doesn't crash.

Symptoms of a broken plugin:

  • The plugin's blocks don't appear in the editor
  • The plugin's hooks don't fire
  • A console error: Plugin "<id>" failed to register: <error>

To recover:

  • Disable the plugin via the Plugins page (its register() doesn't run, no error)
  • Update the plugin — the author needs to fix the bug and ship a new version
  • Uninstall if you've given up on it

Plugin compatibility

Plugins declare an apiVersion in their manifest (e.g. 1.0.0 or 1.1.0). The admin checks this against [FLEXWEG_API_MIN_VERSION, FLEXWEG_API_VERSION]:

  • If the plugin's apiVersion is in range → loads
  • If outside range (too old or too new for the admin) → loads is skipped, console warning, plugin doesn't register

When the admin's API version bumps (e.g. 1.0.0 → 1.1.0), older plugins might still work (if backwards compatible) — the admin's MIN_VERSION controls the cutoff.

If you update the admin and a plugin stops loading, it's likely an apiVersion mismatch. Update the plugin to a newer release.

Continue