165

I want to create common header and footer pages that are included on several html pages.

I'd like to use javascript. Is there a way to do this using only html and JavaScript?

I want to load a header and footer page within another html page.

m4n0
  • 25,434
  • 12
  • 57
  • 77
Prasanth A R
  • 3,556
  • 9
  • 44
  • 67

12 Answers12

218

You can accomplish this with jquery.

Place this code in index.html

<html>
<head>
<title></title>
<script
    src="https://code.jquery.com/jquery-3.3.1.js"
    integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
    crossorigin="anonymous">
</script>
<script> 
$(function(){
  $("#header").load("header.html"); 
  $("#footer").load("footer.html"); 
});
</script> 
</head>
<body>
<div id="header"></div>
<!--Remaining section-->
<div id="footer"></div>
</body>
</html>

and put this code in header.html and footer.html, at the same location as index.html

<a href="http://www.google.com">click here for google</a>

Now, when you visit index.html, you should be able to click the link tags.

iAMkVIN_S
  • 1
  • 2
Hariprasad Prolanx
  • 2,362
  • 1
  • 14
  • 13
  • Yes. all page should have these page structure – Hariprasad Prolanx Sep 10 '13 at 07:25
  • Yes and we are just calling the content from other html files – Hariprasad Prolanx Sep 10 '13 at 07:51
  • that means the other 2 html pages header.html and footer.html that pages contain the contents.. – Prasanth A R Sep 10 '13 at 08:10
  • Does this load fast enough that the user doesn't see a blip on every page load? I was wondering whether it would be necessary to store the html in a cookie or local storage for quicker reloading. – kalenjordan Mar 20 '14 at 22:55
  • 20
    load or other function that import or use a `local file` not work in new version of Google Chrome or IE, reason: security! – Sinac Jan 12 '15 at 18:56
  • Couple issues with this approach. It will not work on chrome when you are working locally. You have to put it on local server. The other issue it will load header and footer after it renders all html. So that there will be a delay to load header and footers. [http://stackoverflow.com/a/25288597] (More information) – kalibrain Feb 04 '15 at 19:01
  • 9
    Sometimes I wonder how people can even breathe without jQuery. Or is there a `.breathe(in)` and `.breathe(out)` already? Any scripting language is pure overkill here. – The Conspiracy Apr 24 '15 at 22:38
  • 6
    I keep getting `Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.` when I run in chrome – digiwebguy Apr 07 '16 at 11:16
  • 2
    It is required to run the code in server. Which means url needs to be like "http://.....". – Patriotic Apr 23 '17 at 15:58
  • 1
    Patriotic is right, it must run under a web server. – Fabio Belz May 25 '17 at 13:59
  • You can see [my answer below using HTML5 Templates](https://stackoverflow.com/a/46515280/7120290) – JavierFuentes Oct 21 '17 at 09:24
  • The cross origin error will only be a problem locally because you access the file through file:// protocol. Have a look at this [answer](https://stackoverflow.com/a/20578692/4266296). You can either test locally with Firefox, upload the file(s) to a server or run a web server locally like other comments already mentioned. – fap Oct 24 '17 at 12:29
  • If the footer / header has a lot of links, what will be the impact of using this technique on seo ? – JP. Feb 03 '18 at 01:45
  • the only downside is that the links and stuff will be loaded in the `` and not in the `
    `
    – Morris S Mar 25 '18 at 05:57
  • Guys who are having trouble making it work, Make sure: 1) you are running a local server. 2) you are not using defer/async for Jquery script. – SKG Dec 24 '18 at 19:51
  • Thanks for the above method, Is this going to work if we use bootstrap on the page included and also on the home page? – sm.ali Apr 28 '20 at 17:40
  • Is this an acceptable answer or this approach with the local file has been stopped by chrome as mentioned in the comments? – user3156040 Dec 29 '20 at 18:13
45

I add common parts as header and footer using Server Side Includes. No HTML and no JavaScript is needed. Instead, the webserver automatically adds the included code before doing anything else.

Just add the following line where you want to include your file:

<!--#include file="include_head.html" -->
The Conspiracy
  • 2,225
  • 15
  • 17
  • 9
    i like this old-fashioned way. In fact, it doesn't seem to have a whole lot benefits using script to do such a simple action. – Jenna Leaf Aug 05 '15 at 11:38
  • 3
    In fact, including files using a script has major disadvantages: It hinders performance as the client needs to download the main page, load the DOM, run the script and only then can download the included files, which needs an additional server request per included file. Including files using Server Side Includes serves all elements during the first server request, there's no client action needed. – The Conspiracy Aug 06 '15 at 16:48
  • SSI requires using a file extension of: `.shtml`, `.stm`, `.shtm`. It works in Apache, LiteSpeed, nginx, lighttpd and IIS. – ubershmekel Sep 29 '17 at 02:25
  • @ubershmekel As you said, the relevant webservers support SSI. The file extension is not limited to `.shtml`, `.stm` and `.shtm`: On IIS, all parsed files may contain SSI, e.g. `.aspx`. If working with PHP, you need to use the PHP `include` or `virtual` command instead to achieve the same result. – The Conspiracy Sep 30 '17 at 04:34
