Custom Header Links

Hi @Johani
Thanks for creating such an awesome component!

Is it possible to have a link only be visible if the user is logged in?
It will be an external link.

1 Like

Hey @andreas_can welcome to Meta :wave:

This component adds a CSS class to each link based on its text. The class added is the same as the text you give the link except that spaces are replaced with a hyphen (-) and the text is set to lowercase. Then the string -custom-header-links is appended at the end.

So if you add a link with the text


then the link element will have the class


If your link text is

Visit Shop

then the CSS class would be


So, now you know the class added to each link. Going back to your question.

Discourse adds a CSS class to the <HTML> tag when the user is not logged in. That class is


So, you can use that to hide certain links for users who are not logged in. Let’s say I have a link with the text

Customer Support

and I don’t want it to show to users who are not logged in.

I would then add this CSS

.anon {
  .customer-support-custom-header-links {
    display: none;

in the common > CSS tab of my main theme.

This will hide that particular link for users who are not logged in.


Thank you for such a quick and thorough reply!
This is exactly what I was looking for.

I’ll give it a go :slightly_smiling_face:


Note that CSS display: none; only hides the link from browser rendering but it is always fully visible to anyone looking at the page source, to web crawlers and search engines.


This is generally true, CSS isn’t a secure way to hide anything because a savvy person might look at the page source for whatever reason… but we do serve a no-js view to crawlers, so in that case content added by themes usually isn’t indexed anyway.


The preview does not work


I’ve updated the preview link, it should work now!


Is it possible to use this component to call a javascript with
instead of an actual url?

(It seems to almost work, but I’m hitting CSP violations.)

Edited to add:
I got it to work. If anyone else should ever wonder, I used # in the component’s UI in place of a url, then used an event listener to call the javascript function.

Others likely know a better way, and I hope they’ll share that knowledge if they do!


Hi, I’d like to adjust the font style and size of the header links. Can someone please point me to the correct CSS that allows me to do this? Thanks!


Hey @brentoshiro, the properties will vary depending on what you need styled, but the way you would select the links would be like so:

To style all header links:

.custom-header-links .headerLink a {
    font-size: 1rem; // replace with your font size of choice
    color: #96b67b; // can also use variables such as var(--tertiary);
    font-style: italic; // options: normal, italic, oblique

To style a specific link
You can access the link either using the link title (separated by dashes and lower case) like so for “Privacy”:

.custom-header-links .headerLink.privacy-custom-header-links a:hover {
    color: red;

or by using the title attribute and entering the link title:

.custom-header-links .headerLink a[title='Our Privacy Policy'] {
    color: purple;

To add styles on hover, you simple add :hover after the a tag:

.custom-header-links .headerLink a:hover {
    color: var(--primary-low);

Hello, could it be possible to style the links to be centered instead of just left/right?

1 Like

This is really cool. I’m wondering how much additional work this would be to allow for different lists of header links per-group? We have staff and students on our site and would love to be able to provide different primary links in the header for each group.


You could achieve that by having each group on a different Theme, with each theme using its own copy of this Theme Component.

This would work nicely if one of your two groups was quite static (or at least smaller) - your staff group seems ideal for that. Or at least if you only had one dynamic group.

You then make the student links the site default Theme, and the make your staff members have the staff links manually (either by the UI or via the Rails Console).


I was just coming here to ask this as I finally noticed they appear on the log in screen

In my case, one of the links is changed every month (while the header name remains the same). Is it possible to hide the header with a code without having to edit to hide the link? For example using your example I would have

Customer Support
2022-customer-support/26903 is what my link is, then customer-support-july, etc.

So as you can see hiding customer-support-june would works fine, but it has to be updated monthly instead of if I was just hiding “FAQ” (and I also can’t add the /26903 from the topic to the CSS code so I can’t hide this specific link although I can possibly get around this by publishing the page?). If there’s no other way to do it this isn’t a big deal at all that’s not any amount of effort, it’s more that I guarantee I’ll forget.


hello, i was curious to know if it was possible to get possibly translations for the text ? Maybe by including translation keys, if the componant includes them :slight_smile:

1 Like

****Any reason why by default it’s not showing to non-logged in users?

Ignore, for some reason when I apply a component to the Theme, it doesn’t appear. I have to add the component onto the Theme instead.

1 Like

Using UTF-8 icons

Note that you can use UTF-8 icons as link anchors.

In this case, you might want to try this CSS to match other header dropdown icons:

.custom-header-links .headerLink {
    margin-top: -1px;
.custom-header-links .headerLink a {
    padding: 3px 10px;
    color: var(--primary-low-mid);
    font-size: var(--font-up-5);
    font-weight: bold;
.custom-header-links .headerLink:hover {
    background-color: var(--primary-low);
.custom-header-links .headerLink:hover a {
    color: var(--primary-medium);

It does something like that:



1 Like

I just installed this component and added some links, but they weren’t displayed.

I discovered that entering a language prevents the links from displaying on my site. Originally I’d added ‘blank’ for completeness even though it wasn’t needed. They still didn’t display when I changed blank to ‘en’. Removing the value completely fixed the problem in my case. Haven’t a clue why, but I thought I’d mention this in case anyone else has a similar problem.


I fell afoul of that myself the other day too:

I’ll see if we can perhaps change the default examples to make it more intuitive.


I’ve removed the locale from the default settings here: UX: remove locale from default settings by awesomerobot · Pull Request #38 · discourse/discourse-custom-header-links · GitHub

So the defaults should now appear no matter which locale the site is set to. Thanks @packman and @JammyDodger!