I'm using Tiptap editor to write content, and then I attach data generated by it via v-html
directive.
I understand that v-html can process images that have absolute source like 'https://something/file.jpg', but I need to require an image that goes through Webpack and gets a hash in its name. And requiring images seems not to be working inside v-html. Did someone solve such a problem?
upd The code is the following:
<div v-html="someData"></div>
someData comes as response to async request and it looks like this:
<p> kjfdkf </p> <p> kfdfk </p> <div> kdfjdkf </div>
This is a standard output of text editor. In order not to show it with tags I pass it to v-html
. The question is how to address images going through webpack. I don't have a clue.
I'm not totally sure I understood your question correctly, but considering you have an HTML string like this:
<p> kjfdkf </p>
<img src="PATH" />
<p> kfdfk </p>
<img src="PATH" />
<div> kdfjdkf </div>
...with random image elements inside, you could probably parse the HTML to change the sources of the image elements to their raw data instead of the current relative paths.
DOMParser
seems like the easiest option to parse the HTML, as you can parse it in one line:
let el = new DOMParser().parseFromString(this.html, "text/html");
Then just find all image elements:
let imgs = el.getElementsByTagName("img");
...change their sources to the raw forms:
imgs.forEach((img) => (img.src = require(img.src)));
...select the body of el
(since that's where your HTML is in):
let body = el.body;
...and return its innerHTML:
return body.innerHTML;
You can wrap this all in a computed property:
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
}
Here's the full code:
<template>
<div id="app">
<div v-html="processedHtml"></div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
html: `<p> kjfdkf </p><img src="PATH" /> <p> kfdfk </p> <img src="PATH" /> <div> kdfjdkf </div>`,
};
},
computed: {
processedHtml() {
let el = new DOMParser().parseFromString(this.html, "text/html"),
imgs = el.getElementsByTagName("img");
imgs.forEach((img) => (img.src = require(img.src)));
let body = el.body;
return body.innerHTML;
},
},
};
</script>
Alternatively, if you move the images to your public
directory, their names won't be modified by webpack, so you could possibly avoid all this.