WordPress allows .jpg, .png, .gif, .webp, and a few others. It blocks SVG. Most tutorials online treat this as an oversight and hand you a snippet to bypass it. That is wrong. WordPress blocks SVG for a real security reason, and you should know what it is before you switch it on.

Diagram showing the anatomy of an SVG with vector path, anchor points, and viewBox.

Why WordPress blocks SVG

SVG is XML, not pixels. An SVG file can contain <script> tags, onload="..." attributes, and links to external resources. Render a malicious SVG in a browser and you have a stored XSS vulnerability sitting in your media library. That is why core says no. 😶

The one-line snippet (use carefully)

If your site has only trusted users uploading files (you and your team), the snippet below is enough. Drop it in your theme’s functions.php or a site-specific plugin:

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

That is it. SVG uploads now work. Note the MIME type: image/svg+xml, not image/svg as some older tutorials say.

If untrusted users can upload

If your site has authors, contributors, customers, or anyone you would not personally vouch for, the snippet above is unsafe. You need sanitization on upload. The two clean options:

  • Safe SVG by Daryll Doyle. Free, well-maintained, strips dangerous SVG content on upload. Install it and SVG uploads just work for any user role you allow.
  • Roll your own. Hook into wp_handle_upload_prefilter and run the file through enshrined/svg-sanitizer. Use this only if Safe SVG does not fit your stack.

Why bother with SVG at all

SVG files are tiny (often under 5 KB for a complex logo), scale to any size without losing quality, and look razor-sharp on retina screens. For logos, icons, and any flat illustration, SVG is the obvious choice and PNG/WebP are a compromise. The security cost is real, the security fix is one plugin away. Worth it.