How can I reuse a navigation bar on multiple pages?
Asked Answered
S

8

154

I just finished making my home/index.html page. To keep the nav bar where it is, and have it stay while users click through all my pages. Do I have to copy and paste the nav code to the top of each page? Or is there another way to do so that would look cleaner?

HMTL nav:

<nav>
    <div>
        <a href="/">
            <div id="logo"><img src="image.png" alt="Home"/></div>
            <div id="headtag"><img src="image.png" alt="Home"/></div>
            <div id="tagline"><img src="image.png" alt="Home"/></div>
        </a>
    </div>
    <div> 
        <a href="/" class="here">Home</a>
        <a href="/about.html" >About</a>      
        <a href="/services.html" >Services</a>          
        <a href="/pricing.html" >Pricing</a>    
        <a href="/contact.html" >Contact Us</a>
        <input id="srchbar" type="search" placeholder="Search">
    </div>
</nav>
Spikelet answered 12/8, 2015 at 0:19 Comment(3)
Yes. Keep in mind that when a user clicks a link in your navigation, your server/local system is sending the file indicated by the link to be downloaded and displayed. When they click "About," about.html will be loaded by the browser. So it should contain the same navigation.Anarchism
if you have a server side language you can put this code in a template and include in all pages else use angular js to make this a directiveJahncke
I'm looking for the same thing. This is a shame that in 2017 we can't do this with a client based web site. Microsoft has had the concept of a master page (_layouts in the current version) forever. Seems like a client side "container page" wouldn't be ridiculous.Louisalouisburg
D
129

This is what helped me. My navigation bar is in the body tag. Entire code for navigation bar is in nav.html file (without any html or body tag, only the code for navigation bar). In the target page, this goes in the head tag:

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>

Then in the body tag, a container is made with an unique id and a javascript block to load the nav.html into the container, as follows:

<!--Navigation bar-->
<div id="nav-placeholder">

</div>

