ルカ-さん Luca-san

Improving Eleventy blog


Recently i decided to do some minor improvements over the Eleventy base blog that i am using here to give it a nicer feeling.

Table of Contents

Improvements

Add a little blog icon

One day i thought about adding a little icon next to the blog name on the top bar (where you now see "Luca-san" at left in the bar. Just thought might be nice, so after i decided an image to use for it, i was playing with the code to find how to actually place there.

Eventually i added this code in the base.njk file in _includes\layouts, just after the <header> tag in the body and before the name of the blog, which is the variable metadata.title:

<a href="/" class="home-link"><div style="display: flex; align-items: center;"><img eleventy:widths="30,30" src="/IMAGENAME.png" alt="IMAGEALT" style="margin-right: 5px;"> Luca-san</a>

The result is what you see on top: blog icon

Favicon

Another thing i wanted was to add a favicon, a small graphic improvement but nice nevertheless. This is trivial to do. There are several ways to do it but chances are that you want to keep it simple, and for that you might need to use what is called Passthrough File Copy in Eleventy.

Fortunately the base blog configuration file eleventy.config.js is already configured to use it:

// Copy the contents of the `public` folder to the output folder
	// For example, `./public/css/` ends up in `_site/css/`
	eleventyConfig
		.addPassthroughCopy({
			"./public/": "/"
		})
		.addPassthroughCopy("./content/feed/pretty-atom-feed.xsl");

In short, all this does is copying the content of your public folder to the root of your website (output), which in Eleventy is _site. All you need to do is copy your favicon.ico file in the public folder, and that will work. Simple as that.

I use the same method to add a redirect in Cloudflare, which is where i'm hosting this blog.

Light/dark theme switcher

Next i wanted to implement both a light and dark theme for readability. Personally i normally keep the light mode, unless it's really night, as i find it more comfortable. You might not know but dark mode is actually bad for your eyes, especially for those with certain eye conditions, such as astigmatism. Some sources so you don't have to trust me:

and so on. I especially hate when the dark mode is forced with no way to change it (random example, Google Chronicle) so i thought for my blog to implement both to leave the choice up to the few readers i will have.

Enough with the intro, here's how to implement the very basic switcher you see on this blog. Full disclaimer, i took the code shown in this blog post https://traveling-coderman.net/code/light-mode/ and adjusted it to my needes. I'm no developer and wanna give the author the credits for that.

I wanted something similar because it only use CSS and little JS; no plugins, no external dependencies. The original code include Font Awesome icons but i removed this dependency as well (as mentioned in the blog) hosting the icon myself.

  1. As a first step create a file in your folder _includes named theme-switch.css containing the following code. This is a slight variation from the blog above:
:root.light {
	--color-gray-20: #e0e0e0;
	--color-gray-50: #C0C0C0;
	--color-gray-90: #333;

	--background-color: #fff;

	--text-color: var(--color-gray-90);
	--text-color-link: #082840;
	--text-color-link-active: #5f2b48;
	--text-color-link-visited: #17050F;

	--syntax-tab-size: 2;
}

:root:not(.light) {
		--color-gray-20: #e0e0e0;
		--color-gray-50: #C0C0C0;
		--color-gray-90: #dad8d8;

		/* --text-color is assigned to --color-gray-_ above */
		--text-color-link: #1493fb;
		--text-color-link-active: #6969f7;
		--text-color-link-visited: #a6a6f8;

		--background-color: #15202b;
}

.theme-icon {
  width: 2rem;
  height: 2rem;
  background-size: contain;
  background-repeat: no-repeat;
  border: none;
  background-color: var(--background-color);
  display: flex;
  justify-content: center;
  cursor: pointer;
}

:root.light .theme-icon {
    background-image: url('/img/sun.svg');
}

:root:not(.light) .theme-icon {
    background-image: url('/img/moon.svg');
}

.sr-only {
  height: 1px;
  width: 1px;
  overflow: hidden;
}
  1. Create another file in the same folder _includes, named theme-switch.js. This time the file is exactly the same as the one from the blog post:
function isLight() {
  return localStorage.getItem("light-mode");
}

function toggleRootClass() {
  document.querySelector(":root").classList.toggle("light");
}

function toggleLocalStorageItem() {
  if (isLight()) {
    localStorage.removeItem("light-mode");
  } else {
    localStorage.setItem("light-mode", "set");
  }
}

if (isLight()) {
  toggleRootClass();
}

document.querySelector(".theme-icon").addEventListener("click", () => {
  toggleLocalStorageItem();
  toggleRootClass();
});
  1. Last code edit. Go in _includes\layouts and edit your base.njk file to include the part that calls the 2 files you created above. To have the button in the position you see in this blog, i placed this block just before the </header> tag in the body:
<style>{% include "_includes/theme-switch.css" %}</style>

<button type="button" class="theme-icon">
  <span class="sr-only">Toggle between dark and light mode</span>
</button>

<script type="text/javascript">{% include "_includes/theme-switch.js" %}</script>
  1. The last thing you need to do to make this work, is to add your icons. As you see in the first file above, theme-switch.css, i placed them in /img/sun.svg and /img/moon.svg. Here is where you can find the moon and the sun i am using.

And that's it, i now have a simple yet nice theme switcher!