We’ve recently been working on updating Discourse’s header from the legacy ‘widget’ rendering system to modern Glimmer components. This change is now available in Discourse core behind the experimental glimmer header groups
site setting.
Approximate Timeline
(very rough estimates - subject to change in either direction)
Q1 2024:
-
core implementation finished & enabled on Meta
-
upgrade advice published; console deprecation messages enabled
-
work begins to update all official and third-party plugins/themes
Q2 2024:
-
start enabling new header implementation by default
-
official and third-party themes/plugins are ready for the upgrade
-
Deprecation messages start triggering an admin warning banner for any remaining issues
-
Possible announcements topic for site admins (depending on expected impact)
Q3 2024:
- Final removal of feature flag and legacy code
What Does it Mean for Me?
If your plugin or theme uses any ‘widget’ APIs to customize the header, those will need to be updated for compatibility with the new header.
How Do I Try the New Header?
In the latest version of Discourse, the new header is automatically enabled when all your themes/plugins are compatible.
If your themes/plugins are not compatible, then the legacy header will still be used, and a warning will be printed to the console alongside the existing deprecation messages. In the near future, this console warning will be upgraded to a warning banner in the UI.
In the unlikely event that this automatic system does not work as expected, you can temporarily override this ‘automatic feature flag’ via the glimmer header mode
site setting. If you do that, please let us know the reason in this topic.
Do I Need to Update My Plugin/Theme?
To determine whether your customization needs to be updated, check if it uses decorateWidget
, changeWidgetSetting
, reopenWidget
or attachWidgetAction
on any of these widgets:
- header
- site-header
- header-contents
- header-buttons
- user-status-bubble
- sidebar-toggle
- header-icons
- header-topic-info
- header-notifications
- home-logo
or uses one of these plugin API methods:
addToHeaderIcons
addHeaderPanel
All of these things will now cause deprecation messages to be printed to the console. Deprecation IDs are:
discourse.add-header-panel
discourse.header-widget-overrides
What Are the Replacements?
Each theme/plugin is different, but here is some guidance for the most common use cases:
addToHeaderIcons
The addToHeaderIcons
plugin API has been deprecated in favor of the new headerIcons
API. It exists to allow adding, removing, or re-ordering of icons in the header. It requires a Component to be passed.
The component can be passed as so:
Before | After |
---|---|
api.addToHeaderIcons(“widget-foo”) | api.headerIcons.add(“foo”, FooIcon) |
api.decorateWidget(“header-icons:before”, () => return helper.h(“div”, “widget-foo”)) | api.headerIcons.add(“foo”, FooIcon, { before: “search” }) |
api.decorateWidget(“header-icons:after”, () => return helper.h(“div”, “widget-foo”)) | api.headerIcons.add(“foo”, FooComponent, { after: “search” }) |
This example uses Ember’s Template Tag Format (gjs) to define a component inline and pass it to the headerButtons.add API:
// .../discourse/api-initializers/add-my-button.gjs
import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("1.0", (api) => {
api.headerIcons.add("some-unique-name", <template>
<li><DButton class="icon btn-flat" @href="/u" @icon="address-book" /></li>
</template>);
});
Or for a dropdown, you could use <DMenu
instead of <DButton
:
import DButton from "discourse/components/d-button";
import { apiInitializer } from "discourse/lib/api";
import DMenu from "float-kit/components/d-menu";
export default apiInitializer("1.0", (api) => {
api.headerIcons.add("some-unique-name", <template>
<li>
<DMenu class="icon btn-flat" @icon="address-book">
<DButton @translatedLabel="User 1" @href="/u/user1" />
<DButton @translatedLabel="User 2" @href="/u/user2" />
<DButton @translatedLabel="User 3" @href="/u/user3" />
</DMenu>
</li>
</template>);
});
Example upgrade commits:
decorateWidget("header-buttons:*")
The header-buttons
widget has been deprecated and we have introduced a headerButtons
plugin API. It exists to allow adding, removing, or re-ordering of buttons in the header. It requires a Component to be passed.
Before | After |
---|---|
api.decorateWidget(“header-buttons:before”) | api.headerButtons(“button-name”, ButtonComponent, { before: “auth” }) |
api.decorateWidget(“header-buttons:after”) | api.headerButtons(“button-name”, ButtonComponent, { after: “auth” }) |
home-logo
We have introduced a home-logo
plugin outlet in replacement of home-logo:before
or home-logo:after
widget decorations. You can utilize the automatic __before
and __after
naming in your connector file to specify where your custom content should be placed.
More details on before/after connector file naming can be found here.
Before | After |
---|---|
api.decorateWidget(“home-logo:before”) | Move content to /connectors/home-logo__before |
api.decorateWidget(“header-buttons:after”) | Move content to /connectors/home-logo__after ) |
What about other customizations?
If your customization cannot be achieved using CSS, PluginOutlets, or the new APIs we’ve introduced, please let us know by creating a new dev topic to discuss.
How do I update a theme/plugin to support both old and new header?
All the new APIs and plugin outlets listed in this document are supported on both the new and the old header. So you only need to make one update to your theme/plugin now, and users will be ready for the switch.