Extend Jetpack’s SVG Icons

Jetpack for WordPress comes with a great social menu feature and a fair amount of supported social icons—use WordPress’s menu editor to create so-called social menu and link to your Twitter profile, and a perfectly crisp, scalable Twitter icon will be shown, rather than a plain text link.

Update: I’ve since created Add Fediverse Icons to Jetpack, a WordPress plugin (available at the official WordPress.org repository) that adds below icons, and a couple more. So, if you’d rather not mess with PHP or (child) theme files, you can now simply install the plugin via WP Admin > Plugins > Add New.

But what if you wanted to add links to your Mastodon or Pixelfed profiles—platforms not currently supported—and not have them accompanied by an ugly, generic anchor icon? In other words: how do we get from the first image below to the second one?

Screenshot of our example social menu before the changes
The ‘before’ shot.
Screenshot of our example social menu after the changes
And the end result.

Well, Jetpack hooks into WordPress’s menu walker—essentially, a function that walks through the nav menu tree and spits out the necessary HTML—to work its magic, and we can do exactly the same.

/**
 * Applies extra SVG icons to social menu links.
 */
add_filter( 'walker_nav_menu_start_el', function( $item_output, $item, $depth, $args ) {
  // Our own, additional icons.
  $social_icons = array(
    'mastodon.social' => 'mastodon', // Modify according to your instance.
    'pixelfed.social' => 'pixelfed', // Modify according to your instance.
  );

  // If the URL in `$item_output` matches any of the sites above, apply the SVG icon.
  if ( 'jetpack-social-menu' === $args->theme_location ) {
    foreach ( $social_icons as $attr => $value ) {
      if ( false !== strpos( $item_output, $attr ) ) {
        $item_output = str_replace( $args->link_after, '</span>' . jetpack_social_menu_get_svg( array( 'icon' => esc_attr( $value ) ) ), $item_output );
      }
    }
  }

  // Always return `$item_output`.
  return $item_output;
}, 100, 4 );

Important: above function, and the ones below, all go into our child theme’s functions.php.

Now of course, we also have to somehow define the icons themselves. So I headed over to the Fork Awesome repository, grabbed the SVGs I needed, opened them up in Inkscape and resized them down to 24 by 24 pixels.

Actually, I sized the Pixelfed icon down to 20 by 20 pixels, giving it a 2 pixel overall padding, and resized the Mastodon icon to exactly 21 pixels in height, leaving 2 pixels above and 1 below the image, and a bit over 2 pixels on either side. I then ran both icons through Jake Archibald’s SVG optimizer, and copied the results into a file I named new-icons.svg. The result?

<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <symbol id="icon-mastodon" viewBox="0 0 24 24">
      <path d="M21.377 14.59c-.288 1.48-2.579 3.102-5.21 3.416-1.372.164-2.723.314-4.163.248-2.356-.108-4.215-.562-4.215-.562 0 .23.014.448.042.652.306 2.325 2.306 2.464 4.2 2.529 1.91.065 3.612-.471 3.612-.471l.079 1.728s-1.337.718-3.718.85c-1.314.072-2.944-.033-4.844-.536-4.119-1.09-4.824-5.481-4.935-9.936-.033-1.323-.013-2.57-.013-3.613 0-4.556 2.985-5.891 2.985-5.891C6.702 2.313 9.284 2.022 11.969 2h.066c2.685.022 5.269.313 6.774 1.004 0 0 2.984 1.335 2.984 5.89 0 0 .038 3.362-.416 5.695zm-3.104-5.342c0-1.127-.277-2.032-.864-2.686-.594-.663-1.373-1.002-2.34-1.002-1.118 0-1.965.43-2.525 1.29L12 7.761l-.544-.913c-.56-.86-1.407-1.29-2.525-1.29-.967 0-1.746.34-2.34 1.003-.577.663-.864 1.559-.864 2.686v5.516h2.186V9.41c0-1.128.474-1.701 1.424-1.701 1.05 0 1.577.68 1.577 2.023v2.93h2.172v-2.93c0-1.344.527-2.023 1.577-2.023.95 0 1.424.573 1.424 1.701v5.354h2.186V9.248z"/>
    </symbol>
    <symbol id="icon-pixelfed" viewBox="0 0 24 24">
      <path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-.794-7.817h1.835c1.728 0 3.129-1.364 3.129-3.046 0-1.682-1.401-3.046-3.13-3.046h-2.647c-.997 0-1.805.787-1.805 1.757v6.84z" fill-rule="evenodd"/>
    </symbol>
  </defs>
</svg>

Yep, that’s both our icons, in SVG format.

With new-icons.svg living in our child theme’s assets/svg subfolder, we can add its contents—out of sight, mind you—to our footer, so they’re ready to be picked up by any menu that requires ’em:

/**
 * Outputs our own social menu icons so they can be used anywhere on the page.
 */
add_action( 'wp_footer', function() {
  $custom_icons = dirname( __FILE__ ) . '/assets/svg/new-icons.svg';

  if ( file_exists( $custom_icons ) ) {
    require_once $custom_icons;
  }
}, 10000 );