Enabling and Using SVG in WordPress


Recently I’ve had a lot of issues with displaying a client’s rather intricate logo correctly at a small enough size to fit into a sticky navigation bar on their WordPress site. I tried everything. PNGs with transparency and PNGs without transparency (just in case that was a factor). I tried PNGs from 72ppi to 300ppi. I even had the client’s graphic designer who originally designed the logo to redesign a version just for that size! Still the logo looked blurred, pixellated and lost important detail. Eventually I resigned myself to the idea that “it’s as good as it’s going to be” and moved onto other tasks.

The client wasn’t too happy, and neither was I. I don’t like saying things like “that’s as good as I can get it to look” or words to that effect. They’re excuses. Even when it’s a known browser rendering issue (like the Mozilla “pixel pop” when using CSS transition hover effects on images). So, when I read a CSS-Tricks article on Using SVG, I decided to give that a try. Browser support for using SVG as an img is across the board as of writing this (according to Can I Use) so I sat down and gave it a shot.

If you’ve tried simply uploading an SVG to WordPress through the Media Uploader, you may have had a few issues. Either it gave you an error and wouldn’t let you upload the file or it allowed you to upload the .svg file but just wouldn’t display it. Either way, here’s two simple steps for enabling SVG images in WordPress easily.

Note: You’ll need to be able to edit your theme’s (or child theme’s) functions.php file and the root .htaccess file for this to work.

Add SVG MIME Types to functions.php

Open up your functions.php and add the following code:

 * Add SVG capabilities
