Custom Header Links

:discourse2: Summary Custom Header Links allows you to easily add custom text-based links to the header.
:eyeglasses: Preview Preview on Discourse Theme Creator
:hammer_and_wrench: Repository Link GitHub - discourse/discourse-custom-header-links · GitHub
:open_book: New to Discourse Themes? Beginner’s guide to using Discourse Themes

Install this theme component


Features

Desktop

Mobile


(due to very limited space, adding more than one link on mobile is not recommended)


Settings

Setting Description
custom_header_links The structured list of links to display in the header. Each link is configured through a form with individual fields (see below).
links_position Controls whether links appear on the right (default) or left side of the header near the logo. When set to left, all links are automatically hidden on topic pages to make room for the topic title — regardless of individual link hide_on_scroll settings.

Adding Links

Links are configured through a structured form in the theme component settings. Click Add to add a new link. Each link has the following fields:

Field Required Description
Text :white_check_mark: Yes The visible label for the link. Max 100 characters. Also determines the CSS class applied to the link (see CSS Customisation below).
Title :x: No The tooltip text shown when hovering over the link. Max 1000 characters.
URL :white_check_mark: Yes The URL the link points to. Can be a relative path (e.g. /faq) or a full URL. Max 2048 characters.
View :x: No Controls which device the link appears on. If left unset, the link shows on all devices (same as vdm). See values below.
Target :x: No Controls how the link opens. If left unset, defaults to opening in a new tab (same as blank). See values below.
Hide on scroll :x: No Controls whether the link hides when the topic title becomes visible in the header on topic pages. Defaults to keep. Only applies when links_position is set to right — see note below. See values below.
Locale :x: No If set, the link is only shown when the site’s page language matches this value. Leave blank to show the link on all locales. See details below.

View values:

Value Behaviour
vdm Visible on both desktop and mobile
vdo Visible on desktop only
vmo Visible on mobile only
(unset) Same as vdm — visible on all devices

Target values:

Value Behaviour
blank Opens in a new tab
self Opens in the same tab
(unset) Defaults to opening in a new tab (same as blank)

Hide on scroll values:

Value Behaviour
keep Link stays visible even when the topic title is shown in the header (default)
remove Link hides when the topic title becomes visible on topic pages

:information_source: hide_on_scroll only applies when links_position is right. When links_position is left, all links are hidden together on topic pages regardless of their individual hide_on_scroll setting.

Here’s an example of hide_on_scroll in action (with links_position set to right):

Most Liked and Privacy are set to keep, so they remain visible when the title expands. The other links are set to remove, so they hide when the title becomes visible. This behaviour only affects topic pages.


Locale Filtering

The Locale field allows you to show a link only when the site is set to a specific language. This is useful for multilingual communities that want different header links per language.

  • Set the field to a locale code such as en, de, fr, zh_CN, etc.
  • The match is case-insensitive, and both - and _ separators are treated identically — so en-US, en_US, and en_us all match equally.
  • If the locale field is left blank, the link shows on all locales. This is the recommended setting for most single-language sites.
  • A CSS class headerLink--{locale} is also added to the link element, which can be used for additional CSS targeting.

:warning: Common issue: If your links are not appearing, check whether you have accidentally set a locale value that does not match your site’s configured language. Leaving the locale field blank is safe and will always show the link.


CSS Customisation

Each link automatically receives a CSS class derived from its Text value: spaces are replaced with hyphens, the text is lowercased, and -custom-header-links is appended.

For example:

  • A link with text Privacy gets the class privacy-custom-header-links
  • A link with text Visit Shop gets the class visit-shop-custom-header-links

Style all header links:

.custom-header-links .headerLink a {
  font-size: var(--font-up-1);
  color: var(--header_primary);
}

Style a specific link (e.g. a link with text “Privacy”):

.custom-header-links .headerLink.privacy-custom-header-links a {
  color: var(--tertiary);
}
.custom-header-links .headerLink.privacy-custom-header-links a:hover {
  color: var(--tertiary-high);
}

Show or hide a link based on login state:

Discourse adds an anon class to the <html> tag for logged-out users. You can use this to conditionally show or hide links:

/* Hide "Dashboard" from logged-out users */
html.anon .dashboard-custom-header-links {
  display: none;
}

