# dp-content
Renders user-supplied text as safe rich content: emoji shortcodes, GitHub-flavored markdown,
`DOMPurify` sanitisation, then media embeds (images, video, YouTube), mentions, and
autolinks. It exposes the shared `contentRenderer` engine (`static/js/ContentRenderer.js`),
the same pipeline used by the site's `data-render` attribute, as a custom element.
> Server-rendered content is now produced on the **backend** for SEO (the `render_content`
> Jinja global, `devplacepy/rendering.py`, full feature parity built on mistune). This client
> component is retained for **live, client-generated content only** - for example the DeepSearch
> chat answers and the planning report, which do not exist when the page is first rendered. Do not
> use it for content that is known at request time; call `render_content` in the template instead.
Source: `static/js/components/AppContent.js`.
## Behaviour
- On connection the element reads its own text, renders it once, and replaces its contents with
the sanitised HTML; code blocks are highlighted.
- Sanitisation is fail-closed: rendering throws if `DOMPurify` is unavailable rather than
emitting unsanitised HTML.
- Equivalent to `data-render` on a server-rendered element, but as a self-contained element you
drop in directly.
- A copy button appears in the top-right corner on hover (and on focus) that copies the element's
original markdown source to the clipboard, mirroring the code-block copy button. Add the
`no-copy` boolean attribute to suppress it.
## Usage
Put markdown (or plain text) as the element's text. Escape any literal HTML you do not want
treated as live markup:
```html
<dp-content>
# Hello
Visit **DevPlace** :rocket: and watch https://youtu.be/dQw4w9WgXcQ
</dp-content>
```
Live example
## Markdown, rendered live
This is **bold**, this is _italic_, and here is a shortcode :rocket: :fire:.
- a list item
- another with `inline code`
- a mention of @alice_test and a link to https://example.com
```js
const answer = 42;
```