docs/1.x/examples/rendering-raw-html.md
Text content in Fresh is always escaped, whether serverside rendered or rendered in islands. While this generally desired, it can create issues in certain situations.
The TL;DR is to use Preact's dangerouslySetInnerHTML. As the name implies, it
should not be used lightly.
Setting arbitrary HTML can be dangerous. Make sure you trust the source. Rendering user-supplied HTML to the DOM makes your site vulnerable to cross- site scripting. The markup must first be sanitizied, or better yet, something you trust.
Suppose we need to add some microdata markup to a page. The following will result in escaped characters, and will not work:
const json = `
{
"@context": "http://schema.org",
"@type": "PostalAddress",
"streetAddress": "8888 University Drive",
"addressLocality": "Burnaby",
"addressRegion": "British Columbia"
}
`;
export default function JsonLd() {
return <script type="application/ld+json">{json}</script>;
}
Instead, we can use dangerouslySetInnerHTML:
export default function JsonLd() {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: json }}
/>
);
}
Syntax highlighters parse strings into HTML tags, allowing them to be individually styled with CSS. We can build a simple Preact syntax highlighter like so:
import Prism from "https://esm.sh/[email protected]";
interface Props {
code: string;
lang: string;
}
export default function Code({ code, lang }: Props) {
const parsed = Prism.highlight(code, Prism.languages[lang], lang);
return (
<pre data-lang={lang} className={`language-${lang}`}>
<code
dangerouslySetInnerHTML={{
__html: parsed,
}}
/>
</pre>
);
}
Of course, we will also have to add some CSS to make this look nice.