Add support for inline SVG
Open, Needs TriagePublicFeature

Description

Feature summary:
SVG, or at least some degree of HTML graphics, should be directly supported in wikitext. For example, Inside of having to use a thumbnail for a pre-made image of an SVG circle, it should be possible to directly insert the circle into wikitext, like so:

This is a circle

<svg aria-labelledby="The following is a black circle">
<circle cx = "50" cy = "25" r="50/>
</svg>

This is consistent with wikitext support for inline HTML and CSS, and would be primarily useful in templates and modules, as will be discussed below.

Use case(s)

Many vector graphics, such as https://commons.wikimedia.org/wiki/File:44th_Canadian_Parliament.svg and https://commons.wikimedia.org/wiki/File:Eleventh_Jatiya_Sangsad.svg, would be best off templatized in some form, rather than having to create and upload images from scratch.

The main problem an attempted templatization currently runs into is the fact that it could only output raw SVG, which is not currently supported. As such, in order to create such diagams or maps, one would have to use a text editor or Inkscape to either create a fresh graphic or recolor a previously-uploaded graphic, and upload it fresh to Commons, and then link it from Commons. With a template (and, by extension, inline SVG), one could cut out such a middleman and make the maps directly in the source material, similar to what is already done on enwiki with Template:Graph:Chart.

Benefits:
As largely described above, this would save users much work in having to create raw maps of niche subjects and "polluting" Commons with such maps; it would also, much like Graphs do currently, save users from a thumbnail and allow for direct insertion of graphics into prose.

I am aware the power this gives people might be too great and am fine with reasonable nerfing, perhaps by not allowing other namespaces such as xlink. Also, viewboxes would have to be sorted. I do, however, believe that the benefits greatly outweigh the costs and am slightly surprised that this does not already exist in some form.

See also:
https://www.mediawiki.org/wiki/Inline_SVG_use

Implementation

This implementation allows SVGs to be generated by modules and templates, enabling the templatization of SVGs and supporting use cases like graphs, charts, and timelines.

Note that an SVG will still be a vector image, but primarily a static one. This means JavaScript interactions will not work. This is by design, for security reasons. Internal CSS will work so some movement is possible.

Enable with $wgEmbeddedSvg

New option to enable SVG embedded in wikitext: $wgEmbeddedSvg:

  • default: false
  • description: Allow adding embedded SVG in <svg>...</svg> tags rendered as an inline <img> tag. This is safe, as any inline SVG is secure by default. Browsers do not allow interactivity in <img> tags per HTML specification.
  • Enabling embedded SVG: $wgEmbeddedSvg=true.

Minimal SVG

<svg viewbox="-5 -5 10 10" width="100" height="100">
    <circle r="5" />
</svg>

Default rendering
SVG is then rendered as img tag for HTML like this:

<img class="mw-svg-parsed" width="100" height="100" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSItNSAtNSAxMCAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxjaXJjbGUgcj0iNSIgLz4KPC9zdmc+">

Where data-uri is an SVG image. This is done for security reasons (you cannot run JavaScript in this context, in img tag; see: SVG as image on w3.org).

Empty SVG
On a rare occasion when SVG tag in wikitext is empty the rendering is:

<img class="mw-svg-empty" src="" alt="">

Custom class
You can add custom classes with img-class attribute.

<svg width="34" height="34" viewBox="0 0 48 48" class="spinner" img-class="spinner-tpl">
  <defs>
    <style type="text/css"><![CDATA[
.spinner {
  animation: spin var(--spinner-animation-speed) linear infinite;
}
/* ... other styles ... */
    ]]></style>
  </defs>
    <g>
      <circle cx="24" cy="24" r="22" fill="transparent" stroke="url(#gradientFade)" stroke-width="4" />
    </g>
</svg>

Rendered:

<img width="34" height="34" src="data:image/svg+xml;base64,..." class="spinner-tpl">

