Search code examples
javascriptstatic-siteeleventy

custom dark mode in static site generator 11ty


I want to add a dark mode button to my statically generated site with eleventy. The code for dark mode is take from this site But I don't know where to put the js file/function. The button should be at the header, shared by all pages. So I put reference to js file in base layer template base-layout.njk, but it is not working. The button is there but when I click the page does not change.

This is my base-layout.njk:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
  <meta charset="utf-8"> 
  <meta name="viewport" content="width=device-width, initial-scale=1" /> 
  <title>Eleventy Blog</title> 
  <link rel="stylesheet" href="/css/site.css">
</head> 
<body> 
  <header>
    <a href="/" class="link--home">My Blog</a>
    <a href="/About">About</a>
    <button id="dark-button" onclick="darkToggle()">Dark Mode</button>
  </header> 
  <main> 
    {{ content | safe }}
  </main> 
  <footer>&copy; My Blog</footer>
</body> 
<script type="text/javascript" src="../global.js"></script>
</html>

Here is my directory structure

.
├── css
│   └── site.css
├── global.js
├── _includes
│   ├── base-layout.njk
│   └── post-layout.njk
├── index.njk
├── package.json
├── package-lock.json
├── posts
│   └── 2021-0520.md
├── README.md
└── _site
    ├── css
    │   └── site.css
    ├── index.html
    ├── posts
    │   └── 2021-0520
    │       └── index.html
    └── README
        └── index.html

8 directories, 13 files

Solution

  • First, you need to include the JS file in your eleventy build so it ends up in the output directory. If you deploy your site, only the output directory will be accessible over the web, so accessing the source file directly won't work. Then you need to adjust the path in your <script> tag to make sure it matches the output location of the JS file.

    // .eleventy.js
    
    // copy the JS file to the output directory in the build step
    eleventyConfig.addPassthroughCopy('global.js');
    

    With this config, the JS file will end up in your output directory. Now adjust the script tag to use an absolute URL:

    <script type="text/javascript" src="/global.js"></script>
    

    You can read more on how to use passthroughFileCopy in Eleventy here and more on why you need to do this as well as the difference between build time and client-side JavaScript here.