astro-remote
v0.3.3
Published
Render remote HTML or Markdown content in Astro with full control over the output.
Downloads
8,597
Maintainers
Readme
Astro Remote
Render remote HTML or Markdown content in Astro with full control over the output.
Powered by ultrahtml
and marked
.
Install
npm install astro-remote
pnpm install astro-remote
yarn install astro-remote
Rendering Remote Content
The most basic function of astro-remote
is to convert a string of HTML or Markdown to HTML. Use the Markup
and Markdown
components depending on your input.
---
import { Markup, Markdown } from 'astro-remote';
const { html, markdown } = await fetch('http://my-site.com/api/v1/post').then(res => res.json());
---
<Markup content={html} />
<Markdown content={markdown} />
Sanitization
By default, all HTML content will be sanitized with sensible defaults (script
blocks are dropped). This can be controlled using the SanitizeOptions
available in ultrahtml
. Set to false
to disable sanitization.
---
import { Markup } from 'astro-remote';
const content = await fetch('http://my-site.com/api/v1/post').then(res => res.text());
---
<!-- Disallow `head` and `style` attributes, and standard formatting from host website -->
<Markup
content={content}
sanitize={{
dropElements: ["head","style"],
blockElements: ["html", "body", "div"],
}}
/>
Customization
Both Markup
and Markdown
allow full control over the rendering of output. The components
option allows you to replace a standard HTML element with a custom component.
---
import { Markdown, Markup } from 'astro-remote';
import Title from '../components/Title.astro';
const content = await fetch('http://my-site.com/api/v1/post').then(res => res.text());
---
<!-- Render <h1> as custom <Title> component -->
<Markup content={content} components={{ h1: Title }} />
<Markdown content={content} components={{ h1: Title }} />
In addition to built-in HTML Elements, Markdown
also supports a few custom components for convenience.
<Heading />
The Heading
component renders all h1
through h6
elements. It receives the following props:
as
, theh1
throughh6
taghref
, a pre-generated, slugifiedhref
text
, the text content of the children (for generating a custom slug)
---
import { Markdown } from 'astro-remote';
import Heading from '../components/Heading.astro';
const content = await fetch('http://my-site.com/api/v1/post').then(res => res.text());
---
<!-- Render all <h1> through <h6> using custom <Heading> component -->
<Markdown content={content} components={{ Heading }} />
A sample Heading
component might look something like this.
---
const { as: Component, href } = Astro.props;
---
<Component><a href={href}><slot /></a></Component>
<CodeBlock />
The CodeBlock
component allows you customize the rendering of code blocks. It receives the following props:
lang
, the language specified after the three backticks (defaults toplaintext
)code
, the raw code to be highlighted. Be sure to escape the output!...props
, any other attributes passed to the three backticks. These should follow HTML attribute format (name="value"
)
A sample CodeBlock
component might look something like this.
---
const { lang, code, ...props } = Astro.props;
const highlighted = await highlight(code, { lang });
---
<pre class={`language-${lang}`}><code set:html={highlighted} /></pre>
<CodeSpan />
The CodeSpan
component allows you customize the rendering of inline code spans. It receives the following props:
code
, the value of the code span
A sample CodeSpan
component might look something like this.
---
const { code } = Astro.props;
---
<code set:text={code} />
<Note />
The Note
component allows you customize the rendering of GitHub-style notes and warnings. It receives the following props:
type
, either"note"
or"warning"
To use a Note
component in Markdown, use the following syntax:
> **Note**
> Some tip here!
> **Warning**
> Some warning here!
Custom Components in Markdown
If you'd like to allow custom components in Markdown, you can do so using a combination of the sanitize
and components
options. By default, sanitization removes components.
Given the following markdown source:
# Hello world!
<MyCustomComponent a="1" b="2" c="3">It works!</MyCustomComponent>
---
import { Markdown } from 'astro-remote';
import MyCustomComponent from '../components/MyCustomComponent.astro';
const content = await fetch('http://my-site.com/api/v1/post').then(res => res.text());
---
<Markdown content={content} sanitize={{ allowComponents: true }} components={{ MyCustomComponent }} />
Using Marked Extensions
If you'd like to extend the underlying Marked behavior, the marked
prop accepts extensions
.
---
import { Markdown } from 'astro-remote';
import markedAlert from 'marked-alert'
const content = await fetch('http://my-site.com/api/v1/post').then(res => res.text());
---
<Markdown content={content} marked={{ extensions: [ markedAlert() ] }} />