Testing

  1. https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1043323 -- Current patch.
  2. https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1141966 -- Enable SVG (sets $wgEmbeddedSvg=true). Only for testing only (like creating a PatchDemo).

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Change #1043223 had a related patch set uploaded (by Eccenux; author: Eccenux):

[mediawiki/core@master] PoC: Embeded to inline SVG

https://gerrit.wikimedia.org/r/1043223

Change #1043217 abandoned by Eccenux:

[mediawiki/core@master] PoC: Embeded to inline SVG

Reason:

https://gerrit.wikimedia.org/r/1043217

Change #1043240 had a related patch set uploaded (by Eccenux; author: Eccenux):

[mediawiki/core@master] PoC: embedded to inline SVG

https://gerrit.wikimedia.org/r/1043240

Change #1043223 abandoned by Eccenux:

[mediawiki/core@master] PoC: Embeded to inline SVG

Reason:

Doesn't work

https://gerrit.wikimedia.org/r/1043223

Change #1043243 had a related patch set uploaded (by Eccenux; author: Eccenux):

[mediawiki/core@master] PoC: embedded to inline SVG

https://gerrit.wikimedia.org/r/1043243

Change #1043240 abandoned by Eccenux:

[mediawiki/core@master] PoC: embedded to inline SVG

Reason:

typo

https://gerrit.wikimedia.org/r/1043240

Sorry about the noise... 🙈 Finally got this right though. BTW. @SD0001 I think you have a typo in your rendering of attributes ;)

So this works (as a proof of concept at least):
https://patchdemo.wmflabs.org/wikis/0e24852599/wiki/Main_Page

What I didn't expect is that you can actually live edit SVG images out of the box in VisualEdit. When you, for example, change colors, you get a live preview of your changes. Pretty neat.

It should be safe out of the box, as img-src is designed to be secure. Browsers ensure that no scripts are executed.

There is one weird issue: the SVG disappears when not modified (you edit with VE; modify 1 of 2 SVG; check diff). So I guess some change in the VE configuration or something extra might be needed.
Embedded SVG editing in VisualEditor bug?

This still works great for me as a PoC. There are some things to work on still:

  • ✅Definitely should render width and height as the width and height of the img tag. Otherwise, you would have to scale elements of SVG, which is not ideal.
  • ✅Would need some unit tests, probably.
  • ✅Code cleanup.
  • ✅Need some decent error reporting or just remove the current debug... Not sure what's best route here.
  • ❌❔Should we add SVG in figure/figcaption tags? Maybe as an option? Or would we assume templates/modules will do that?
  • ❌⏱Figure out the VE problem mentioned above.
  • ❌Does this need a separate cache? Not sure. Doing base64 is most of the work there. Otherwise, it's just browser work.

But it should be usable even in its current form.

I would suggest making this an extension. I think this would be a very hard sell as a mw core feature. (Of course, being realistic, its still going to be a hard sell getting the extension deployed to WMF)

With Wikimedia deployment being the end goal, I suppose putting it in core behind a feature flag would cause less friction than a whole new extension?

It should be safe out of the box, as img-src is designed to be secure. Browsers ensure that no scripts are executed.

As for rasterized vs native load, should we honour the SVGNativeRendering option? It is disabled by default and in Wikimedia cluster for reasons I'm not sure about.

Change #1043323 had a related patch set uploaded (by Eccenux; author: Eccenux):

[mediawiki/core@master] PoC: embedded to inline SVG (clean)

https://gerrit.wikimedia.org/r/1043323

With Wikimedia deployment being the end goal, I suppose putting it in core behind a feature flag would cause less friction than a whole new extension?

I personally disagree, but i could be wrong. Just my 2 cents.

Change #1043243 abandoned by Eccenux:

[mediawiki/core@master] PoC: embedded to inline SVG

Reason:

https://gerrit.wikimedia.org/r/1043243

I think the PoC is cleaned up and ready to go.
https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1043323

