Migration and rollback record
Prepare the replacement on a non-default preview theme first. If Brand Navigation is already used by visitors, use a separate component copy or staging site: copying a theme alone does not isolate a shared component’s code or settings. Detach an old component only from the theme you are changing. Disable it globally only when you intend to stop it on every theme using it.
Every procedure below uses this same shared-component rule: settings imports, code updates and the Enabled? control affect all themes attached to that component. For an existing live installation, prepare changes on a separate component copy or staging site. Another parent theme, a copied theme or Preview alone does not isolate them. During cutover, attach or detach the appropriate component on the selected theme; do not use global disabling as a substitute for detaching it from one theme.
Configuration bundles
Section titled “Configuration bundles”Use the Configuration bundles panel to export and import a versioned JSON
configuration without recreating every object-setting row. The browser panel
updates only the portable Brand Navigation settings listed in the bundle. It
does not apply the bundle’s non-functional exported_at, source_theme_id, or
source_theme_name metadata, and it does not attach or enable the component.
Bundle validation is fail-closed for field types, allowed values, URL schemes, unknown fields, navigation depth, size limits, and cross-field requirements. The browser importer sends one complete theme update after preflight rather than saving settings one at a time. If connectivity is lost after submission, reload the target component and verify its settings before retrying. The same 1,000,000-byte file ceiling applies to imports and generated exports. The structured navigation data must also fit Discourse’s 524,288-byte serialized object-setting limit. Brand Navigation checks both limits before an import request or downloadable bundle is created; oversized settings must be shortened first.
For normal administrator use, the same operation is available in the Configuration bundles panel near the bottom of Brand Navigation’s administration page. Discourse does not load a disabled component’s custom JavaScript, so the panel cannot be used while the native Enabled? control is off. Prepare a new installation without publishing it by attaching the enabled component only to a non-default staging theme, opening that theme through Discourse’s Preview control, and then opening Brand Navigation’s settings in the preview context. Import and verify the bundle there before attaching Brand Navigation to a visitor-facing theme.
The repository’s configurations/repeal-obbba.json file is the first migration
fixture. It was assembled from observed Brand Header, Dropdown Header, and
Custom Header Links (icons) settings and is also useful for exercising larger
menus, external destinations, icon-only links, and left/right sections.
Import and export use the administration panel in your browser. A local checkout
can validate a saved bundle without contacting a forum by running
pnpm bundle validate configurations/repeal-obbba.json; this command does not
import or export settings on a forum. Logo uploads remain a separate site-local
step.
From Brand Header
Section titled “From Brand Header”- Record
brand_name,website_url, light/dark/mobile logos, text links, icon links, targets, mobile behavior, and outlet. - Install Brand Navigation and prepare it on an enabled, non-default staging theme as described above; do not attach it to a visitor-facing theme yet.
- Map the brand name and
website_urltobrand_nameandbrand_url. - Upload the light and dark logos. Brand Navigation intentionally uses the light logo as the dark fallback and responsive sizing instead of a separate mobile-logo setting.
- Add text links as top-level
navigation_items. - Add icon-only links from the earlier component as labeled navigation entries. A visible label is required for clear administration and accessibility.
- Select the equivalent outlet and mobile mode.
- During the controlled cutover, attach the prepared Brand Navigation component to the intended visitor-facing theme, detach Brand Header from that theme, confirm Brand Navigation’s native Enabled? control remains on, and immediately run the acceptance checks. Restore Brand Header if the replacement is not visible and usable.
From Header Submenus
Section titled “From Header Submenus”- Export or copy the
Menu_items,Submenu_items, icon list, placement, and color choices before changing anything. - Install Brand Navigation and prepare it on an enabled, non-default staging theme as described above; do not attach it to a visitor-facing theme yet.
- Create one structured top-level item for every menu item.
- Add each submenu entry under its parent. Divider-only entries have no direct equivalent; use grouping and ordering instead.
- Omit placeholder links such as
#until they have real destinations; Brand Navigation validates submenu destinations instead of preserving no-op links. - Map
vdmtoboth,vdotodesktop, andvmotomobilein each item’sdevice_visibility. Then choose the component-wide mobile mode that controls whether mobile navigation uses the menu, full bar, or stays hidden. - Keep color customization in the parent theme when needed; Brand Navigation defaults to Discourse color-scheme variables.
- During the controlled cutover, attach the prepared Brand Navigation component to the intended visitor-facing theme, detach Header Submenus from that theme, confirm Brand Navigation’s native Enabled? control remains on, and immediately run the acceptance checks. Restore Header Submenus if the replacement is not visible and usable.
The same mapping applies to Pavilion’s Dropdown Header: header links become
top-level items, dropdown rows become children matched to their parent, and
its icon list becomes custom_font_awesome_icons.
From Custom Header Links (icons)
Section titled “From Custom Header Links (icons)”- Export or record each title, icon, URL, device view, width, and target.
- Map each link to a top-level Brand Navigation item. Choose the
rightsection on thebarsurface, or choosesite_headerto retain its compact location among Discourse’s core header icons. - Use
icon_onlypresentation on the bar, oricon_onlysite-header presentation (header_presentation) on the core header, while retaining the full title as the required accessible label. - Map
blankto_blankandselfto_self. - Add every used icon to
custom_font_awesome_icons. - Map each device view to
both,desktop, ormobile, then review the component-wide mobile mode. For crowded mobile headers, keep only priority icons onbothand mark the restdesktop. - During the controlled cutover, attach the prepared Brand Navigation component to the intended visitor-facing theme, detach Custom Header Links (icons) from that theme, confirm Brand Navigation’s native Enabled? control remains on, and immediately verify the header at desktop and narrow mobile widths.
From Custom Header Links (text links)
Section titled “From Custom Header Links (text links)”The text-based Custom Header Links component is separate from Custom Header Links (icons). Brand Navigation can replace its links with text-only or icon-and-text entries in Discourse’s header.
- Record each label, URL, tooltip, target, and desktop/mobile visibility.
- Add a top-level item with
surface: site_headerandheader_presentation: label_only. Useicon_and_labelif an icon is also wanted. Copy the original destination and target and map device visibility. - Prepare and test the replacement on a staging theme. Keep long labels short enough for the available header space; use desktop-only visibility when appropriate. Header links remain direct links; they do not support submenus.
- During cutover, detach the text-based Custom Header Links component on the affected themes, refresh, and confirm each link appears exactly once. Verify desktop/mobile layout, keyboard focus, anonymous and signed-in controls, and topic-header scrolling before accepting the change.
- Keep the original component and its configuration available for rollback.
Roll back to an earlier component
Section titled “Roll back to an earlier component”Keep the original components and their saved settings until the replacement has passed staging. To restore them on a theme:
- Detach Brand Navigation from the affected theme.
- Reattach the earlier component to that theme. If it was disabled, enable it, bearing in mind that this enables it on every theme still using it.
- Restore its exported settings if they were changed.
- Verify normal pages, mobile navigation, authentication, and an embedded discussion.
Brand Navigation does not mutate settings from either earlier component, core site settings, or DiscussionBridge, so rollback has no data migration to reverse.
Roll back Brand Navigation to a release tag
Section titled “Roll back Brand Navigation to a release tag”Use this procedure when a Brand Navigation update causes a regression and the
site needs the previous known-working Brand Navigation release. It keeps the
same Discourse component record so its settings and theme attachments can be
preserved. This procedure is provisional: the project has not yet recorded the
complete pin-and-return workflow on staging. Review the current evidence in
TESTING.md and test the complete procedure on staging first.
Prerequisites:
- Choose an existing Brand Navigation release tag that is documented as compatible with the site’s Discourse release. Do not invent or move a tag.
- Keep administrator access through Discourse safe mode available in case the active theme cannot render normally.
To pin the existing component to a release:
- Open Admin → Appearance → Themes & components → Components → Brand Navigation. Record the current component commit, exact configured Branch field value (including blank/default), separately displayed or resolved compatibility ref, native Enabled? state, and every attached parent theme.
- Attach Brand Navigation to a non-default staging theme that visitors do not use, then temporarily remove every visitor-facing parent-theme attachment. Keep only the staging-theme attachment.
- Turn or confirm Discourse’s native Enabled? control on and open the staging theme through Preview. Export the current Configuration bundle and store it outside Discourse before changing source. If the preview or bundle panel cannot load, stop and restore the recorded source, activation, and attachment state.
- Select Change source. Leave the repository URL as
https://github.com/CodeWorksLabs/brand-navigation.git. - Enter the exact tag of your chosen compatible release in Branch, then submit the source change. Current Discourse uses this field for a named Git branch or tag; the release tag pins the component to that immutable revision.
- In the staging-theme preview, confirm the component reports the intended tag/commit with no import error and that its settings remain present.
- If a setting needs restoration, import the saved configuration bundle only after confirming that the selected release supports that bundle schema.
- Verify the staging preview, then restore the recorded visitor-facing parent-theme attachments. Run the focused desktop, mobile, anonymous/authenticated, link, color, and embed checks before ending the rollback window.
The v0.9.0 release also exposes a legacy Enabled setting inside Brand
Navigation’s own settings. That release requires both activation controls to
be on before it renders. Set the legacy setting deliberately while testing the
rollback; it is removed on the current channel because it duplicated and could
contradict Discourse’s native component control.
While pinned to a tag, the component does not advance with main or a
d-compat/<YYYY>.<M> branch. Automatic update checks may still run, but the tag
itself is immutable.
To return to the supported current channel:
- Export the current bundle again, record and temporarily remove every visitor-facing parent-theme attachment, and keep only the non-default staging theme attached. Leave the native Enabled? control on so the custom bundle panel remains available in preview.
- Open Change source, leave the repository URL unchanged, clear Branch, and submit the source change.
- Select Check for updates, then Update to latest when offered.
Discourse will follow repository-default
mainon current core or resolve the maintainedd-compat/<YYYY>.<M>ref appropriate to an older supported core. - In the staging-theme preview, confirm the intended commit/ref, zero import errors, and preserved settings. Import the saved bundle there if restoration is required and supported by the selected version.
- Verify the staging preview, restore the recorded visitor-facing parent-theme attachments, and repeat the focused acceptance checks. On the current channel, native Enabled? is the only activation control; the legacy setting is no longer shown or read.
Do not edit a Git-installed remote component locally, force-move a release tag, or delete and reinstall the component as a normal rollback method. If the source change fails, turn native Enabled? off, capture the displayed error, and restore the exact prior configured Branch field value—including a blank/default value—before making another attempt. Before reopening the custom bundle panel, confirm that only the non-default staging theme is attached, turn native Enabled? on, and return through that theme’s preview. After a native update, separately verify the resolved compatibility ref rather than copying that resolved ref into Branch.