/* Hide "Sign Up" from logged-in users */
html:not(.anon) .sign-up-custom-header-links {
  display: none;
}

:warning: CSS display: none is a visual-only hiding mechanism. The link’s HTML is still present in the page source. Do not use this to protect sensitive or access-controlled URLs.

Reorder links with CSS (using flexbox order):

.custom-header-links li {
  &:nth-child(1) { order: 3; }
  &:nth-child(2) { order: 1; }
  &:nth-child(3) { order: 2; }
}

Use the /my path for user-specific links, to avoid hardcoding a username:

/my/messages     → the current user's inbox
/my/activity     → the current user's activity

:discourse2: Hosted by us? Theme components are available to use on our Pro, Business, and Enterprise plans.


Changelog highlights:

  • The custom_header_links setting was migrated from a comma-delimited list format to a structured type: objects form UI. If you previously configured links using the old comma-separated text input, the migration should have preserved your data automatically

Last edited by @Moin 2026-03-23T22:46:59Z

Last checked by @MarkDoerr 2026-03-23T22:39:09Z

Check documentPerform check on document:
83 Likes
How can I add custom hamburger menu
Header Submenus
Structuring a multilingual community
Display StatusPage status on as a header link
Control CSS based on user's logged in state
Looking for a freelancer to implement a custom Discourse theme (based on an existing mockup)
Add a global header between Discourse & Website
How to make custom setting type
Is it possible to have users' job titles next to their names on posts?
Link to find all deleted posts by all users in a particular period
Dropdown links in existing Header
Insert Link to External Website
Is anyone here using their Discourse instance as their entire website?
How to fire on every footer load (or page load?)
Custom links above header bar
Custom Header Links (icons)
Pre seeded posts all missing - Missing Terms of Service, FAQ and Privacy pages
Dropdown header links in the existing Header
Add a "curated personal learning" page for users
Redirect search icon to search page
Possible to change main logo URL?
2021: The Year in Review
How to add breadcrumb?
How to add contact us page?
Navigation bar above all post
Adding link to blog on main page
Customizing your site with existing theme components
Show "new topic" when not logged in
How can I add a new button to the topbar?
⬇️ Dropdown Header
How to fix logo size?
Links into the header block
Customize the header with links, icons, or menus
Privacy Policy does't meet Google's requirements
Custom Header Links and New Topic Header Button don't play nice
Customize Your Site Branding
Nextcloud support
How to override the site-header.hbs file from custom theme?
Sidebar link / top button to PM admin
Toolbar under site header per category
Privacy Policy does't meet Google's requirements
Link buttons on the top disappear when scrolling around the site
Disclaimer section on the "about" page
What Themes are being used for these Discourse forums?
Alternative component (plugin?) to categories navbar
Add button in header for logged in users
Use decorateWidget to add text link to header
[PAID] Expert Wanted for Forum Redesign
Add social media handles on home page
Create hyperlink from home logo
Configure a custom sidebar link to open in a new tab
2023: The Year in Review
Modifying Header
Fully Theme
Visiting /admin/upgrade may lead to a server error
Header Submenus
How do I go about making a very customized theme?
How to Integrate a Custom Plugin in discourse UI
Embedding a whole Discourse forum on another site in an <iframe>
Memberstack + Webflow + Discourse OpenID Connect
Custom website header with forum
Custom Header Links (icons)
Brave default Theme
Why does the logo navigate to Discourse home not main site home
Structuring a multilingual community
How to make sidebar sticky?
Forum navbar is repeating
Adding my Nav into the header bar
Best place(s) to link back to a non-forum homepage?
Allow non-members to pm the administrator
Adding a header link for Guests Only
Link on Top header to Go to Home page of main site
How to finely scroll out custom header?
Can I add a icon and link back to my homesite at the top bar
Custom Header links was automatically hide when scrolling topic page contents
Link behavior inconsistent
Upcoming Header Changes - Preparing Themes and Plugins
How to add a "button" which composes a pre-filled topic
Where to place project external URL?
Change destination of logo link
External header links are not opening in a new tab
How to split the forum into two main parts (general/groups) and how to display only subcategories I can create a new post in?
Add secondary url / embed into Wordpress
"An empty string is not a valid JSON string" when updating theme component #2
How can I add a button to the header?
Showing categories statically above most recent posts
How to add a button to the header area?

