diff --git a/src/lib/components/preview.svelte b/src/lib/components/preview.svelte
index 6b3984d..392da4e 100644
--- a/src/lib/components/preview.svelte
+++ b/src/lib/components/preview.svelte
@@ -1,12 +1,6 @@
diff --git a/src/lib/render-preview.ts b/src/lib/render-preview.ts
new file mode 100644
index 0000000..62ca291
--- /dev/null
+++ b/src/lib/render-preview.ts
@@ -0,0 +1,28 @@
+import rehypeDocument from 'rehype-document';
+import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
+import rehypeStringify from 'rehype-stringify';
+import remarkParse from 'remark-parse';
+import remarkRehype from 'remark-rehype';
+import { unified } from 'unified';
+
+const renderPreview = async (markdown: string, stylesheet: string): Promise => {
+ let allowedTags: string[] = ['body', 'head', 'html', 'style'];
+ if (defaultSchema.tagNames) {
+ allowedTags = [...defaultSchema.tagNames, ...allowedTags];
+ }
+ return String(
+ await unified()
+ .use(remarkParse)
+ .use(remarkRehype)
+ .use(rehypeDocument, { style: stylesheet })
+ .use(rehypeSanitize, {
+ ...defaultSchema,
+ allowDoctypes: true,
+ tagNames: allowedTags,
+ })
+ .use(rehypeStringify)
+ .process(markdown),
+ );
+};
+
+export default renderPreview;