The least ceremonious way to do this is by extending HTMLElement in JS and using a custom prop in Elm, see Print unescaped HTML - #5 by jreusch
TLDR:
Object.defineProperty(HTMLElement.prototype, "dangerouslySetInnerHTML", {
get () {
return this.innerHTML
},
set (value) {
this.innerHTML = value
}
})
And in your Elm code:
dangerouslySetInnerHTML: String -> Attribute msg
dangerouslySetInnerHTML= Json.Encode.string >> Html.Attributes.property "dangerouslySetInnerHTML"
view =
div [ dangerouslySetInnerHTML "<b>Hi!</b> I'll probably end up exposed to XSS!" ] []
I did the ports way in a project and it is quite complex to understand for people new to the project.