Power BI is turning 10! Tune in for a special live episode on July 24 with behind-the-scenes stories, product evolution highlights, and a sneak peek at what’s in store for the future.
Save the dateEnhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.
Hello,
We are developing a custom visual where we have to add at least one <img> HTML element. We already have plenty of DOM manipulation and it generally works exactly as we would expect.
However, we have not been able to set the <img> src property to any image included in our own assets. The HTML simply does not locate the file. This is despite attempts such as placing the image source in the same folder as the TypeScript code. Using an online URL as source for the <img> element works fine.
Furthermore, our .less files in our style folder can appropriately detect and implement images located in assets or other folders, applying these as background images to HTML elements.
If we inspect the <img> elements with broken paths, we can tell that their point of origin is: https://app.powerbi.com/[ID-HERE]/
Inspecting elements with correctly applied background images to locate the URI gives us a massive base64 encoded string.
It seems this issue may be related to the context in which our TS files are run, perhaps altering their relative paths. We feel the solution should be simple but we could not find any documentation on it.
Thank you in advance for any and all help!
Solved! Go to Solution.
Hi @JSJB,
If you're trying to lazy-load assets after the visual is initialised, this will not work, as custom visuals have a null domain and therefore have no relative paths to reference if you attempt to load them from a local address.
I've personally solved this in a similar way in which you've observed: bundling into the .less file and using the background-image attribute on a div, or similar.
However, as powerbi-visuals-tools includes base64-inline-loader, you could declare your images as variables in your code and use this to get a valid data URL for each one, which can be set to the src attribute on an image element.
For example, if I just use the visual icon file in the assets folder, I can do something like this:
const img = require("!!base64-inline-loader!./../assets/icon.png");
...
export class Visual implements IVisual {
private target: HTMLElement;
...
constructor(options: VisualConstructorOptions) {
this.target = options.element;
const new_img = document.createElement("img");
new_img.src=img;
this.target.appendChild(new_img);
...
}
...
}
And if I load my visual, this seems to work, e.g.:
If you're expecting your images to be bundled into the visual package, they're going to be base64 encoded anyway, so this approach may be an option for you?
Regards,
Daniel
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Hi @JSJB,
If you're trying to lazy-load assets after the visual is initialised, this will not work, as custom visuals have a null domain and therefore have no relative paths to reference if you attempt to load them from a local address.
I've personally solved this in a similar way in which you've observed: bundling into the .less file and using the background-image attribute on a div, or similar.
However, as powerbi-visuals-tools includes base64-inline-loader, you could declare your images as variables in your code and use this to get a valid data URL for each one, which can be set to the src attribute on an image element.
For example, if I just use the visual icon file in the assets folder, I can do something like this:
const img = require("!!base64-inline-loader!./../assets/icon.png");
...
export class Visual implements IVisual {
private target: HTMLElement;
...
constructor(options: VisualConstructorOptions) {
this.target = options.element;
const new_img = document.createElement("img");
new_img.src=img;
this.target.appendChild(new_img);
...
}
...
}
And if I load my visual, this seems to work, e.g.:
If you're expecting your images to be bundled into the visual package, they're going to be base64 encoded anyway, so this approach may be an option for you?
Regards,
Daniel
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Hey again @dm-p, apologies for the super late reply.
At the time, I didn't pursue the image loading further, but it has become relevant again.
Your proposed solution seems like it would be perfect for me. The only issue I have is actually using the base64 inline loader. Could you give me the full rundown of how you implement it in the project and utilize it? I have installed the tools via npm but I can't seem to be able to detect the base64 inline loader.
Thank you in advance
Hi @JSJB - I set this example up with a brand new project and no additional dependencies, so the base64-inline-loader was already present in my project's dependencies and typings (due to being included in powerbi-visuals-tools). If this is not working for you, you should be able to manually include via npm like you would for any other package and then the example syntax would work.
Daniel
Proud to be a Super User!
On how to ask a technical question, if you really want an answer (courtesy of SQLBI)
Check out the July 2025 Power BI update to learn about new features.