How do I make reusable HTML elements in a Django project?

I'm new to Django, and I'm working on a project where I'm reusing static pages and changing them to be suitable Django templates. As a part of the previous project, I made some custom HTML elements using JavaScript files and customElements.define() since I'm not familiar with React.

I realized that Django's templates can't modify the static JS files where these elements live, and in particular links can't be modified. The main element that I really want to be able to port over to this project is a navigation bar at the top of the screen that has a link to the homepage, and, depending on whether the user is logged in or not, will either show "login" + "register" buttons, or a notification icon and profile picture.

I don't really know what the best way to do this is, I've seen some suggestions where I turn the navbar element into a templatetag, and some others are just placing the raw HTML into a file and including that inside the templates.

This is the current code that I have for my navbar:

/**
 * The main navigation bar that should only present one time in each page
 * of the website.
 */
class NavBar extends HTMLElement {
    constructor() {
        super();
    }

    connectedCallback() {
        
        this.innerHTML = `
            <nav>
                <div id="nav-bar-left">
                    <p class="home-page-link">
                        <a href="./home.html">Games Forum</a>
                    </p>
                </div>

                // this div should be shown when the user isn't logged in
                <div id="log-in-options" class="nav-log-dependent" data-active="true">
                    <button class="primary-button" id="to-login">Log In</button>
                    <button class="secondary-button" id="to-signup">Sign Up</button>
                </div>

                // this div should be shown when the user IS logged in
                <div id="logged-in-options" class="nav-log-dependent" data-active="false">
                    <svg class="small-icon"><use href="../assets/icons/icons.svg#bell"></use></svg>
                    <svg class="icon"><use href="../assets/icons/icons.svg#circle-user"></use></svg>
                </div>
            </nav>
        `;

        this.querySelector('#to-login').addEventListener('click', () => {
            // this should somehow have the login page url
            window.location.href = "login.html"
        })

        this.querySelector('#to-signup').addEventListener('click', () => {
            // this should somehow have the page url, I hard coded this in the previous project
            window.location.href = "register.html"
        })
    }
}

customElements.define("nav-bar", NavBar);

What is the best way to do this? Should I even bother with this or switch to doing something else?

The way it’s usually done with web components is to add a little bit of extra information to your main HTML template and then react to it in the web component/custom element. For example, in the template where you compose the content of the <head> element, add something similar to the following code (assuming the auth context processor is active):

<script>
const currentUser = {% if user.is_authenticated %}{
  "user": "{{ user.username }}",
}{% else %}null{% endif %};
</script>

Now you can change the innerHTML of your custom element based on the currentUser JS variable.

There are different solutions, too. E.g., the custom element could query an API endpoint to check for authentication data (basically a Django view that returns JSON), or you could parametrize the custom element, if you’ve got the auth information at that place:

<nav-bar user="some user data"></nav-bar>

The chosen way to implement should preferably depend on the exact problems that you need to solve.

However, if you do not need any of the dynamic features of web components, it might actually be easier for you to make the nav bar into a template that you can re-use:

<nav>
     <div id="nav-bar-left">
        <p class="home-page-link">
            <a href="./home.html">Games Forum</a>
        </p>
    </div>

    {# this div should be shown when the user isn't logged in #}
  {% if user.is_authenticated %}
    <div id="log-in-options" class="nav-log-dependent" data-active="true">
        {# Attention! changed button to a here. #}
        <a href="login.html" class="primary-button" id="to-login">Log In</a>
        <a href="register.html" class="secondary-button" id="to-signup">Sign Up</a>
    </div>
  {% else %}
    {# this div should be shown when the user IS logged in #}
    <div id="logged-in-options" class="nav-log-dependent" data-active="false">
        <svg class="small-icon"><use href="../assets/icons/icons.svg#bell"></use></svg>
        <svg class="icon"><use href="../assets/icons/icons.svg#circle-user"></use></svg>
    </div>
  {% endif %}
</nav>

and then including it at the place where you need it:

{% include "nav-bar.html" %}
Вернуться на верх