SD0001 mentioned adding parser tests, but because base64 is involved, I'm not sure if that is something worth exploring. Both writing and reading such tests would be hard. Also, I don't feel comfortable writing parser tests in that text format. I don't really know if setting up articles in this tests is required or not. I don't know if I need to run Parsoid tests or if it is just nice to have, etc. Having said that, I did add unit tests, and I think all paths are covered by unit tests already. So now that unit tests are here, maybe parser tests are not needed?

It should be safe out of the box, as img-src is designed to be secure. Browsers ensure that no scripts are executed.

As for rasterized vs native load, should we honour the SVGNativeRendering option? It is disabled by default and in Wikimedia cluster for reasons I'm not sure about.

Good question. Reading the T208578 task, I get the impression that wgSVGNativeRendering and wgSVGNativeRenderingSizeLimit are designed for images used on Commons (for current problems with them). That means these options result from the fact that we already have a complex situation with many different SVGs. Different SVGs can have a lot of elements (tags, path points) and render slowly. Some SVGs on Commons also contain translations. So, a full switch to SVG is simply unrealistic there.

Here however, we have a significantly different situation, because the nested SVG in the article does not exist yet. So we have the opportunity to start fresh and avoid some mess with complex SVG. There is also no problem with translations through mechanisms rendered in PNG. So I think wgSVGNativeRendering does not apply here.

This is the last demo with SVG enabled by default:
https://patchdemo.wmflabs.org/wikis/604876b5e5/wiki/Main_Page

The SVG embedding feature will be blocked by the new option. As SD0001 suggested, this is done in a similar way to allowing raw <html>.

So new option is $wgEmbeddedSvg:

  • default: false
  • description: Allow adding embedded SVG in "<svg>...</svg>" tags rendered as an inline img tag. This is safe as any inline SVG is secure by default. Browsers do not allow interactivity in img tags per HTML specification.
  • Enabling embedded SVG: $wgEmbeddedSvg=true

Change #1043111 abandoned by SD0001:

[mediawiki/core@master] [WIP] Support for inline SVG in wikitext

Reason:

in favour of Ida4cc0f8f57d4a34b61460384c3902ed53b8d67e

https://gerrit.wikimedia.org/r/1043111

To demo the use case mentioned in the ticket - which is enabling templatization of SVGs, we can use some SVG-writing lua library. https://gitlab.com/hansonry/luasvgwriter is the one I found in 5 minutes of searching.

On patchdemo, setting it up as Module:SVGWriter, I created Module:Circle svg to produce circles of customisable colour. Example uses are shown on Templated SVG test.

As far as I can see it's impossible to have a lua module insert an svg snippet into a wiki article.

Of course it’s impossible right now – this is why task exists. https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1043323 will make it possible.

As an aside, I just realized you can do a surprising amount of drawing with just CSS. See https://en.wikipedia.org/wiki/Module:Sandbox/Bawolff/canvas for an example.

In principle I'm fine with <svg> as an extension tag. However, I disagree strongly with the "inline SVG is secure in browsers by default" which is the current POC patch. We absolutely need to run this through a appropriate sanitizer. We already have bugs like T381617 caused by mismatches between HTML and SVG semantics, and the POC patch should also use the 'isRawHTML' flag (7b1c8c45600596944bea6b2e200f3fae0a7ea3f0) to ensure that the result isn't subject to doBlockLevels, language conversion, etc.

I'm not sure why this has to be in core -- it seems like having an Extension:Svg would be a better way to (a) keep core compact, and (b) bundle this with an appropriate sanitization and rendering library, so that (eg) the image/png fallback was actually functional.

However, I disagree strongly with the "inline SVG is secure in browsers by default" which is the current POC patch.

It seems like people are using "inline svg" to mean an <img> tag with a src attribute that is a data url of an svg, which is not what people usually mean by "inline svg".

Personally im not aware of anything evil you can do in the <img> data: url context (at the absolute worse maybe you can make a really complex file that takes a lot of resources to render for a client side dos) as browsers disable external resources and scripting in that context.

