# Interactive SVG using \<object\>?

**URL:** https://meta.discourse.org/t/interactive-svg-using-object/173747
**Category:** Self-hosting
**Created:** [December 18, 2020, 5:25pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747 "2020-12-18T17:25:01Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [December 18, 2020, 5:25pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/1 "2020-12-18T17:25:01Z")

</div>

I’m trying to embed an interactive, SVG-based, data visualization. I’m generating SVG from a separate system, (but still in the same second-level domain as my Discourse installation.) I’ve tried bringing the SVG in using an OBJECT tag…

```
<object type="image/svg+xml" data="full_URL_to_foo.svg">
(appears if object load fails)
</object>

```

If I simply bring that SVG (it’s dynamically generated each time) in with an IMG tag, the visual appears, but (as I expected) there’s no interactivity…

```
<img src="full_URL_to_foo.svg">

```

Thoughts or pointers where I can buy some clues re SVGs and Discourse? 🙂

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [December 18, 2020, 6:47pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/2 "2020-12-18T18:47:38Z")

</div>

The easier way to get this working is using an iframe. Add the SVG domain to the `allowed_iframes` site setting and add it to a post using HTML.

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [December 23, 2020, 1:58am UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/3 "2020-12-23T01:58:57Z")

</div>

hmmmm, so that’s the easy way.

Is there a hard way I can try?

…because I want to have links in the SVG that change the browser location. Links in the SVG, in an IFRAME, change what’s shown in the IFRAME . . .

I suspect that embedding j/s in the topic, just before the IFRAME, and calling a j/s function in the page onclick in the SVG… that’s not going to work either.

Am I making sense? Should I be adding some thin j/s code ala [Mitigate XSS Attacks with Content Security Policy](https://meta.discourse.org/t/mitigate-xss-attacks-with-content-security-policy/104243) and then trying to call that from within the SVG in the IFRAME? …or is “in the IFRAME” an airtight fortress?

Maybe I should be asking how I can directly inline the SVG into the page? Then use theme-component injected j/s to interact with my other server to dynamically update the SVG?

Cluebat please 🙂

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [December 23, 2020, 4:31am UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/4 "2020-12-23T04:31:02Z")

</div>

Putting the svg in the post marked by a sorrounding special div and using a theme-component to make it into an object tag using the decorateCooked callback may work. Check [Developer’s guide to Discourse Themes](https://meta.discourse.org/t/developer-s-guide-to-discourse-themes/93648)

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 9, 2021, 5:58pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/5 "2021-01-09T17:58:31Z")

</div>

…in case anyone is following along, decorateCooked() is deprecated. I’m fiddling with decorateCookedElement() instead.

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 9, 2021, 10:02pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/6 "2021-01-09T22:02:48Z")

</div>

I’m up against CORS/Access-Control-Allow-Origin. I’m not familiar with how that works…

I have two sites—the Hosted Discourse site ([forum.moversmindset.com](http://forum.moversmindset.com)) and an Apache-based Wordpress site ([moversmindset.com](http://moversmindset.com)). Note that there’s no obvious content on the Wordpress site—it’s all generating RSS feeds, serving media, etc. If you go to the domain, it’ll just send you to the forum.

I have a directory, that serves SVG-type replies to GET request. For example (not the real url) [https://moversmindset.com/foo/bar.php](https://moversmindset.com/foo/bar.php)

In my Discourse theme I’m experimenting with script code. (eventually to be a proper plugin) It calls api.decorateCooked() on particular DIVs that have some data-custom added to them. So inside the function called by decorateCooked() I’m doing what amounts to

$.get(‘[https://moversmindset.com/foo/bar.php](https://moversmindset.com/foo/bar.php)’ … bla bla blah

So I want to retrieve the SVG and then append it to the DOM. But my browser error console says:

 ![Screen Shot 2021-01-09 at 16.59.07](https://global.discourse-cdn.com/meta/original/3X/d/4/d470addbcb1670fe1dfb26549f2feb6a85025555.png)

# Question:

Does that mean I have to configure CORS on the Discourse installation or over on the Apache/Wordpress?

I _do_ have [https://moversmindset.com](https://moversmindset.com) configured as allowed in CORS on Discourse.

---

<div class="post-metadata">

### Author: ![tshenry](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tshenry/32/119495_2.png) [@tshenry](https://meta.discourse.org/u/tshenry)
#### Post date: [January 11, 2021, 10:09pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/7 "2021-01-11T22:09:12Z")

</div>

> [@craigconstantine](#):
>
> over on the Apache/Wordpress?

I _think_ it’s on this side. Can you take a look at [Access-Control-Allow-Origin header - HTTP | MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) if you haven’t already and see if that gives you any clues?

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 12, 2021, 1:49am UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/8 "2021-01-12T01:49:06Z")

</div>

teeny tiny steps, but YES!

I had to add an Access-Control-Allow-Origin header on the apache/WP server. That made the j/s (sourced from the Discourse platform) happy. Thanks.

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 24, 2021, 3:56pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/9 "2021-01-24T15:56:07Z")

</div>

I’ve continued to slowly figure this out. This requires a lot of setup to ask my question:

# SVG

I have a web server that generates SVG. For this question, it generates a very simple test SVG…

```
<svg xmlns="http://www.w3.org/2000/svg" stroke-linejoin="round" viewBox="0 0 100 100">
<path d="M50,4L4,50L50,96L96,50Z" stroke="#40638C" stroke-width="3"></path>
<path d="M50,5L5,50L50,95L95,50Z" stroke="#333" fill="#40638C" stroke-width="3"></path>
<path d="M37,42c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#40495E" fill="#40495E"></path>
<path d="M35,40c-1,0,11-20,13-20c1,0,15,20,13,20h-9c0,8,9,22,12,25l-4,4l-8,-7v13h-10v-35z" stroke="#333" fill="#555"></path>
</svg>

```

It’s just a fancy-looking “merge” sign. Note that it has four PATH elements.

# Inlining

To get the SVG into a post, I’m using some javascript added via my theme.

The end-goal would be to make a proper plugin. But I’m just trying to build a proof-of-concept. So it’s simply pasted into the `</head>` section of my theme customization:

```
<script type="text/discourse-plugin" version="0.8">
var UMB = {
    svgload: function(base, target) {
        var url = base + $(target).text();
        $(target).html('');
        $.ajax({
            method: "GET",
            url: url,
            async: false,
            dataType: "text",
            success: function(data) { $(target).append(data); }
        });
        alert('loaded!');
        $(target).children('path').each(function(){alert('here is a path element');});
    },
}
$.fn.umbdv = function() {
    this.each(
        function() {
            UMB.svgload(' __URL_REDACTED__', this);
        }
    );
    return this;
};
api.decorateCooked(
  $elem => $elem.children('.cooked div[data-custom="umbdv"]').umbdv(),
  { id: 'umbdv' }
);
</script>

```

**Where…**

`var UMB = {` is simply a global variable that avoids me having giant anonymous functions all over the place.

`$.fn.umdv = ` is [what I think is called] a “plugin” extending JQuery.

`api.decorateCooked(` let’s me manipulate the post before it’s sent to the browser.

# Incantation

In a topic, I then write…

```
<div data-custom="umbdv">/vtest</div>

```

`UMB.svgload(' __URL_REDACTED__', this)` is called for that DIV.

`UMB.svgload()` correctly groks that `/vtest` string, composes a url and makes the AJAX request. It successfully does the `append(data)` and `*boop*` my SVG is inline…

 ![Screen Shot 2021-01-24 at 10.50.45](https://global.discourse-cdn.com/meta/original/3X/0/d/0d77868422a66d47e0914bd5bff232bc3779bc0e.png)

My `alert()` inside `UMB.svgload()` then fires, just as expected. (It’s obviously a debug hack, right? `:)`

# The question (finally)

I have a STAFF ONLY topic in my Discourse hosted forum where you can see this in action. (I’m talking to Discourse staff/support who can barge into my installation as Admin users.)

[https://forum.moversmindset.com/t/svg-experimentation-in-progress/1109](https://forum.moversmindset.com/t/svg-experimentation-in-progress/1109)

Why doesn’t…

```
$(target).children('path').each(function(){alert('here is a path element');});

```

…select any of the PATH elements?

It does nothing—no errors. Nothing.

# Next

Where I’ll be going if I get this trivial `alert()` proof-of-concept working…

I’m aware that the chunk of the DOM I’m “working with” is not yet connected to the actual document DOM (at the point where `UMB.svgload()` is called.) That’s why I expect `$(target)…` to be what I need.

Ultimately, I’m inlining _vastly_ more complex SVG and I’ll need to use more complex JQuery selectors. I want to find many elements inside `$(target)` and attach event handlers (onclick for example) that will be calling other `UMB.…` global functions.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [January 25, 2021, 4:23am UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/10 "2021-01-25T04:23:12Z")

</div>

> [@craigconstantine](#):
>
> because I want to have links in the SVG that change the browser location. Links in the SVG, in an IFRAME, change what’s shown in the IFRAME . . .

Iframes can change top level navigation if you want to

[http://w3c-test.org/html/semantics/embedded-content/the-iframe-element/iframe\_sandbox\_allow\_top\_navigation\_by\_user\_activation-manual.html](http://w3c-test.org/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation-manual.html)

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 25, 2021, 12:18pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/11 "2021-01-25T12:18:35Z")

</div>

Thanks for the tip!

But definitely preferring the SVG inline now.

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [January 31, 2021, 11:49pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/12 "2021-01-31T23:49:40Z")

</div>

aaaaaanyway. Weeks later. This doesn’t work.

Doesn’t seem possible to manipulate the SVG DOM elements once it’s inlined to the main document. So I cannot figure out how to add event triggers/actions (which one could easily do as onclick et al if the SVG is loaded in an iframe)  
((_not_ using an iFrame was my whole goal.))

`¯\_(ツ)_/¯`

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [March 2, 2021, 11:50pm UTC](https://meta.discourse.org/t/interactive-svg-using-object/173747/13 "2021-03-02T23:50:15Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