<script>
$(function(){
  $("#nav-placeholder").load("nav.html");
});
</script>
<!--end of Navigation bar-->
Donohoe answered 19/2, 2017 at 22:5 Comment(12)
Hello. I don't know anything about jquery/javascript but I just wanted to try this. I tried doing exactly what you said. I have my nav menu on one page without any other tags and I included the rest of the code in the head/body of my index page (simple index page). However, it doesn't load my navbar on all pages. Any idea what I might do wrong ? Thank you !Farias
@Farias does it show at all? I have to tell you that while development (loading the page locally) this code often does not work. Have you placed this code on a server?Donohoe
Slightly off-topic, and forgive my ignorance: if you hardcode the jQuery version as you did in your answer: <script src="https://code.jquery.com/jquery-1.10.2.js"></script>, then what happens to your page when Version 1.10.3 or 1.11.0 come out?Herbartian
@LaryxDecidua Then it continues to work. Always loading the latest version would risk breaking the page. Think of breaking changes between versions. Therefore testing is recommended when switching to a different version.Fort
I used the above code in index.html on local pc, tested in chrome, it give me error below and the nav.html not able to be loaded.jquery.min.js:4 Access to XMLHttpRequest at 'nav.html' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https. Any idea?Sherbet
@Sherbet Where are you serving your nav.html code from? You may need to enable CORS permission on that service (e.g AWS API gateway allows you to enable CORS -- search for how to do that if using AWS). If you are just testing in chrome, you may need to grab the extension. When perform do a COR, a preflight request is sent via the OPTION (like post or get, but option) which is a fake request that uses specif headers checked by the server. If the server isn't configured to accept CO requests (which by default it shouldn't be), then you need to configure that and then specify this in the header.Gilbye
@Sherbet that error is because you're serving the file locally using file:/// which Chrome won't allow. Use Python to spin up a simple HTTP server in the directory of your HTML documents and it should load without error. cd user/website/ then python -m SimpleHTTPServerGelhar
This is the best approach. See here for a full example with link to github project mackenziesoftware.com/#/2020/06/…Daphnedaphnis
@Sherbet I'm having the same CORS issue. Did you fix it?Tamas
@Donohoe but this will too need to add <div id="nav-placeholder"> on every page. What about layout template like frame maybe?Alrick
Used this in virtually the same way, but I'm having a problem with linking to it. The links in my navbar point to the placeholder id, so that the navbar displays at the top of the page. (there's some banner stuff above it, which I don't want to display in this case) In most cases this works fine, but sometimes the link points to just 'below' the navbar, and it's just out of view, (above the displayed part of the page) Pages with many images seem to suffer from this the most, but not always. My suspicion is that it's loading 'late', but I'm not sure how to fix thisSudhir
@Ramtin, my issue seems to be the same one that Lay was facing. I AM aware that this doesn't work locally, I'm working on the uploaded version. Which in most cases works perfectly. About 25% of the pages the navbar loads offscreen, and in a few cases it visually pops in after half a second. (Which isn't dealbreaking, but looks sloppy) I'm failing to grasp why this occurs, since the placeholder div is available on the page to link to, even if the data isn't loaded in yet. If the div is the top of the page, shouldn't the navbar load in at the top as well, even if it's late?Sudhir
H
44

I know this is a quite old question, but when you have JavaScript available you could use jQuery and its AJAX methods.

First, create a page with all the navigation bar's HTML content.

Next, use jQuery's $.get method to fetch the content of the page. For example, let's say you've put all the navigation bar's HTML into a file called navigation.html and added a placeholder tag (Like <div id="nav-placeholder">) in your index.html, then you would use the following code:

<script src="//code.jquery.com/jquery.min.js"></script>
<script>
$.get("navigation.html", function(data){
    $("#nav-placeholder").replaceWith(data);
});
</script>
Hanus answered 23/11, 2015 at 16:38 Comment(2)
This one is better than https://mcmap.net/q/156328/-how-can-i-reuse-a-navigation-bar-on-multiple-pages, because it actually replaces the placeholder element.Colmar
Is there a reason one should not use this?? replaceWith? seems kinda straight forwardSedimentation
S
24

Using pure javascript:

Keep your navbar html code in nav.html file.

Create nav.js file with this code:

fetch('nav.html')
.then(res => res.text())
.then(text => {
    let oldelem = document.querySelector("script#replace_with_navbar");
    let newelem = document.createElement("div");
    newelem.innerHTML = text;
    oldelem.parentNode.replaceChild(newelem,oldelem);
})

And in other html files that you want navbar add this line:

<script id="replace_with_navbar" src="nav.js"></script>

This will replace the script itself with the content of nav.html

Stylish answered 24/8, 2021 at 15:19 Comment(5)
Works with static items, if there are toggle classes or dropdown menus it didn't work. Any solution to make it work with dropdowns, toggle?Innocence
I love you @Mendi Barel. This is what I've been looking for. It separates my JavaScript from my HTML and it works with bootstrap. It even fixed my problem with the dropdown not working. THANK YOU!Firstly
Instead of using .innerHTML, wouldn't it be better to use DOMParser?Scanner
@AbuNooh Seems like the problem is due to the fact that fetch() takes time to run, and the interactivity of the drop-down menu loaded before fetch() finished running. If you check the console, you'll see that it outputs an error of some kind, probably the code complaining that it couldn't find an element. A hacky solution would be to have a setTimeout() for your Javascript interactivity code, or running your interactivity code after the fetch() with another .then().Carlenacarlene
@Scanner Yes, thank you for pointing this out, it's more elegant to do this way: ``` fetch("../header-nav.html") .then((response) => response.text()) .then((data) => { let old_element = document.querySelector( "script#replace-with-header-navbar" ); let new_element = new DOMParser() .parseFromString(data, "text/html") .querySelector("nav"); old_element.parentNode.replaceChild(new_element, old_element); }) .catch((err) => console.log(err)); ```Inhale
S
8

You can use php for making multi-page website.

  • Create a header.php in which you should put all your html code for menu's and social media etc
  • Insert header.php in your index.php using following code

<? php include 'header.php'; ?>

(Above code will dump all html code before this)Your site body content.

  • Similarly you can create footer and other elements with ease. PHP built-in support html code in their extensions. So, better learn this easy fix.
Serow answered 12/8, 2015 at 1:45 Comment(4)
So are you all saying i should convert all this to PHP, instead of multiple HTML pages for my site? It's my first site, and I know html, thats why I used it, but if it should be PHP, then it should be PHP.... So which should it be?Spikelet
This is very basic php which you can learn easily. You won't face nightmare's once when you convert your side to use a server side language. I do recommend this. But if you are intend to use only html, consider .shtml for small issues, still i find it clunky for growing websites.Serow
Ok. Now that this page is html. How do i convert it to php? Is it a few entries or do I have to redo all my tags? And if so, how.... So I don't screw it up haSpikelet
Change extension to .php and you're done. use following code braces to enter php code <?php include 'header.php'; ?> Go to php.net or w3schools for basic learning.Serow
A
5

Brando ZWZ provides some great answers to handling this situation.

Re: Same navbar on multiple pages Aug 21, 2018 10:13 AM|LINK

As far as I know, there are multiple solution.

For example:

The Entire code for navigation bar is in nav.html file (without any html or body tag, only the code for navigation bar).

Then we could directly load it from the jquery without writing a lot of codes.

Like this:

    <!--Navigation bar-->
    <div id="nav-placeholder">

    </div>

    <script>
    $(function(){
      $("#nav-placeholder").load("nav.html");
    });
    </script>
    <!--end of Navigation bar-->

Solution2:

You could use JavaScript code to generate the whole nav bar.

Like this:

Javascript code:

$(function () {
    var bar = '';
    bar += '<nav class="navbar navbar-default" role="navigation">';
    bar += '<div class="container-fluid">';
    bar += '<div>';
    bar += '<ul class="nav navbar-nav">';
    bar += '<li id="home"><a href="home.html">Home</a></li>';
    bar += '<li id="index"><a href="index.html">Index</a></li>';
    bar += '<li id="about"><a href="about.html">About</a></li>';
    bar += '</ul>';
    bar += '</div>';
    bar += '</div>';
    bar += '</nav>';

    $("#main-bar").html(bar);

    var id = getValueByName("id");
    $("#" + id).addClass("active");
});

function getValueByName(name) {
    var url = document.getElementById('nav-bar').getAttribute('src');
    var param = new Array();
    if (url.indexOf("?") != -1) {
        var source = url.split("?")[1];
        items = source.split("&");
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            var parameters = item.split("=");
            if (parameters[0] == "id") {
                return parameters[1];
            }
        }
    }
}