38

Must you use html file structure with JavaScript? Have you considered using PHP instead so that you can use simple PHP include object?

If you convert the file names of your .html pages to .php - then at the top of each of your .php pages you can use one line of code to include the content from your header.php

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

Do the same in the footer of each page to include the content from your footer.php file

<?php include('footer.php'); ?>

No JavaScript / Jquery or additional included files required.

NB You could also convert your .html files to .php files using the following in your .htaccess file

# re-write html to php
RewriteRule ^(.*)\.html$ $1.php [L]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]


# re-write no extension to .php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Sol
  • 851
  • 8
  • 16
  • 2
    @Justin808 - the OP mentions nothing about a local hosted installation, so I presumed he was talking about server based files. – Sol Apr 25 '15 at 05:49
  • 1
    @Sol However the OP DID specifically mention wanting to use Javascript, so your answer is off-topic. Full-stack web development is quickly moving away from using PHP at all, Node.js provides all of the equivalent functionality and requires only Javascript to be used. TL;DR please answer questions as asked. The OP wanted a JS solution, so it's inappropriate to give him a solution PHP, Ruby, Python, C++, or any other language. – Zach Jul 24 '17 at 07:55
12

You could also put: (load_essentials.js:)

document.getElementById("myHead").innerHTML =
 "<span id='headerText'>Title</span>"
 + "<span id='headerSubtext'>Subtitle</span>";
document.getElementById("myNav").innerHTML =
 "<ul id='navLinks'>"
 + "<li><a href='index.html'>Home</a></li>"
 + "<li><a href='about.html'>About</a>"
 + "<li><a href='donate.html'>Donate</a></li>"
 + "</ul>";
document.getElementById("myFooter").innerHTML =
 "<p id='copyright'>Copyright &copy; " + new Date().getFullYear() + " You. All"
 + " rights reserved.</p>"
 + "<p id='credits'>Layout by You</p>"
 + "<p id='contact'><a href='mailto:you@you.com'>Contact Us</a> / "
 + "<a href='mailto:you@you.com'>Report a problem.</a></p>";
<!--HTML-->
<header id="myHead"></header>
<nav id="myNav"></nav>
Content
<footer id="myFooter"></footer>

<script src="load_essentials.js"></script>
JustinM
  • 105
  • 1
  • 8
10

I tried this: Create a file header.html like

<!-- Meta -->
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- JS -->
<script type="text/javascript" src="js/lib/jquery-1.11.1.min.js" ></script>
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/lib/angular-resource.min.js"></script>
<script type="text/javascript" src="js/lib/angular-route.min.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">

<title>Your application</title>

Now include header.html in your HTML pages like:

<head>
   <script type="text/javascript" src="js/lib/jquery-1.11.1.min.js" ></script>
   <script> 
     $(function(){ $("head").load("header.html") });
   </script>
</head>

Works perfectly fine.

Asheesh Gupta
  • 298
  • 3
  • 2
  • 2
    Nice solution, but I think this would load the jquery framework twice, once for the initial page load, and secondly when the .load() method executes - since the target page also contains jquery. – Delali Feb 24 '17 at 16:26
6

I've been working in C#/Razor and since I don't have IIS setup on my home laptop I looked for a javascript solution to load in views while creating static markup for our project.

I stumbled upon a website explaining methods of "ditching jquery," it demonstrates a method on the site does exactly what you're after in plain Jane javascript (reference link at the bottom of post). Be sure to investigate any security vulnerabilities and compatibility issues if you intend to use this in production. I am not, so I never looked into it myself.

JS Function

var getURL = function (url, success, error) {
    if (!window.XMLHttpRequest) return;
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            if (request.status !== 200) {
                if (error && typeof error === 'function') {
                    error(request.responseText, request);
                }
                return;
            }
            if (success && typeof success === 'function') {
                success(request.responseText, request);
            }
        }
    };
    request.open('GET', url);
    request.send();
};

Get the content

getURL(
    '/views/header.html',
    function (data) {
        var el = document.createElement(el);
        el.innerHTML = data;
        var fetch = el.querySelector('#new-header');
        var embed = document.querySelector('#header');
        if (!fetch || !embed) return;
        embed.innerHTML = fetch.innerHTML;

    }
);

index.html

<!-- This element will be replaced with #new-header -->
<div id="header"></div>

views/header.html

