Skip to content Go to Sitemap

Layout Base Code

Tired of having to update all of you HTML files every time you update your layout? Here's a solution. We'll be using JavaScript to load a header and footer on every page. We'll also take care of active links and relative paths.


What it does

Your header and footer HTML will be in a single JavaScript file, so you'll only need to update it once.

HTML in your .html file:

<body>
  <main>
    your page here...
  </main>
</body>

HTML rendered in the browser (the script automatically adds the header and footer):

<body>
  <header>...</header>
  <main>
    your page here...
  </main>
  <footer>...</footer>
</body>

You can see the code in action here.


Tutorial

Step 1: The JS code

Create a javascript file (e.g. layout.js) in the root of your project, and insert the following code:

// initLayout() is called once the DOM (the HTML content of your website) has been loaded.
document.addEventListener("DOMContentLoaded", function () {
  // The layout will be loaded on all pages that do NOT have the "no-layout" class in the <body> element.
  if (document.body.classList.contains("no-layout")) return;

  // Inserting your header and footer:
  document.body.insertAdjacentHTML("afterbegin", headerEl);
  document.body.insertAdjacentHTML("beforeend", footerEl);

  // Other initializations:
  initActiveLinks();

  // your code here...
});

/* ********************************* */

/**
 *  F U N C T I O N S
 */

function initActiveLinks() {
  // This function adds the class "active" to any link that links to the current page.
  // This is helpful for styling the active menu item.

  const pathname = window.location.pathname;
  [...document.querySelectorAll("a")].forEach((el) => {
    const elHref = el.getAttribute("href").replace(".html", "").replace("/public", "");

    if (pathname == "/") {
      // homepage
      if (elHref == "/" || elHref == "/index.html") el.classList.add("active");
    } else {
      // other pages
      if (window.location.href.includes(elHref)) el.classList.add("active");
    }
  });
}

function getNestingString() {
  // This function prepares the "nesting" variable for your header and footer (see below).
  // Only change this function if you know what you're doing.
  const currentUrl = window.location.href.replace("http://", "").replace("https://", "").replace("/public/", "/");
  const numberOfSlahes = currentUrl.split("/").length - 1;
  if (numberOfSlahes == 1) return ".";
  if (numberOfSlahes == 2) return "..";
  return ".." + "/..".repeat(numberOfSlahes - 2);
}

/* ********************************* */

/**
 *  H T M L
 */

const nesting = getNestingString();

/**
  Use ${nesting} to output a . or .. or ../.. etc according to the current page's folder depth.
  Example:
    <img src="${nesting}/images/example.jpg" />
  will output
  	 <img src="./images/example.jpg" /> on a page that isn't in any folder.
    <img src="../images/example.jpg" /> on a page that is in a folder.
    <img src="../../images/example.jpg" /> on a page that is in a sub-folder.
    etc.
 */

// Insert your header HTML inside these ``. You can use HTML as usual. 
// You don't need to use the <header> element, but I recommend it.
const headerEl = `
	<header>Header...</header>
`;

// Insert your footer HTML inside these ``. You can use HTML as usual. 
// You don't need to use the <footer> element, but I recommend it.
const footerEl = `
	<footer>Footer...</footer>
`;


Step 2: Load the JS

Load that javascript file on every page.

Show me how
  • For your index file, or any other page that is not in a folder: <script src="layout.js"></script>
  • For any file that is in a folder: <script src="../layout.js"></script>
  • For files that are in a subfolder use ../../layout.js , and so on. (add another ../ for every subfolder)

This line should be inserted into the head of your HTML file (before before </head>). Alternatively, you can also put it right before </body>. It really doesn't matter.



Step 3: Paste your header/footer into the JavaScript file.

Paste your header and footer inbetween the ticks (``) of the variables headerEl and footerEl.

Use ${nesting} to output a . or .. or ../.. etc according to the current page's folder depth. This is helpful when you want to use relative paths to images.

Example:

const headerEl = `<img src="${nesting}/images/example.jpg" />`;

... will output:

  • <img src="./images/example.jpg" /> on a page that isn't in any folder
  • <img src="../images/example.jpg" /> on a page that is in a folder
  • <img src="../../images/example.jpg" /> on a page that is in a sub-folder.
  • etc.


Step 4: Prepare your pages.

Remove your header and footer from the html files of your pages - They will be added via JavaScript. Make sure all page content is in a wrapper, I suggest using <main> or <div>:

<body>
  <main>
    your page here...
  </main>
</body>

Step 5: Style

Now, style your layout with CSS like you would normally do.

My code adds the class "active" to any links that are linked to the current page. This makes it easy to style active menu links. Just make a CSS rule that checks for the "active" class,
e.g. .active { font-weight:bold; }



Done!

If you have page on which your layout should not be loaded, give the <body> element the "no-layout" class.