function wpcontent_svg_mime_type( $mimes = array() ) {
  $mimes['svg']  = 'image/svg+xml';
  $mimes['svgz'] = 'image/svg+xml';
  return $mimes;
add_filter( 'upload_mimes', 'wpcontent_svg_mime_type' );

You should replace wpcontent_ with your own namespace. This function simply adds the SVG and SVGZ (compressed SVG) to the allowed upload file types in WordPress and hooks into the upload_mimes() WordPress function.

Add SVG Mime Types to .htaccess

After I’d done this, I spent a good half an hour trying to figure out why it still wasn’t showing up on the frontend. I could upload SVGs now just fine, but they wouldn’t show up. Using Firebug and Chrome’s Developer Tools, it seemed to just fail to load the file URL. After some searching, I found an unrelated article about needing to add the SVG MIME type to the .htaccess file on certain server environments. And that’s exactly what the problem was.

So, open your root .htaccess file and add the following after the line, #End WordPress.

# Add SVG Mime Types
AddType image/svg+xml svg
AddType image/svg+xml svgz

Save the file and you’re done! You can now save SVGs from Illustrator or Inkscape and use them on your WordPress site.

But… (There’s Always a But!)

There’s actually quite a large but: Security. SVG is disabled in WordPress by default for a reason. I thought it was simply disabled because support wasn’t 100% but once I started searching for how to turn it on, I kept seeing the same stark warnings on every post.

Why Is SVG a Security Risk?

So, why is SVG a security concern? In short: because SVG is wrapped in XML. SVG isn’t the problem, XML is the problem. XML has many exploitable traits that can allow an attacker to either crash your server with DDoS (Distributed Denial of Service) and DOS (Denial of Service) attacks, or even view open and save files from the server which shouldn’t be accessible. I’m not talking your PHP files within WordPress either, I’m talking folders outside of your root on the server such as etc which can hold password files and other sensitive files. Such attacks are called XML External Entity Attacks.

Also, because XML is like HTML in that it can be used to attach and link to external scripts such as JavaScript and Flash, it can be used to run scripts on your server that might not be on your server. Doing this allows an attacker to use persistent or DOM-based XSS (Cross-Site Scripting) attacks.

Another type of attack is an XML Bomb attack. These are used for DDoS and DoS attacks. A “popular” type of XML Bomb attack is the “Billion Laughs” attack. This is where XMLs nesting traits are exploited to create an exponential loop of nested attributes and entities to run, turning a few kilobytes of markup into dozens of gigabytes of RAM usage trying to parse the file. Basically, this is the equivalent of a server having a cardiac arrest.

Scary Vector Graphics

I’ve scared you now, haven’t I? Let’s take a step back. SVG is a good thing. Especially in this responsive, retina-ready world wide web we find ourselves immersed in every day. If your WordPress site (or any site for that matter) is maintained solely by you or a trusted team of editors, authors and contributors, then unlocking and using SVG on your WordPress website is probably fine. If, however, your site is open to the public to upload media and images, then having SVG uploads allowed is going to be a huge security risk. All I ask is that you make an informed decision.

This post was written by Luke Watts. We are very grateful that Luke has written this post for us, however, the views expressed here belong to the author, and do not necessarily reflect the views and opinions of wpContent.

About Author

Founder and Lead Developer at Affinity4.ie, a web development agency in Galway, Ireland. Develops mosty with WordPress, Laravel, PHP, MySQL, Git, Github, Sass and Compass.

Leave A Reply

  • http://www.anythinggraphic.net Kevin Donnigan

    Thanks for this :-) Very helpful for a huge website I’m working on!

    • http://www.samberson.com Sam Berson

      Hey Kevin! Glad you’ve found this post useful :)

  • Edward

    Excellent! Thank you!

  • https://www.youtube.com/c/umikizatoichi Umiki Zatoichi

    Thanks man

  • http://www.smallbizgeek.co.uk SmallBizGeek

    Thanks for the tips. SVG is a much file size than PNG, but tell me, how do you control the size of the SVG? CSS font-size?

    • http://luke-watts.com/ Luke Watts

      Think of them exactly as you would images. So you would either give them the required height or width and set the other dimension to auto. For example:

      svg {
      width: 100%;
      height: auto;

      The SVG also has to have the for them to be responsive in browsers.

  • Todo Pertin

    Thank you so much. :)

  • gs3n

    Hi, thanks for the tip. Anyway, I cannot use the namespace. I know it should be a string into the functions.php file, but into my parent’s theme folder, the functions.php file doesn’t have the namespace code.
    I tried to add it at the very top of the child theme’s functions.php file, but it returns an error.
    Could you please help?


    • http://luke-watts.com/ Luke Watts

      If you have a child theme installed (which I highly recommend) you should place the function(s) from the above article in the functions.php file of the child theme. Otherwise you can place them in you main/parent themes functions.php file but any updates to that theme will overwrite them.

      You can change “wpcontent_svg_mime_type” to anything you want. Just don’t forget to change the second parameter of the “add_filter” also.

      Hope that helps :)

      • gs3n

        Thanks for your prompt reply.

        So something like the following should work?

        * Add SVG capabilities
        function lyskamm_svg_mime_type( $mimes = array() ) {
        $mimes[‘svg’] = ‘image/svg+xml’;
        $mimes[‘svgz’] = ‘image/svg+xml’;
        return $mimes;

        add_filter( ‘upload_mimes’, ‘lyskamm_svg_mime_type’ );

        …noting no space after first “lyskamm_svg_mime_type”, and a space after the parenthesis, correct?

        • http://luke-watts.com/ Luke Watts

          That should work fine!

          If you’re feeling hip and modern, depending on your version of PHP (if you have PHP5.5+) you can also use an anonymous function with the new array syntax. It’s much cleaner and removes the need for coming up with function names:

          add_filter( ‘upload_mimes’, function ( $mimes = [] ) {
          $mimes[‘svg’] = ‘image/svg+xml’;
          $mimes[‘svgz’] = ‘image/svg+xml’;
          return $mimes;
          } );

          Note there is a space between “function” and “( $mimes = [] )”, however having no space won’t cause any errors.

          • gs3n

            Great, thanks. I’m going to try ASAP.

          • http://luke-watts.com/ Luke Watts

            Any problems just drop me another comment. I’m happy to help :)

          • gs3n

            Thanks again. Now it seems to work well, I can see the svg icon into the page, but I cannot see the image in the media browser. Is it normal?

          • http://luke-watts.com/ Luke Watts

            As long as you can see it on the actual website (as in the front end) I wouldn’t worry too much. The WordPress Media Uploader isn’t setup to display SVG by default seeing as it’s turned off by default.

            If you can upload SVG then you should be fine. If you still can;t see the SVG when you view the page then you’ll need to add the mime types to the .htaccess file also. In which case you’ll need FTP access or a plugin which allows for editing the .htacces file

          • gs3n

            The .htaccess file should be ok. My last concern is about the size. I just uploaded the client’s logo and it’s 1.4 Mb.
            Will it be too heavy or the code is automatically optimised?

          • http://luke-watts.com/ Luke Watts

            That does seem a bit big. SVG should be pretty small. like a few kbs. If you’re using Illustrator or Inkscape make sure you’re saving for web and using Optimized SVG. Sketch too. Turn of comments and anything that isn’t necessary when saving it. Play around with it. Remember you can keep the dimensions small too. It’s not like an image that needs to be 2000px to work on high res screens. Keep it small and let it scale up.

          • gs3n

            Ok thanks. It’s the very first time that I use sag files, so basically is like for bitmap images. I will follow your precious tips.

            Thanks again Luke.

  • http://jwak.website/ Jon Sellers

    Plugin! Use a plugin! Do not edit your core files manually unless absolutely positively %100 no other way, because you will loose your edits when your core is updated or you loose the update ability, security, and 90% of why you chose WP in the first place.

    There are dozens of svg Plugins, please use plugins whenever possible.

    The op function.php edit will only last until your first round of core updates, 3 months max, unless you disable updates and skip them altogether. Don’t do it.


    • http://www.smallbizgeek.co.uk SmallBizGeek

      This is why we use child themes buddy

      • kashmiri

        “child themes”??? what do themes have to do with function.php? you are confusing theme files, where using child themes is an option, with wordpress core files. (I know it’s an old thread, I am commenting just in case someone takes your “advice” seriously).

        • http://luke-watts.com/ Luke Watts

          Placing this code in a child theme’s functions.php is a perfectly valid solution if you’re only using it on one website. If you plan on using it for multiple sites, then yes, by all means put it in a plugin for reuse.

        • http://www.smallbizgeek.co.uk SmallBizGeek

          Jon Sellers doesn’t understand that functions.php in a child theme does not get wiped out when WP core updates. Therefore I stand by my original post and invite anyone reading this to indeed take my “advice” seriously.

          Edit: kashmiri, you don’t appear to understand how child themes work either.