diff --git a/docs/advanced/making plugins.md b/docs/advanced/making plugins.md
index 1f1616f..d0934ad 100644
--- a/docs/advanced/making plugins.md	
+++ b/docs/advanced/making plugins.md	
@@ -247,7 +247,7 @@ If you are creating an emitter plugin that needs to render components, there are
 
 - Your component should use `getQuartzComponents` to declare a list of `QuartzComponents` that it uses to construct the page. See the page on [[creating components]] for more information.
 - You can use the `renderPage` function defined in `quartz/components/renderPage.tsx` to render Quartz components into HTML.
-- If you need to render an HTML AST to JSX, you can use the `toJsxRuntime` function from `hast-util-to-jsx-runtime` library. An example of this can be found in `quartz/components/pages/Content.tsx`.
+- If you need to render an HTML AST to JSX, you can use the `htmlToJsx` function from `quartz/util/jsx.ts`. An example of this can be found in `quartz/components/pages/Content.tsx`.
 
 For example, the following is a simplified version of the content page plugin that renders every single page.
 
diff --git a/quartz/components/TagList.tsx b/quartz/components/TagList.tsx
index e39186e..cb1c121 100644
--- a/quartz/components/TagList.tsx
+++ b/quartz/components/TagList.tsx
@@ -33,9 +33,12 @@ TagList.css = `
   gap: 0.4rem;
   margin: 1rem 0;
   flex-wrap: wrap;
-  justify-content: flex-end;
   justify-self: end;
 }
+
+.section-ul .tags {
+  justify-content: flex-end;
+}
   
 .tags > li {
   display: inline-block;
diff --git a/quartz/components/pages/Content.tsx b/quartz/components/pages/Content.tsx
index 7490a7e..76cecc3 100644
--- a/quartz/components/pages/Content.tsx
+++ b/quartz/components/pages/Content.tsx
@@ -1,10 +1,8 @@
+import { htmlToJsx } from "../../util/jsx"
 import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
-import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
-import { toJsxRuntime } from "hast-util-to-jsx-runtime"
 
-function Content({ tree }: QuartzComponentProps) {
-  // @ts-ignore (preact makes it angry)
-  const content = toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
+function Content({ fileData, tree }: QuartzComponentProps) {
+  const content = htmlToJsx(fileData.filePath!, tree)
   return <article class="popover-hint">{content}</article>
 }
 
diff --git a/quartz/components/pages/FolderContent.tsx b/quartz/components/pages/FolderContent.tsx
index a766d4b..765f846 100644
--- a/quartz/components/pages/FolderContent.tsx
+++ b/quartz/components/pages/FolderContent.tsx
@@ -1,6 +1,4 @@
 import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
-import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
-import { toJsxRuntime } from "hast-util-to-jsx-runtime"
 import path from "path"
 
 import style from "../styles/listPage.scss"
@@ -8,6 +6,7 @@ import { PageList } from "../PageList"
 import { _stripSlashes, simplifySlug } from "../../util/path"
 import { Root } from "hast"
 import { pluralize } from "../../util/lang"
+import { htmlToJsx } from "../../util/jsx"
 
 function FolderContent(props: QuartzComponentProps) {
   const { tree, fileData, allFiles } = props
@@ -29,8 +28,7 @@ function FolderContent(props: QuartzComponentProps) {
   const content =
     (tree as Root).children.length === 0
       ? fileData.description
-      : // @ts-ignore
-        toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
+      : htmlToJsx(fileData.filePath!, tree)
 
   return (
     <div class="popover-hint">
diff --git a/quartz/components/pages/TagContent.tsx b/quartz/components/pages/TagContent.tsx
index 9907e3f..205ba89 100644
--- a/quartz/components/pages/TagContent.tsx
+++ b/quartz/components/pages/TagContent.tsx
@@ -1,12 +1,11 @@
 import { QuartzComponentConstructor, QuartzComponentProps } from "../types"
-import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
-import { toJsxRuntime } from "hast-util-to-jsx-runtime"
 import style from "../styles/listPage.scss"
 import { PageList } from "../PageList"
 import { FullSlug, getAllSegmentPrefixes, simplifySlug } from "../../util/path"
 import { QuartzPluginData } from "../../plugins/vfile"
 import { Root } from "hast"
 import { pluralize } from "../../util/lang"
+import { htmlToJsx } from "../../util/jsx"
 
 const numPages = 10
 function TagContent(props: QuartzComponentProps) {
@@ -26,8 +25,7 @@ function TagContent(props: QuartzComponentProps) {
   const content =
     (tree as Root).children.length === 0
       ? fileData.description
-      : // @ts-ignore
-        toJsxRuntime(tree, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
+      : htmlToJsx(fileData.filePath!, tree)
 
   if (tag === "") {
     const tags = [...new Set(allFiles.flatMap((data) => data.frontmatter?.tags ?? []))]
diff --git a/quartz/util/jsx.ts b/quartz/util/jsx.ts
new file mode 100644
index 0000000..8cba485
--- /dev/null
+++ b/quartz/util/jsx.ts
@@ -0,0 +1,15 @@
+import { toJsxRuntime } from "hast-util-to-jsx-runtime"
+import { QuartzPluginData } from "../plugins/vfile"
+import { Node, Root } from "hast"
+import { Fragment, jsx, jsxs } from "preact/jsx-runtime"
+import { trace } from "./trace"
+import { type FilePath } from "./path"
+
+export function htmlToJsx(fp: FilePath, tree: Node<QuartzPluginData>) {
+  try {
+    // @ts-ignore (preact makes it angry)
+    return toJsxRuntime(tree as Root, { Fragment, jsx, jsxs, elementAttributeNameCase: "html" })
+  } catch (e) {
+    trace(`Failed to parse Markdown in \`${fp}\` into JSX`, e as Error)
+  }
+}
diff --git a/quartz/util/trace.ts b/quartz/util/trace.ts
index c7f3cc3..a33135d 100644
--- a/quartz/util/trace.ts
+++ b/quartz/util/trace.ts
@@ -4,7 +4,7 @@ import { isMainThread } from "workerpool"
 
 const rootFile = /.*at file:/
 export function trace(msg: string, err: Error) {
-  const stack = err.stack
+  let stack = err.stack ?? ""
 
   const lines: string[] = []
 
@@ -12,15 +12,11 @@ export function trace(msg: string, err: Error) {
   lines.push(
     "\n" +
       chalk.bgRed.black.bold(" ERROR ") +
-      "\n" +
+      "\n\n" +
       chalk.red(` ${msg}`) +
       (err.message.length > 0 ? `: ${err.message}` : ""),
   )
 
-  if (!stack) {
-    return
-  }
-
   let reachedEndOfLegibleTrace = false
   for (const line of stack.split("\n").slice(1)) {
     if (reachedEndOfLegibleTrace) {