<!-- This element will replace #header -->
<header id="new-header"></header>

The source is not my own, I'm merely referencing it as it's a good vanilla javascript solution to the OP. Original code lives here: http://gomakethings.com/ditching-jquery#get-html-from-another-page

darcher
  • 2,772
  • 3
  • 19
  • 27
5

I think, answers to this question are too old... currently some desktop and mobile browsers support HTML Templates for doing this.

I've built a little example:

Tested OK in Chrome 61.0, Opera 48.0, Opera Neon 1.0, Android Browser 6.0, Chrome Mobile 61.0 and Adblocker Browser 54.0
Tested KO in Safari 10.1, Firefox 56.0, Edge 38.14 and IE 11

More compatibility info in canisue.com

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML Template Example</title>

    <link rel="stylesheet" href="styles.css">
    <link rel="import" href="autoload-template.html">
</head>
<body>

<div class="template-container">1</div>
<div class="template-container">2</div>
<div class="template-container">3</div>
<div class="template-container">4</div>
<div class="template-container">5</div>

</body>
</html>

autoload-template.html

<span id="template-content">
    Template Hello World!
</span>

<script>
    var me = document.currentScript.ownerDocument;
    var post = me.querySelector( '#template-content' );

    var container = document.querySelectorAll( '.template-container' );

    //alert( container.length );
    for(i=0; i<container.length ; i++) {
        container[i].appendChild( post.cloneNode( true ) );
    }
</script>

styles.css

#template-content {
    color: red;
}

.template-container {
    background-color: yellow;
    color: blue;
}

Your can get more examples in this HTML5 Rocks post

JavierFuentes
  • 1,552
  • 15
  • 12
3

Aloha from 2018. Unfortunately, I don't have anything cool or futuristic to share with you.

I did however want to point out to those who have commented that the jQuery load() method isn't working in the present are probably trying to use the method with local files without running a local web server. Doing so will throw the above mentioned "cross origin" error, which specifies that cross origin requests such as that made by the load method are only supported for protocol schemes like http, data, or https. (I'm assuming that you're not making an actual cross-origin request, i.e the header.html file is actually on the same domain as the page you're requesting it from)

So, if the accepted answer above isn't working for you, please make sure you're running a web server. The quickest and simplest way to do that if you're in a rush (and using a Mac, which has Python pre-installed) would be to spin up a simple Python http server. You can see how easy it is to do that here.

I hope this helps!

Rich
  • 2,362
  • 3
  • 13
  • 26
2

It is also possible to load scripts and links into the header. I'll be adding it one of the examples above...

<!--load_essentials.js-->
document.write('<link rel="stylesheet" type="text/css" href="css/style.css" />');
document.write('<link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />');
document.write('<script src="js/jquery.js" type="text/javascript"></script>');

document.getElementById("myHead").innerHTML =
"<span id='headerText'>Title</span>"
+ "<span id='headerSubtext'>Subtitle</span>";
document.getElementById("myNav").innerHTML =
"<ul id='navLinks'>"
+ "<li><a href='index.html'>Home</a></li>"
+ "<li><a href='about.html'>About</a>"
+ "<li><a href='donate.html'>Donate</a></li>"
+ "</ul>";
document.getElementById("myFooter").innerHTML =
"<p id='copyright'>Copyright &copy; " + new Date().getFullYear() + " You. All"
+ " rights reserved.</p>"
+ "<p id='credits'>Layout by You</p>"
+ "<p id='contact'><a href='mailto:you@you.com'>Contact Us</a> / "
+ "<a href='mailto:you@you.com'>Report a problem.</a></p>";

<!--HTML-->
<header id="myHead"></header>
<nav id="myNav"></nav>
Content
<footer id="myFooter"></footer>

<script src="load_essentials.js"></script>
1

