Building My Website - Adding color themes with JavaScript (Part 6)
💬 | How I built my personal website - Part 6 - Implementing theme switching with JavaScript, localStorage, and a clean data-theme approach. |
---|---|
📅 | |
⏱️ | 2 min read |
🏷️ | #development #web |
This article is part of a series about building my personal website:
- The idea and choosing the right tool
- SEO essentials: meta tags and base head element
- Content management with Markdown and Frontmatter
- Semantic HTML for accessibility and external readers
- Minimalist CSS: styling and native-like design
- Adding color themes with JavaScript
- Astro plugins: RSS, Sitemap, Word count
- SVG icons and Favicon
- Building resume with XeLaTeX
- Extras
Astro ships 0 JavaScript by default, which I love. For a simple website like mine, most things don’t require JavaScript at all.
But some interactions are only possible with it - like switching color themes dynamically.
Theme switching logic
I added a <select>
element where users can choose a theme.
Whenever they select a different option, the website should:
- Update the colors instantly.
- Save the choice so it persists across page reloads (my site is a multi-page app, so state isn’t preserved automatically).
Here’s the script I use:
const theme = localStorage.getItem("theme") ?? "system";
document.documentElement.dataset.theme = theme;
const selector = document.querySelector(
"select#theme-selector"
) as HTMLSelectElement | null;
if (selector !== null) {
selector.value = theme;
selector.addEventListener("change", () => {
const value = selector.value;
localStorage.setItem("theme", value);
document.documentElement.dataset.theme = value;
});
}
- On load, it checks localStorage for a saved theme.
- The
<html>
element gets a data-theme attribute (instead of a class, since it feels cleaner and supports multiple values). - When the user changes the selector, the new value is saved back to localStorage and applied immediately.
This way, the site remembers the theme until the user clears browser storage.
Bonus: a little easter egg 🌿
Just for fun, I added this line:
console.log("%c🌿", "font-size: 8em");
Open the browser console and you’ll see a giant leaf emoji printed out.