don’t know if this has been suggested, tried reading back but couldn’t find it.

was thinking that maybe adding the ability to create “sub-links” thus creating the idea of a list that you could edit (text color, background hover etc.) to get results similar to what zoom has

8 Likes

the links that have the arrow to the right like developer means that it has “sub-links”

1 Like

Is it possible to add some basic dropdown menu to an any item?

I couldn’t create a dropdown menu with “Custom header links”. It seems Zoom did that. I reviewed their dropdown menu via console, but I couldn’t figure out how they interfere with the html of this component for adding dropdown to any item.

Is there a way to add this dropdown to item? @Johani

<div id="dropdown">
  <a title="Zoom Developer Documentation" href="https://marketplace.zoom.us/docs" target="_blank">Developer</a>
  <span class="caret"></span>
  <div class="dropdown-content">
    <a title="Zoom API Docs" href="https://marketplace.zoom.us/docs/api-reference/introduction" target="_blank">API</a>
    <a title="Zoom SDK Docs" href="https://marketplace.zoom.us/docs/sdk/native-sdks/introduction" target="_blank">SDK</a>
    <a title="Zoom Developer Blog" href="https://medium.com/zoom-developer-blog" target="_blank">Blog</a>
    <a title="Zoom Developer Changelog" href="https://marketplace.zoom.us/docs/changelog" target="_blank">Changelog</a>
    <a title="Zoom Developer Survey" href="https://docs.google.com/forms/d/e/1FAIpQLSeJPLhNuxjtkxyyV276R8S_nYz99fpMbbS8VWkC8Hwi7-2Byg/viewform" target="_blank">Survey</a>
  </div>
</div>
5 Likes

Has anyone run into any issues with links not opening when setting links position to “left”?

Links work on Preview but not when I apply it to a theme.
Right alined links work fine though.

1 Like

Hi! Thanks for creating this.
Is it possible to add an SVG before the text link? If so - how?

1 Like

Have you found a solution for this? I am look for the same solution.

6 Likes

how can the title convert **formatting code** into actual formatting? also how about Font Awesome icons before the text?

2 Likes

Could be possible to add a flag to show or hide links as specific groups of users?

3 Likes

Is there a way this theme component can allow for dropdown navigation? That means, when I hover over a header link, it has sub-items that appear underneath it. I know that this can be done via html/css as shown here:

2 Likes

Thank you for creating this component!
One question and potentially a feature request: can we show a specific link for a specific group?
For example, if a user is in group customers I’d like to show a link to the customer’s control panel, if a user is in group workers I’d like to add a link to a different panel.
I think this would be a very useful feature.
The group name could be the last (optional) parameter.

2 Likes

Thanks for this! I just found it after trying various other banners and components. Its exactly what I need!

One request/suggestion: ability to re-order the links. I just made a bunch and realized I’d like to add one at the top. Now I’ll have to manually copy and paste them all, which is actually quite cumbersome as they keep syncing/updating other entries as I copy them down.

Drag and drop or up/down buttons would be very useful for future users (or future edits).

4 Likes

You can already manipulate the order very easily with some lines of CSS since we use the flex property.

E.g.:

CSS example:

.custom-header-links li {
  &:nth-child(1) {
    order: 3;
    background: red;
  }

  &:nth-child(2) {
    order: 1;
    background: green;
  }

  &:nth-child(3) {
    order: 2;
    background: yellow;
  }
}
5 Likes

@Nick_Chomey I’ve often found myself needing to do this, not only for this theme component but many other theme components that use the type: list setting. I was planning on submitting a feature request before, but I completely forgot, but since you’ve reminded me, I’ve added one here:

3 Likes

@dax Thanks! I had no idea this was possible!

@keegan looks great, hopefully itll get added at some point!

2 Likes

I’m looking for the same solution, did you find out how they did this yet?
Thanks!

1 Like

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

privacy

then the link element will have the class

privacy-custom-header-links

If your link text is

Visit Shop

then the CSS class would be

visit-shop-custom-header-links

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

anon

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.

11 Likes

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:

3 Likes

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.

3 Likes