Aljosha Gasser.

How to add a SVG favicon to your website – with dark mode support

For me adding a nice favicon to a website is part of the finishing touches to a project. And while it’s certainly not priority number one, there’s something satisfying about looking at a website in dark mode, with a nice favicon looking good in dark and light mode.

I recently updated my own website and had to look up a thing or two about how to add an SVG favicon, supporting both dark and light mode. I thought it might be useful for someone else, looking for a solution to the same problem.

Create an SVG icon

Start by creating a square SVG icon. Here’s an example of the one I used for my own website:

<svg xmlns="<http://www.w3.org/2000/svg>" width="512" height="512" viewBox="0 0 512 512">
  <g>
    <rect x="-0" y="0" width="512" height="512" style="fill:#6366f1;"/>
    <path d="..." style="fill:#ffffff;" />
  </g>
</svg>

Now of course we don’t need to overcomplicate things. A simple solution to the problem we’re trying to solve here might be to just use an SVG with a background color.

That’s exactly what I did for my own website. I went with the primary theme color for the background, with white text on top of it. Of course, you need to make sure to use a high enough contrast for both dark and light mode.

This is how it looks right now:

However, if you still need to prefer using two favicon versions for dark and light mode, I suggest the following option.

Using media query to change SVG colors

There are two options for how to make use of the media query to set the color of your SVG favicon.

The first option is to use inline CSS and @media (prefers-color-scheme: dark) to style the dark mode version of your SVG favicon. Make sure to remove any stylings (the fill and stroke attributes) from the shapes in the SVG you want to change the color of and add them as inline CSS instead, like this:

<svg xmlns="<http://www.w3.org/2000/svg>" width="512" height="512" viewBox="0 0 512 512">
  <style>
    rect {
      fill: #6366f1;
    }
    
    @media (prefers-color-scheme: dark) {
      rect {
        fill: #f43f5e;
      }
    }
	</style>
  <g>
    <rect x="-0" y="0" width="512" height="512" />
    <path d="..." style="fill:#ffffff;" />
  </g>
</svg>

The second option is to create two different versions of your SVG favicon (one for dark and one for light mode) and let your browser know which one to use for dark mode directly in the HTML <link> tag, like this:

<link rel="icon" href="/assets/images/favicon.svg">
<link rel="icon" href="/assets/images/favicon-dark.svg" media="(prefers-color-scheme: dark)">

I personally prefer the first option, using inline styles and eliminating the need for two different SVGs.

And this is what it looks like now in the browser:

Creating a fallback version for old browsers

I prefer using an SVG favicon for my websites because it’s easy to change and I don’t have to think about dimensions and size. And I can easily add inline CSS, using the <style> tag to add separate styles for dark mode, as shown in the previous example.

The problem is SVG favicons are still not 100% supported by all browsers, meaning that we’ll have to provide a fallback version.

Without going into too much detail about browser support, I simply suggest creating a PNG version for your favicon, and adding it to your website like this:

<link rel="icon" href="/assets/images/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/assets/images/favicon.png" type="image/png">

Add SVG favicon to your WordPress theme

If you’re not using WordPress for your website(s), you can skip the last part.

I added my SVG favicon to my theme’s asset directory /assets/images/favicon.svg but you can of course add it wherever you like.

I then simply added the two lines (the SVG itself and the PNG fallback) as shown above to my header.php file.

<link rel="icon" href="<?php echo get_stylesheet_directory_uri(); ?>/assets/images/favicon.svg" type="image/svg+xml">
<link rel="icon" href="<?php echo get_stylesheet_directory_uri(); ?>/assets/images/favicon.png" type="image/png">

Again, no need to overcomplicate things.

If you want, you can use your functions.php instead to insert the favicon links in your <head> section, using the wp_head action hook:

function your_theme_favicon() {
  echo '<link rel="icon" href="' . get_stylesheet_directory_uri() . '/assets/images/favicon.svg" type="image/svg+xml">'
  echo '<link rel="icon" href="' . get_stylesheet_directory_uri() . '/assets/images/favicon.png" type="image/png+xml">'
}
add_action( 'wp_head', 'your_theme_favicon', 100 );

And that’s it. I hope this article was useful to you!


Want to learn how to build a successful freelance career?

Once a week you'll get a new article with stories, ideas and practical advice on working for yourself, making a living from your creativity and leading a fulfilled life.

    Aljosha Gasser

    I respect your privacy. No spam. No bullshit. Unsubscribe at any time. See you around!