FMHO both are great, but using pure svg file instead of png thumb will be much more useful, for me.

It seems like some people use "inline SVG" to refer to an <img> tag with an SVG data URL in the src attribute, but that's not the usual meaning of "inline SVG."

That’s a fair point – I’m not entirely sure what the best term for it is either. I do see how it could be misleading, so to clarify:

  • In MediaWiki, you can directly edit SVG code in the editor, meaning the SVG tags are technically seen "inline" within the MW code.
  • However, as you mentioned, the SVG is ultimately converted into an <img> tag with the SVG data inside the src attribute. This approach enhances security. More here: https://www.w3.org/wiki/SVG_Security#SVG_as_image

From a Wikipedia editor’s perspective, the SVG feels "inline" since it can be edited and manipulated directly (which enables cool features like templates and modules that SD added to patchdemo).
From a security standpoint, however, it’s treated as an image – similar to PNGs or GIFs.

Could you turn on VE on your patchdemo? I'd like to verify that Visual Editor does something sane here (it ought to, but you never know). I think VE ought to allow you to edit the SVG text directly in a popup, like it would for other extension tag content.

Could you turn on VE on your patchdemo? I'd like to verify that Visual Editor does something sane here (it ought to, but you never know). I think VE ought to allow you to edit the SVG text directly in a popup, like it would for other extension tag content.

Try https://patchdemo.wmcloud.org/wikis/32e7a844e0/wiki/Talk:Main_Page?veaction=edit.

It seems VE doesn't work in Minerva on current version and I did switch main user in previous to Minerva (hence probably why it might not have worked for cscott).

Anyway I've added a custom patch that now works on top of of whatever is in main patch. Hacky, but works ;). Should be easier to update PatchDemo now.

I principally highly support this. It should be possible to brew SVG:s by LUA modules. Either let the browser rend the SVG, or add the "missing link" from existing LUA interpreter to existing SVG rasterizer. The challenge is to design this in a decent way maximizing usefulness and minimizing maintainance nigtmare, abuse and nonsense, as well as and risk of sudden killing (see T334940). Also this should be limited to "commons" to prevent that a gazillion-SVG-mess located at commons only is repaced by a gazillion-templates-mess spread over hundreds of wikis (see T121470). While a solution to T121470 possibly is not expected soon, the "templatized SVG idea" ultimately must not become a part of that problem making it even harder to solve.

Thank you for your support. I did keep in mind the need to make this feature as secure as possible and opted for a sandboxed mode that, by design, doesn't run any kind of scripts (see: SVG as image security). So it should both be secure and future friendly (as browsers evolve).

As for Lua, I think we should be able to develop at least simple graphs generated by Lua as an alternative and addition to the more interactive graphs now being deployed by WMF. I know I will be re-writing my Pie chart module (live e.g. on enwiki) if and when embedded SVG is enabled.

Regarding the part about the globalisation of scripts: while it's still early to say what will be decided here, I hope that this will be available on all wikis. For now this is the only way. I also hope global or synchronised modules and templates will eventually become a reality. The synergy of solutions is sometimes lost on Wikipedia; I hope some of that can be regained in charts and, in the future, maybe through global modules and styles.

Added some examples and info to patch demo.

You should be able to use the VisualEditor on the main page. Sometimes VE removes SVG tags, but that seems like a VE or Parsoid bug. Haven't dug into that yet.

As an aside, I just realized you can do a surprising amount of drawing with just CSS. See https://en.wikipedia.org/wiki/Module:Sandbox/Bawolff/canvas for an example.

