コンテンツへスキップ
My Site

NotroContent

NotroContent is an Astro component that compiles and renders preprocessed Notion markdown. It handles MDX compilation, component mapping, and optional internal link resolution.

Import

import { NotroContent } from "notro-loader";

Usage


---
import { NotroContent } from "notro-loader";
const { entry } = Astro.props;

---
<div class="notro-markdown">
  <NotroContent markdown={entry.data.markdown} />
</div>

Props

interface Props {
  markdown: string;
  linkToPages?: Record<string, { url: string; title: string }>;
  classMap?: Partial<Record<ClassMapKeys, string>>;
  components?: Partial<NotionComponents>;
}

markdown (required)

The preprocessed markdown string from the Content Collection entry. This is the value stored under entry.data.markdown by the loader.

<NotroContent markdown={entry.data.markdown} />

linkToPages

A map from Notion page UUID to { url, title } for resolving internal Notion page links. When a Notion page contains a link to another Notion page, NotroContent replaces the notion.so URL with the corresponding site-relative URL.


---
import { getCollection } from "astro:content";
import { buildLinkToPages } from "notro-loader/utils";

const allPosts = await getCollection("posts");
const linkToPages = buildLinkToPages(allPosts);

---
<NotroContent
  markdown={entry.data.markdown}
  linkToPages={linkToPages}
/>

buildLinkToPages builds the map by iterating over all entries and mapping each entry.id to { url: "/blog/" + entry.data.slug, title: entry.data.title }.

classMap

A partial map of component slots to additional Tailwind class strings. Use this to customize styling without replacing entire components.

<NotroContent
  markdown={entry.data.markdown}
  classMap={{
    callout: "rounded-xl border-2",
    toggle: "my-6",
    codeBlock: "text-sm font-mono",
    table: "w-full",
  }}
/>

Available keys correspond to the notro-ui component slots. Run notro-ui list --installed to see installed components and their class map keys.

components

A partial map of Notion block types to custom Astro components. Merged with the notro defaults — only the keys you provide are overridden.


---
import MyCallout from "./MyCallout.astro";
import MyToggle from "./MyToggle.astro";

---
<NotroContent
  markdown={entry.data.markdown}
  components={{
    callout: MyCallout,
    toggle: MyToggle,
  }}
/>

Component map keys

KeyHTML elementNotion block
callout<callout>Callout
toggle<details>Toggle
columns<columns>Column layout wrapper
column<column>Individual column
video<video>Video embed
table_of_contents<table_of_contents>Table of contents
empty_block<empty-block>Empty block
pre<pre>Code block
img<img>Image
a<a>Link
h1h4<h1><h4>Headings
p<p>Paragraph
blockquote<blockquote>Blockquote
table<table>Table

MDX compilation caching

NotroContent uses compileMdxCached() internally, which caches the compiled MDX module keyed by a hash of the markdown string. Re-renders of the same page within a single build reuse the cached module without re-invoking the MDX compiler.

CSS wrapper

The notro-markdown CSS class is applied to the element wrapping NotroContent's output (by the parent in the template, not by NotroContent itself). This class in notro-theme.css scopes styles for:

  • <pre> / <code> blocks

  • Task list checkboxes

  • Tables

  • Blockquotes

<!-- Apply the wrapper class in your layout -->
<div class="notro-markdown">
  <NotroContent markdown={entry.data.markdown} />
</div>

Type reference

import type { NotionComponents, ClassMapKeys } from "notro-loader";

interface NotroContentProps {
  markdown: string;
  linkToPages?: Record<string, { url: string; title: string }>;
  classMap?: Partial<Record<ClassMapKeys, string>>;
  components?: Partial<NotionComponents>;
}