Html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <div id="main-bar"></div>
    <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <%--add this line to generate the nav bar--%>
    <script src="../assets/js/nav-bar.js?id=index" id="nav-bar"></script>
</body>
</html>

https://forums.asp.net/t/2145711.aspx?Same+navbar+on+multiple+pages

Auroraauroral answered 13/6, 2019 at 1:54 Comment(0)
S
3

A very old but simple enough technique is to use "Server-Side Includes", to include HTML pages into a top-level page that has the .shtml extension. For instance this would be your index.shtml file:

<html>
<head>...</head>
<body>
<!-- repeated header: note that the #include is in a HTML comment -->
<!--#include file="header.html" -->
<!-- unique content here... -->
</body>
</html>

Yes, it is lame, but it works. Remember to enable SSI support in your HTTP server configuration (this is how to do it for Apache).

Seifert answered 26/8, 2018 at 9:13 Comment(0)
U
1

In your javascript file you can create a element with the HTML code as string and then insert that variable in the beginning of your HTML using insertAdjacentHTML keyword

    var navbar = ` 
        <nav>
            <div>
                <a href="/">
                    <div id="logo">
                        <img src="image.png" alt="Home" />
                    </div>
                    <div>
                        <img src="image.png" alt="Home" />
                    </div>
                    <div id="tagline">
                        <img src="image.png" alt="Home" />
                    </div>
                </a>
            </div>
            <div>
                <a href="/" class="here">
                    Home
                </a>
                <a href="/about.html">About</a>
                <a href="/services.html">Services</a>
                <a href="/pricing.html">Pricing</a>
                <a href="/contact.html">Contact Us</a>
            </div>
        </nav>`;

        // inserting navbar in beginning of body
        document.body.insertAdjacentHTML("afterbegin", navbar);

Lastly link the Javascript file to your HTML using

script src="script.js"></script>
Unplug answered 28/2, 2022 at 6:41 Comment(0)
R
1

Very simple without any scripting.

Write your html in a normal (external) html file and in the html file(s) you want to include its contents, add the following:

<embed type="text/html" src="my-menu.html">
Rattlebox answered 15/8, 2022 at 20:19 Comment(1)
I am afraid, why is it bad way? looks very simple code...Tjirebon

© 2022 - 2024 — McMap. All rights reserved.