Please note using div+css to create charts (e.g. https://en.wikipedia.org/wiki/Template:Pie_chart) may be considered a hack instead of a proper solution - the "chart" is not a proper image you can download.

As an aside, I just realized you can do a surprising amount of drawing with just CSS. See https://en.wikipedia.org/wiki/Module:Sandbox/Bawolff/canvas for an example.

Please note using div+css to create charts (e.g. https://en.wikipedia.org/wiki/Template:Pie_chart) may be considered a hack instead of a proper solution - the "chart" is not a proper image you can download.

My thing was a hack in a lot of ways. That said, i'd point out you can't easily download extension:Charts charts either, and nobody seems concerned, so i don't know if downloading is really needed.

Please note using div+css to create charts (e.g. https://en.wikipedia.org/wiki/Template:Pie_chart) may be considered a hack instead of a proper solution - the "chart" is not a proper image you can download.

Yes, it would be great to re-write the pie chart in SVG. BTW. Still waiting for the merge. I think the patch is ready for action :)

BTW. Still waiting for the merge. I think the patch is ready for action :)

Patches with merge conflicts can't be merged.

I think it will be good to have a Lua equivalent for the parser tag. Not quite the same as T66460 or T396307, but just a mw.svg class that allows constructing the SVG with some content and attributes and having a :toImage() method that emits the image html directly. It would be a cleaner implementation as it avoids the kludges in the current patch like having a <svg> tag that mimics HTML <svg> but outputs an <img>, the CASE_SENSITIVE_ATTRS thing, etc.

I imagine most cases of generated SVGs would be via Lua. Native lua support also avoids having to do string concatenations and feeding the result to frame:preprocess().

Yeah, but core may also provide a solution not involving Scribunto - which is this task.

Yeah, but core may also provide a solution not involving Scribunto - which is this task.

I'll create a dedicated task for Scribunto in that case: T405861.

BTW. Still waiting for the merge. I think the patch is ready for action :)

Patches with merge conflicts can't be merged.

I can fix that if you can merge it later ;)

Nux removed Nux as the assignee of this task.Oct 26 2025, 2:09 PM

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

Lua can be used anywhere wiki markup can be used, so I don't see how use cases are lesser. T405861 also has additional benefits described in its task description.

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

Lua can be used anywhere wiki markup can be used, so I don't see how use cases are lesser. T405861 also has additional benefits described in its task description.

I already met limitations of this twice in the last couple of days. The most important one - I can't use external files in the code, for example, a css style sheet. I really hope that inline svg will be deployed soon.

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

Lua can be used anywhere wiki markup can be used, so I don't see how use cases are lesser. T405861 also has additional benefits described in its task description.

Lua cannot be used directly in articles. You have to write a module first, which requires programming knowledge. You cannot just edit an SVG in the article when Lua is involved. In contrast, this task would allow using SVGs in articles (for simple images), in templates (for reusable images), or in modules (for more specialized use cases). So, like I said, approach from this task is more universal.

Also, if SVGs were allowed in articles, at some point an editor could be added to easily modify them, even without any knowledge of SVG. Perhaps it could even integrate an existing edit tool, such as: https://en.wikipedia.org/wiki/SVG-edit

Lua can be used anywhere wiki markup can be used

Apart from what @Nux wrote, Lua also cannot be used on (third-party) wikis on which Scribunto is not installed. I’m not sure how common this is, though; Scribunto is so widespread on WMF wikis that people probably have hard time importing Wikipedia templates to wikis without Scribunto, so they may want to have it installed.

Lua cannot be used directly in articles. You have to write a module first, which requires programming knowledge.