another approach made available since this question was first asked is to use reactrb-express (see http://reactrb.org) This will let you script in ruby on the client side, replacing your html code with react components written in ruby.

Mitch VanDuyn
  • 2,604
  • 1
  • 16
  • 27
  • 2
    op asked only using html and javascript but you take him to use ruby.. :D lol but cool tool man.. – Meily Chhon Jan 20 '17 at 04:25
  • I took the spirit of the question to be - without serverside templating languages. it all compiles down to Javascript so I believe it meets the intent of the question. – Mitch VanDuyn Jan 25 '17 at 13:39
1

For a quick setup with plain javascript and because not answered yet, you could also use a .js file to store your redundant pieces (templates) of HTML inside a variable and insert it through innerHTML.

backticks are here the make it easy part this answer is about.
(you will also want to follow the link on that backticks SO Q/A if you read & test that answer).

example for a navbar that remains the same on each page :

<nav role="navigation'>
    <a href="/" class="here"><img src="image.png" alt="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>
</nav>

You can keep inside your HTMl :

<nav role="navigation"></nav>

and set inside nav.js file the content of <nav> as a variable in between backticks:

const nav= `
    <a href="/" class="here"><img src="image.png" alt="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>
` ;

Now you have a small file from which you can retrieve a variable containing HTML. It looks very similar to include.php and can easily be updated without messing it up (what's inside the backticks).

You can now link that file like any other javascript file and innerHTML the var nav inside <nav role="navigation"></nav> via

let barnav = document.querySelector('nav[role="navigation"]');
    barnav.innerHTML = nav;

If you add or remove pages, you only have to update once nav.js

basic HTML page can be :

// code standing inside nav.js for easy edit
const nav = `
    <a href="/" class="here"><img src="image.png" alt="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>
`;
nav[role="navigation"] {
  display: flex;
  justify-content: space-around;
}
<!DOCTYPE html>

<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Home</title>
  <!-- update title   if not home page -->
  <meta name="description" content=" HTML5 ">
  <meta name="author" content="MasterOfMyComputer">
  <script src="nav.js"></script>
  <!-- load an html template through a variable -->
  <link rel="stylesheet" href="css/styles.css?v=1.0">
</head>

<body>

  <nav role="navigation">
    <!-- it will be loaded here -->
  </nav>
  <h1>Home</h1>
  <!-- update h1 if not home page -->

  <script>
    // this part can also be part of nav.js 
    window.addEventListener('DOMContentLoaded', () => {
      let barnav = document.querySelector('nav[role="navigation"]');
      barnav.innerHTML = nav;
    });
  </script>
</body>

</html>

This quick example works & can be copy/paste then edited to change variable names and variable HTML content.

Looky1173
  • 35
  • 1
  • 8
G-Cyrillus
  • 85,910
  • 13
  • 85
  • 110
-2

Credits : W3 Schools How to Include HTML

Save the HTML you want to include in an .html file:

Content.html

<a href="howto_google_maps.asp">Google Maps</a><br>
<a href="howto_css_animate_buttons.asp">Animated Buttons</a><br>
<a href="howto_css_modals.asp">Modal Boxes</a><br>
<a href="howto_js_animate.asp">Animations</a><br>
<a href="howto_js_progressbar.asp">Progress Bars</a><br>
<a href="howto_css_dropdown.asp">Hover Dropdowns</a><br>
<a href="howto_js_dropdown.asp">Click Dropdowns</a><br>
<a href="howto_css_table_responsive.asp">Responsive Tables</a><br>

Include the HTML

Including HTML is done by using a w3-include-html attribute:

Example

    <div w3-include-html="content.html"></div>

Add the JavaScript

HTML includes are done by JavaScript.

    <script>
    function includeHTML() {
      var z, i, elmnt, file, xhttp;
      /*loop through a collection of all HTML elements:*/
      z = document.getElementsByTagName("*");
      for (i = 0; i < z.length; i++) {
        elmnt = z[i];
        /*search for elements with a certain atrribute:*/
        file = elmnt.getAttribute("w3-include-html");
        if (file) {
          /*make an HTTP request using the attribute value as the file name:*/
          xhttp = new XMLHttpRequest();
          xhttp.onreadystatechange = function() {
            if (this.readyState == 4) {
              if (this.status == 200) {elmnt.innerHTML = this.responseText;}
              if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
              /*remove the attribute, and call this function once more:*/
              elmnt.removeAttribute("w3-include-html");
              includeHTML();
            }
          } 
          xhttp.open("GET", file, true);
          xhttp.send();
          /*exit the function:*/
          return;
        }
      }
    }
    </script>

Call includeHTML() at the bottom of the page:

Example

<!DOCTYPE html>
<html>
<script>
function includeHTML() {
  var z, i, elmnt, file, xhttp;
  /*loop through a collection of all HTML elements:*/
  z = document.getElementsByTagName("*");
  for (i = 0; i < z.length; i++) {
    elmnt = z[i];
    /*search for elements with a certain atrribute:*/
    file = elmnt.getAttribute("w3-include-html");
    if (file) {
      /*make an HTTP request using the attribute value as the file name:*/
      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4) {
          if (this.status == 200) {elmnt.innerHTML = this.responseText;}
          if (this.status == 404) {elmnt.innerHTML = "Page not found.";}
          /*remove the attribute, and call this function once more:*/
          elmnt.removeAttribute("w3-include-html");
          includeHTML();
        }
      }      
      xhttp.open("GET", file, true);
      xhttp.send();
      /*exit the function:*/
      return;
    }
  }
};
</script>
<body>

<div w3-include-html="h1.html"></div> 
<div w3-include-html="content.html"></div> 

<script>
includeHTML();
</script>

</body>
</html>
Raaf003
  • 103
  • 1
  • 7