2 min read

How to Show "New Topic" Button for Non-Logged In Users in Discourse

Introduction

This guide will show you how to create a "New Topic" button for non-logged-in users in Discourse. By default, "New Topic" button is only visible to logged-in users. When clicked by a guest user, it will prompt them to sign up.

Note from the author: This solution was developed with significant help from Claude (Anthropic's AI). While the code works, I don't fully understand all the technical details of why it works. If you're a developer who can explain this better, please feel free to contact me to help improve upon this guide!

The Solution

Step 1: Add JavaScript Code

In your Discourse admin panel:

  1. Go to Appearance → Components
  2. Install → + Create New
  3. Add this code to the Body section of your Component:
(function() {
  const { api } = require("discourse/lib/plugin-api");
  const { withPluginApi } = require("discourse/lib/plugin-api");

  withPluginApi("0.8", api => {
    const addNewTopicButton = () => {
      // Check if user is logged in
      if (Discourse.User.current()) {
        return; // Exit if user is logged in
      }
      
      const navContainer = document.querySelector('.navigation-container');
      if (!navContainer) return;
      
      // Create button if it doesn't exist already
      if (!document.querySelector('.guest-new-topic-button')) {
        const button = document.createElement('button');
        button.className = 'btn btn-icon-text btn-default guest-new-topic-button';
        
        button.innerHTML = `
          <svg class="fa d-icon d-icon-plus svg-icon svg-string" xmlns="http://www.w3.org/2000/svg">
            <use href="#plus"></use>
          </svg>
          <span class="d-button-label">New Topic</span>
        `;
        
        // Add click handler to open signup modal
        button.addEventListener('click', () => {
          const authButton = document.querySelector('.sign-up-button');
          if (authButton) {
            authButton.click();
          }
        });
        
        navContainer.appendChild(button);
      }
    };

    api.onPageChange(() => {
      setTimeout(addNewTopicButton, 100);
    });
    
    api.onAppEvent('page:changed', () => {
      setTimeout(addNewTopicButton, 100);
    });
  });
})();

Step 2: Add the CSS

Add this CSS to your theme's Stylesheet section:

.guest-new-topic-button {
    color: var(--secondary);
    background: var(--tertiary);
    transition: all .3s linear;
    border-radius: var(--mint-border-radius);
    text-transform: uppercase;
    border: 2px solid var(--tertiary);
    margin-left: 1em;
    height: 38px !important;
    min-height: 38px !important;
    padding: 3px 12px !important;
    line-height: 1 !important;
}

.guest-new-topic-button:hover {
    background: color-mix(in srgb, var(--tertiary) 85%, black) !important;
    border-color: color-mix(in srgb, var(--tertiary) 85%, black) !important;
}

.guest-new-topic-button .d-icon {
    font-size: 0.8em;
    margin-right: 4px;
}

.guest-new-topic-button .d-button-label {
    font-size: 0.9em;
}

What This Does

  1. Shows a "New Topic" button to non-logged-in users
  2. Matches the style of the regular "New Topic" button
  3. Opens the signup modal when clicked
  4. Persists across page navigation
  5. Only appears for guests (non-logged-in users)

Troubleshooting

If the button doesn't appear:

  • Verify you added the code to the Body section
  • Test while logged out
  • Clear your browser cache and reload
  • Make sure you're not running other themes that might conflict

Background

Finding a solution for this was challenging because:

  1. Discourse's documentation doesn't cover this specific use case
  2. The button needs to persist across Discourse's single-page navigation
  3. The solution requires understanding of Discourse's plugin API
  4. There weren't many resources available online about this specific customization

Need Help?

If you run into issues or need to customize the button further, the Discourse community forums are a great place to ask for help. Remember to share any improvements you discover to help others!