However, it seems relatively easy to write a module that simply takes <svg> and <img> attributes as parameters, the content as another parameter, and calls the appropriate Scribunto methods. At that point, you can write SVGs practically directly in articles or templates (it starts with {{svg| instead of <svg, and you might need to <nowiki> the content, but that’s about it).

Also, if SVGs were allowed in articles, at some point an editor could be added to easily modify them, even without any knowledge of SVG.

Of course, this part won’t be possible with the {{svg| solution (unless some on-wiki gadget hooks into the editor – I’m not sure if that’s even possible).

The most important one - I can't use external files in the code, for example, a css style sheet. I really hope that inline svg will be deployed soon.

This isn’t a wikitext vs Lua difference, but rather an intentional restriction for security reasons – imposed by the browser, not even our code. (See https://www.w3.org/wiki/SVG_Security#SVG_as_image, which is also linked from the description of the present task.) You’ll need to inline those styles.

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are
the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

LUA is the best programming language currently available on wikis. What use cases other than LUA do you need? Anyway, the ultimately useful idea "allow to dynamically generate graphs":

Lua cannot be used directly in articles. You have to write a module first, which requires
programming knowledge. You cannot just edit an SVG in the article when Lua is involved.

True, but there are programmers who can create well-designed global modules that you subsequently can use in articles or lemma pages in over 1000 wikis, quite an impovement over editing essentially same SVG individually in over 1000 wikis, one at a time.

Lua also cannot be used on (third-party) wikis on which Scribunto is not installed

True, but the more streamlined solution is to install Scribunto there, rather than to install several hacky extensions, and then code horrible non-LUA templates non even providing cycles and variables.

Another problem with this "inline SVG rendered by browser" is that wikis now have 2 very distinct ways to serve SVG, certainly causing maintenance problems in future.

With the "compass problem" I mentioned in the other task https://commons.wikimedia.org/wiki/Category:Sixteen-pointed_compass_roses_(blue_or_white,_grey,_pink) I now, thanks to the solution provided per this task, have 2 alternatives:

  • Maintain 40 almost identical SVG files on commons.
  • Brew a LUA module able to generate those 40 compass roses, controlled by parameters, at commons. Unfortunately, the module will not be usable from other wikis, defeating the point of commons. So I would have to maintain ca 70 copies of that module, one at every wiki using those compass roses. This on not what I would call progress.

If T121470: Central Global Repository for Templates, Lua modules, and Gadgets (10 years old) ever should get resolved, then one must not add further types of or use cases for local templates and modules. On the contrary, the market for local templates and modules should shrink, towards global modules.

Maintain 40 almost identical SVG files on commons.

Well, inline SVG can use a wiki template.

I don't understand why T405861 (Lua implementation) was merged and not this task. The effects for readers are the same, but T405861 only works in Lua (so less use cases for creators). I don't understand this decision.

One reason is scribunto is more self-contained which makes it for various reasons easier to deploy and make changes to.

I would consider users directly inserting svgs in articles an anti-pattern. Even if hypothetically inline svg tags were added i think they should go in templates not articles.

Apart from what @Nux wrote, Lua also cannot be used on (third-party) wikis on which Scribunto is not installed. I’m not sure how common this is, though; Scribunto is so widespread on WMF wikis that people probably have hard time importing Wikipedia templates to wikis without Scribunto, so they may want to have it installed.

I think that one is a them problem. They can install scribunto or not use svgs

I already met limitations of this twice in the last couple of days. The most important one - I can't use external files in the code, for example, a css style sheet.

That is definitely not changing.

At best, a hypothetical inline svg solution might allow svgs styled by templatestyles (maybe, its one variant of the feature idea, but also the nost risky one) There is no world where we will ever allow using arbitrary external stylesheets.

I really hope that inline svg will be deployed soon.

I wouldn't hold my breath. I dont think anyone is actively working on it, and there isnt even political agreement to do it yet.

There is no world where we will ever allow using arbitrary external stylesheets.

I'm talking about a "sanitized CSS" content model local wiki pages, what problem can they possibly create? You can even decide they can be in namespace 8 only, if it will make things better.

I really hope that inline svg will be deployed soon.

I wouldn't hold my breath. I dont think anyone is actively working on it, and there isnt even political agreement to do it yet.

A pity.

However, it seems relatively easy to write a module that simply takes <svg> and <img> attributes as parameters, the content as another parameter, and calls the appropriate Scribunto methods.

This is still less convenient since it uses a module. For an editor of 3rd party wiki, they may want to create SVG images using Inkscape or Illustrator and paste the SVG code directly to wikitext - if the use case is just static SVG image, we can alternatively just upload the image; but if you want to create a template, uploading it as file is not enough and inline SVG provides a way as easy as creating an ordinary MediaWiki template.