- Why WordPress blocks SVG uploads
- Allowing is not the same as sanitising
- Method 1: a sanitising plugin
- Method 2: the code snippet, and what it does not do
- Method 3: skip the media library entirely
- When the SVG uploads but displays wrong
- Preparing the file before you upload it
- When you should leave the block in place
- Frequently asked questions
SVG is the obvious format for a logo, an icon or a simple illustration on a WordPress site. It stays sharp at every size, it is usually a fraction of the weight of the PNG version, and it scales to any screen without WordPress needing to generate a stack of resized copies. So it surprises people that the platform running a huge share of the web refuses the format outright. Drag an SVG into the media library on a default install and the upload fails with a security message.
The refusal is not a bug and it is not your hosting company. It is WordPress applying a blunt precaution to a genuinely sharp edge. This guide explains the edge, then walks through the three realistic ways to get SVG onto a WordPress site, in the order you should consider them. It finishes with the rendering problems that appear after the upload finally works, because getting the file in is only half the job.
Why WordPress blocks SVG uploads
A JPG or PNG is a grid of pixels. Whatever is in the picture, the file itself cannot do anything. An SVG is different in kind: it is an XML document, a text file full of markup, as covered in what an SVG file is. That markup is mostly drawing instructions, but XML can also carry script blocks, event handlers, external references and embedded stylesheets. A file that looks like an innocent icon can execute JavaScript the moment a browser opens it directly.
That makes an unfiltered SVG upload a cross-site scripting vector, and it is why WordPress core has excluded the format from its allowed upload types for years and still does. Core has no sanitiser built in, so it cannot tell a clean icon from a booby-trapped one, and it takes the safe option of refusing both. The full mechanics of what can hide inside an SVG, and when it actually executes, are covered in the SVG security guide. The short version that matters here: the block protects you from other people's files far more than from your own.
Allowing is not the same as sanitising
Every method of enabling SVG in WordPress does one or both of two separate jobs, and keeping them separate in your head is the whole trick to choosing well. Allowing means adding image/svg+xml to the list of upload types WordPress accepts. It takes one filter and about four lines of code. Sanitising means parsing each uploaded file and stripping scripts, event handlers and other active content before it is stored. That is the part that takes real work, which is why the quick fixes you find in forum answers almost never do it.
A solution that only allows leaves the security hole exactly as wide as it was; it just opens the door through it. A solution that sanitises closes most of the hole for everyday use. Which one you need depends on who uploads to your site, and that single question decides everything below.
Method 1: a sanitising plugin
For nearly every site, the right answer is a plugin that does both jobs, and the sensible default is Safe SVG. It has been the standard for years, sits on over a million active installations, and is actively maintained. Install and activate it and SVG uploads simply start working, with each file run through a sanitiser on the way in.
What you get beyond the basic unlock:
- Sanitisation on every upload. Scripts, event handlers and other executable content are stripped before the file touches your media library, and a file the sanitiser cannot process is refused rather than waved through.
- Media library previews. Without help, WordPress shows uploaded SVGs as blank tiles, which turns finding the right icon into guesswork. The plugin renders proper thumbnails in every view.
- Role restrictions. You can limit SVG uploads to administrators or other chosen roles, which is worth doing on any site with more than one author.
- Optional optimisation. It can pass files through SVGO on upload if you switch the feature on with a one-line filter, though it is off by default. If you already optimise your SVGs before upload, which is the better habit, you will not need it.
SVG Support is the other plugin you will see recommended, with a similarly large install base and a useful option to render uploaded SVGs inline so CSS can reach inside them. It is a reasonable choice too. The deciding factor is not features, it is that whichever plugin you pick must sanitise, and both of these do. A plugin whose description only promises to "enable SVG uploads" with no mention of sanitising belongs in the same category as the snippet below, whatever its install count says.
One habit worth keeping even with a sanitiser in place: treat plugin sanitisation as the second line of defence, not the first. Sanitisers are good and they keep improving, but bypasses do get found and patched. Files you drew yourself or exported from your own design tool are low risk. A file that arrived by email from someone you have never worked with deserves a look before it goes anywhere near your site.
Method 2: the code snippet, and what it does not do
The no-plugin route is a filter in your child theme's functions.php or a code snippets tool:
function ioop_allow_svg( $mimes ) {
if ( current_user_can( 'administrator' ) ) {
$mimes['svg'] = 'image/svg+xml';
}
return $mimes;
}
add_filter( 'upload_mimes', 'ioop_allow_svg' );
The capability check matters: without it, every user who can upload media can now upload SVG, which is precisely the situation the core block exists to prevent. Keep the restriction to administrators unless you have a documented reason to widen it.
Now the honest part. This snippet allows and does nothing else. No sanitising, no previews, no safety net. It is the right tool in exactly one situation: a site where you are the only person who uploads, and every SVG is a file you made or exported yourself. The moment client staff, contributors or inherited media libraries enter the picture, the snippet is the wrong tool and the plugin is the right one. The few kilobytes a plugin adds are not worth an XSS hole.
Two follow-on problems to expect. First, some hosts and setups still reject the upload after the filter is added, because WordPress checks the actual file contents against the claimed type and SVG can fail that stricter comparison; this is the point at which people pile on further filters and the correct response is to stop and install the plugin instead. Second, you will meet advice to define ALLOW_UNFILTERED_UPLOADS in wp-config.php. Do not. That constant switches off file-type checking across the board for privileged users, which is a far bigger change than letting a logo through, and it is the kind of setting that outlives the person who added it.
Method 3: skip the media library entirely
Here is the reframe that dissolves the problem for a lot of cases: the media library is not the only way to get an SVG onto a page, and for icons it is usually the worst way. An SVG dropped into a Custom HTML block, a theme template or your header is just markup. No upload happens, so no upload block applies, and you get the one thing an SVG in an img tag can never give you: CSS can reach inside it.
Inline SVG icons inherit text colour through currentColor, restyle on hover, and flip automatically in dark mode, all without a second file. The trade-offs between inline, img and the other embedding routes are covered properly in how to use SVG icons in HTML, and the colour mechanics in changing icon colour. If what you need is a set of clean UI icons rather than your own artwork, you can search the icon library, set the colour and stroke, and copy ready-to-paste inline SVG straight into a block.
The sensible split on a typical WordPress site: interface icons and decorative flourishes go inline in the theme or in blocks, while the logo and content illustrations, the things editors need to place and reuse, go through the media library once uploads are safely enabled. You need method 1 or 2 for the second group only.
When the SVG uploads but displays wrong
Enabling uploads is where most guides stop, and it is where the second wave of problems starts. The recurring ones:
| Symptom | Cause and fix |
|---|---|
| Renders tiny, enormous or invisible | The file has no viewBox, or hard-coded width and height fighting your CSS. Fix the file: add a viewBox matching the artwork, remove fixed dimensions, size it from the block or stylesheet. The viewBox guide shows exactly how. |
| Blank square in the media library | WordPress does not thumbnail SVGs on its own. A sanitising plugin adds previews; the snippet route leaves them blank. |
| No size options when inserting | Normal. WordPress generates no resized copies or srcset for SVG because one file already scales to every size. Set display size on the block. |
| Looks different on the live page than in preview | Usually theme CSS setting a max-width or height on images. Inspect the rendered element rather than re-exporting the file repeatedly. |
| Colours or details missing after upload | The sanitiser stripped something it considered unsafe, often embedded CSS or external references. Re-export the file with plain presentation attributes instead of a style block. |
One more that is invisible until an audit: alt text. An SVG placed through an image block still needs a text alternative like any other image, and decorative ones should be explicitly empty. The rules are the same as for any icon, covered in accessible icons.
Preparing the file before you upload it
The best time to fix an SVG is before it enters WordPress, because the media library is where messy files go to be duplicated forever. Three habits cover it. Export clean: a proper vector drawn in a design tool, not a photograph pushed through a tracer, which produces exactly the bloated multi-megabyte files described in the PNG to SVG guide. Optimise it: strip editor metadata and cut decimal precision so a typical icon or logo lands in single-digit kilobytes. Sanity-check it: open the file in a browser tab on its own and confirm it scales when you resize the window, which catches viewBox problems before they become support tickets.
Files from this site need none of the first two steps; everything exported here is plain path data and presentation attributes with no scripts and no external references, which also means a sanitiser has nothing to strip out of them.
When you should leave the block in place
There are sites where the correct amount of SVG upload support is none. If your site accepts files from people you do not control, through open registration, contributor accounts, front-end submission forms, or marketplace listings, then every uploader is a potential attacker and sanitisation becomes your single point of failure. Large platforms that must accept user SVGs do not rely on a sanitiser alone; they serve uploaded files from a separate origin so a malicious file cannot touch the main site, a pattern explained at the end of the SVG security guide. If you cannot do that, keep the block for untrusted roles and let trusted admins upload through a sanitising plugin. WordPress made the paranoid choice for you; only relax it as far as your actual situation justifies.
Frequently asked questions
Handling SVGs from people you do not fully trust? Read SVG security before you loosen anything, because the upload block exists for exactly that situation.
Files coming out of your design tool heavier than they should be? Optimising SVG files shows what to strip before anything reaches your media library.