Discourse has recently deprecated api.decorateWidget
, which I used to insert custom header icons and post the current user’s username via a URL.
I was wondering how I can post the user’s current username via HTTP with the new headerIcons
API. I couldn’t find any documentation or examples on how to implement this. I couldn’t find a way to do it via the Customer Header Link plugin either.
Appreciate your help! Below is my current code using the decorateWidget
API to post the username:
<script type="text/discourse-plugin" version="0.12">
const { iconNode } = require("discourse-common/lib/icon-library");
let icon = iconNode('calculator');
var currentUser = api.getCurrentUser();
var username = currentUser.username;
api.decorateWidget('header-icons:before', helper => {
const showExtraInfo = helper.attrs.minimized;
if(!showExtraInfo) {
return helper.h('li#calculator', [
helper.h('form#header-calculator.icon', {
action:'https://example.com/',
method:'post'
}, [
helper.h('button', {name:'u', value: username},[
iconNode('calculator'),
])
])
]);
}
});
</script>
Hey,
I will help you, but can you explain what you’re trying to do before that?
Is it to display a menu with a form inside?
Like for example:

Or is it just a button with the username as label, and it redirects to some URL?
It’s to click the header icon >> post the user’s username to a specified URL.
No form is actually displayed. Only the header icon is displayed. The post action is performed behind the scene. Sorry for the confusion. Let me remove “form” from the title of my post.
Okay, so a redirection to an external URL that contains the username.
Here is a basic example on how you can do, using the new API:
import { apiInitializer } from "discourse/lib/api";
import DButton from "discourse/components/d-button";
export default apiInitializer("1.8.0", (api) => {
const currentUser = api.getCurrentUser();
if (!currentUser) {
return;
}
const url =
"https://example.com/?u=" + encodeURIComponent(currentUser.username);
const iconComponent = <template>
<li class="calculator">
<DButton
@href={{url}}
@icon="calculator"
class="icon btn-flat"
title="Calculator"
target="_blank"
/>
</li>
</template>;
api.headerIcons.add("calculator", iconComponent, { before: "search" });
});
calculator
is a unique name
iconComponent
refers to an inline glimmer <template>
as you see here, but it can also refer to a glimmer class component you create in the components
directory.
- You can choose where to place your icon by using
before
or after
followed by the header icon’s unique name.

Feel free to adjust!
Note:
Let me know if you need further help!
3 Likes
Hi @Arkshine ,
Thank you so much for the detailed write-up. I tried injecting the code in <head>
but is not seeing the icon show up. What did I do wrong?
<script type="text/discourse-plugin">
import { apiInitializer } from "discourse/lib/api";
import DButton from "discourse/components/d-button";
export default apiInitializer("1.8.0", (api) => {
const currentUser = api.getCurrentUser();
if (!currentUser) {
return;
}
const url =
"https://example.com/?u=" + encodeURIComponent(currentUser.username);
console.log("url: " + url)
const iconComponent = <template>
<li class="calculator">
<DButton
@href={{url}}
@icon="calculator"
class="icon btn-flat"
title="Calculator"
target="_blank"
/>
</li>
</template>;
api.headerIcons.add("calculator", iconComponent, { before: "search" });
});
</script>
1 Like
@littleviolette Hi, it can’t be run in the Admin UI here.
Using the Theme CLI, you can easily create a theme component on your computer.
Then, you edit the file with a text editor of your choice (like vscode) and add the code in the initializer. You make a file in /javascripts/discourse/api-initializers/my-header-icon.gjs
and you paste the code in it. You can also change the default values in about.json
.

The next step to install the component on your production forum:
- you can either put the component on Github and in the Admin UI, use the repository link to install;
- or you zip the directory on your computer, and in the Admin UI, you install it from the device.
Give it a shot and let me know if you have any issues!
3 Likes