# Perspective HTML Injection

**URL:** <https://forum.inductiveautomation.com/t/perspective-html-injection/74680>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [June 7, 2023, 3:07am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680 "2023-06-07T03:07:53Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [June 7, 2023, 3:07am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/1 "2023-06-07T03:07:53Z")

</div>

So... while doing some module debugging, I noticed Ignition trying to access a non-existent folder `<install-directory>\data\modules\com.inductiveautomation.perspective\injectables`.

After creating the folder manually, Ignition then tried to access:

```auto
injectables\head_top.txt
injectables\head_bottom.txt
injectables\body_top.txt
injectables\body_bottom.txt

```

And what do you know, any HTML you put in these files will be directly loaded in the DOM of all Perspective sessions 🤷‍♂️ .

![java_xpBJWmVKrm](https://us1.discourse-cdn.com/inductiveautomation/original/3X/d/3/d3a5734db83bbad37e69395e878847314e72bfa7.gif)

_PS:_ Please don't send the hit squad 🙃 .

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [June 7, 2023, 8:11am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/2 "2023-06-07T08:11:53Z")

</div>

Oh this is gonna be fun !

edit: It's been 11h and we still haven't heard from Victor.  
I'm guessing he's currently being held in custody for of all the server fires in his area.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [June 7, 2023, 4:16pm UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/3 "2023-06-07T16:16:40Z")

</div>

TL;DR: This has been possible forever. You're certainly allowed to do it (we can't stop you) but I'll present the following caveats as reasons we haven't and won't document this:

1. You can completely break Perspective, pretty easily, with this
2. We don't want you to have to know HTML or JS to develop in Perspective
3. We don't want people doing silly stuff like trying to dynamically modify these
4. Anything you _do_ use this for should be considered unsupported. If we ever broke this functionality, it would likely be because we offered a supported, first-party solution, so I wouldn't necessarily worry about it dropping out from underneath you, but also, don't even _think_ about contacting support if you do use this and something goes wrong.

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 6:55am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/4 "2023-06-16T06:55:24Z")

</div>

I had exams xd

Does look interesting though. could be usefull to track some general things on every page. Tho it being loaded everywhere is not super versatile

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [June 16, 2023, 6:58am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/5 "2023-06-16T06:58:23Z")

</div>

Yea, right...  
You don't wanna say IA orange clockworked you for a week somewhere in a damp basement, I get it.

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 7:00am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/6 "2023-06-16T07:00:54Z")

</div>

xD It was AI actual not IA 😛 im following a course for AI (artifical intellengce)

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [June 16, 2023, 8:03am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/7 "2023-06-16T08:03:28Z")

</div>

> [@victordcq](#):
>
> AI actual

Nope. Unfortunately, AI doesn't stand for Actual Intelligence. 🤣

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 9:10am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/8 "2023-06-16T09:10:05Z")

</div>

Well for many specific applications AI is a lot smarter than us.  
But yes the all purpose general super AI isnt there yet

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 9:20am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/9 "2023-06-16T09:20:30Z")

</div>

reading up on some of the recent questions...

This could be usefull for:

> [@\[FEATURE\] Perspective Workstation: Show numeric/text input on-screen keyboard for touchscreens](https://forum.inductiveautomation.com/t/feature-perspective-workstation-show-numeric-text-input-on-screen-keyboard-for-touchscreens/41741):
>
> We’ve just started rolling out Perspective Workstation on touchscreens and have noticed that there’s no onscreen keyboard that pops up when a user tries to enter a new setpoint into a numeric input field. We have to ensure that Windows 10 is set to tablet mode, and tell the operators to click on the onscreen keyboard icon in the windows tray to enter values… however then the keyboard covers the bottom half of the Perspective screen, 50% of the time which is where the input component is located, …

> [@Perspective - Font Scaling with SVG?](https://forum.inductiveautomation.com/t/perspective-font-scaling-with-svg/74584/11):
>
> CSS can't know things like container sizes reliably because of how rendering order and style cascading works in the browser, fundamentally. So you would have to have JS running on the page to dynamically report the actual container size in order to run an actual dynamic font size calculation the way Vision does. But we don't allow you to write arbitrary JS in Perspective, because we didn't want folks to have to become web developers.

---

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [June 16, 2023, 10:47am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/10 "2023-06-16T10:47:22Z")

</div>

> [@victordcq](#):
>
> following a course for AI

I'm with ya. I've been learning it too.

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [June 16, 2023, 12:15pm UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/11 "2023-06-16T12:15:29Z")

</div>

Hear me out……

banner ads

😆

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 12:23pm UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/12 "2023-06-16T12:23:58Z")

</div>

it would be super easy to add in google adds or something yes...  
i dont think you'll be able to sell that to your clients though xd

_watch this add for 10 sec before you can press the emergency stop button_  
_Clash of clans..._

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [June 16, 2023, 12:25pm UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/13 "2023-06-16T12:25:15Z")

</div>

does this get loaded in on the login page too? could be usefull to highjack that page for 3th party login methodes or something

(if you know what you are doing ofc)

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [January 24, 2024, 4:31am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/14 "2024-01-24T04:31:45Z")

</div>

Back again with some highly-questionable antics.

**head\_top.txt**

```auto
<script>

const root = document.querySelector(':root');

document.addEventListener("mousemove", (e) => {
  root.style.setProperty("--mousemove-clientX", e.clientX + "px");
  root.style.setProperty("--mousemove-clientY", e.clientY + "px");

  root.style.setProperty("--mousemove-pageX", e.pageX + "px");
  root.style.setProperty("--mousemove-pageY", e.pageY + "px");
  
  root.style.setProperty("--mousemove-screenX", e.screenX + "px");
  root.style.setProperty("--mousemove-screenY", e.screenY + "px");
});

document.addEventListener("mousedown", (e) => {
  root.style.setProperty("--mousedown-clientX", e.clientX + "px");
  root.style.setProperty("--mousedown-clientY", e.clientY + "px");

  root.style.setProperty("--mousedown-pageX", e.pageX + "px");
  root.style.setProperty("--mousedown-pageY", e.pageY + "px");
  
  root.style.setProperty("--mousedown-screenX", e.screenX + "px");
  root.style.setProperty("--mousedown-screenY", e.screenY + "px");
});

document.addEventListener("mouseover", (e) => {
  root.style.setProperty("--mouseover-id", '"' + e.target.id + '"');
});

</script>

```

This makes the _mousemove_ and _mousedown_ positions available as CSS custom properties on the root.

_Edit:_  
This can be used to create performant dragging functionality, by moving the _mousemove_ values into session properties.

```auto
  window.__client.page.sessionCustom.write('mousemove', {
    clientX: e.clientX,
    clientY: e.clientY,
    pageX: e.pageX,
    pageY: e.pageY,
    screenX: e.screenX,
    screenY: e.screenY
  });

```

In this example:

1. While dragging, the position of the box is set using CSS properties for a smooth experience.
2. While dragging, in the background, the position of the box is stored in tags using the **onMouseMoved** component event.
3. All non-dragging sessions use the tag values for the position of the box. (Animation could also be applied to the non-dragging sessions to smooth the movement out).

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [January 24, 2024, 8:04am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/15 "2024-01-24T08:04:55Z")

</div>

i guess this is simpler to implement with limited js knowledge, than the mutation observers and js i used.  
But my js dnd method is correcter to do than use this css hack. But i guess its not as easy to make it general.

ive not really experimentent with the general html page yet, i kinda forgot about it cuz i was busy at the time you created this. But this made me interested again, tobad im kinda busy again 😛

---

<div class="post-metadata">

**Author:** ![sunshare21](https://avatars.discourse-cdn.com/v4/letter/s/9de0a6/32.png) [@sunshare21](https://forum.inductiveautomation.com/u/sunshare21)\
**Post date:** [November 16, 2025, 9:00am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/16 "2025-11-16T09:00:30Z")

</div>

Hello everyone, may I ask if the injection method is feasible in IgnitionScada8.3? Has anyone tested it?

---

<div class="post-metadata">

**Author:** ![nminchin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nminchin/32/6911_2.png) [@nminchin](https://forum.inductiveautomation.com/u/nminchin)\
**Post date:** [December 19, 2025, 2:34am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/17 "2025-12-19T02:34:11Z")

</div>

Yes it works, still the same folder path though so you have to manually create the path now as it no longer exists by default… a bit dodgy.

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [December 19, 2025, 3:08am UTC](https://forum.inductiveautomation.com/t/perspective-html-injection/74680/18 "2025-12-19T03:08:46Z")

</div>

It was dodgy originally.

IMO if you’re doing something that requires special client-side HTML/JavaScript, then you’re probably capable enough to accomplish the task the supported way (i.e. build a module).
