8. Production notes and pitfalls#

Your overrides work. This chapter collects what you need to know before you ship them.

8.1. Version pinning#

The versions of @plone/mockup and @patternslib/patternslib in your package.json must match the Mockup version that plone.staticresources ships. Module federation negotiates shared modules through version ranges. If the versions drift too far apart, module federation loads two instances, and registrations end up in the wrong registry.

On every Plone upgrade, align the versions, and rebuild the bundle. Check the browser console for module federation warnings.

Some techniques also need a minimum Mockup version in the Plone bundle. The shared Svelte runtime needs Mockup 5.6.9, and the override under the default component key needs Mockup 5.6.11.

8.2. Clean uninstall#

The uninstall profile removes what the default profile added:

  • Bundle records are removed with remove="true" in profiles/uninstall/registry/bundles.xml.

  • Whole records, such as plone.mark_special_links, are reset with a plain value.

  • Single dictionary keys, such as our entries in plone.patternoptions, cannot be removed declaratively. The post_uninstall handler in setuphandlers.py removes them in Python:

PATTERN_OPTION_KEYS = ("markspeciallinks", "contentbrowser")


def post_uninstall(context):
    registry = getUtility(IRegistry)
    options = dict(registry.get("plone.patternoptions") or {})
    remaining = {k: v for k, v in options.items() if k not in PATTERN_OPTION_KEYS}
    if remaining != options:
        registry["plone.patternoptions"] = remaining

8.3. Known pitfalls#

Forgotten build

static/bundles/ is empty, and the remote bundle returns a 404 error. Run pnpm run build first, then install.

Missing trigger class

Options alone don’t run a pattern. When a pattern “does nothing”, first check the trigger, then the options.

Missing purge="false"

Without it, your plone.patternoptions import overwrites the options of the Plone core and of other add-ons.

Two Svelte runtimes

The selection list renders an empty slot, and the console shows Cannot read properties of null (reading 'nodes'). The host and the add-on don’t share the Svelte runtime. Either the Plone bundle is older than Mockup 5.6.9, or the svelte and svelte/ shares are missing in your webpack configuration. See Overriding a Svelte component.

The default component wins again

You registered your component under the default key, but the content browser still renders the original. The Plone bundle is older than Mockup 5.6.11, which re-registered the default component on every widget initialization. Register your component under a custom key, and activate it with componentRegistryKeys, see Block 3: scoping the override.

Lazy component registration

With a typo in a custom registry key, the content browser silently falls back to the default component.

8.4. Where to go next#