Skip to content

Commit

Permalink
Add page about setting raw HTML content (denoland#2189)
Browse files Browse the repository at this point in the history
  • Loading branch information
CAYdenberg committed Mar 15, 2024
1 parent 4f671ec commit c4b4919
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
80 changes: 80 additions & 0 deletions docs/latest/examples/rendering-raw-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
description: |
How to render raw HTML in Fresh.
---

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.

## Warning

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.

## Example: Rendering JSON-LD

Suppose we need to add some microdata markup to a page. The following will
result in **escaped characters, and will not work**:

```tsx
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`:

```tsx
export default function JsonLd() {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: json }}
/>
);
}
```

## Another example: Code highlighting

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:

```tsx
import Prism from "https://esm.sh/prismjs@1.29.0";

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.
2 changes: 2 additions & 0 deletions docs/toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const toc: RawTableOfContents = {
["creating-a-crud-api", "Creating a CRUD API", "link:latest"],
["handling-complex-routes", "Handling complex routes", "link:latest"],
["rendering-markdown", "Rendering markdown", "link:latest"],
["rendering-raw-html", "Rendering raw HTML", "link:latest"],
[
"sharing-state-between-islands",
"Sharing state between islands",
Expand Down Expand Up @@ -160,6 +161,7 @@ const toc: RawTableOfContents = {
["creating-a-crud-api", "Creating a CRUD API"],
["handling-complex-routes", "Handling complex routes"],
["rendering-markdown", "Rendering markdown"],
["rendering-raw-html", "Rendering raw HTML"],
["sharing-state-between-islands", "Sharing state between islands"],
["using-csp", "Using CSP"],
["active-links", "Styling active links"],
Expand Down

0 comments on commit c4b4919

Please sign in to comment.