Vue Notion Renderer

3.0.0 · active · verified Sun Apr 19

Vue-notion is a Vue.js component library designed to render content from Notion pages within a Vue 3 application. It parses Notion's block structure, typically obtained via the Notion API, and translates it into interactive Vue components, enabling developers to display rich text, images, lists, code blocks, and other Notion content types directly in their web apps. The current stable version is 3.0.0, released recently to target lower ES features for broader browser and environment compatibility. While there isn't a strict, regular release cadence, the project receives updates to introduce new features and fix bugs, as evidenced by patches for issues like the `??` operator bug in earlier versions and fixes for empty table rows. Key differentiators include its tight integration with Vue 3's reactivity system, support for custom component overrides via `blockOverrides` to highly customize the rendering of specific Notion block types, and an `imageOptions` API for advanced image handling. It also seamlessly integrates with `@janniks/vue3-katex` for mathematical equation rendering, offering a comprehensive solution for Notion content display.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to import and use the `NotionRenderer` component with mock Notion block data. It includes necessary CSS for KaTeX and sets up a basic Vue 3 application to display rendered content, highlighting various block types including code and equations.

import { createApp, defineComponent, h } from 'vue';
import { NotionRenderer } from 'vue-notion';
import '@janniks/vue3-katex/dist/katex.min.css'; // Essential for math rendering

// Mock Notion block data (in a real app, this would come from Notion API)
const mockNotionBlocks = [
  { id: '1', type: 'paragraph', paragraph: { rich_text: [{ type: 'text', text: { content: 'Welcome to your Notion page rendered in Vue!' } }] } },
  { id: '2', type: 'heading_2', heading_2: { rich_text: [{ type: 'text', text: { content: 'Key Features:' } }] } },
  { id: '3', type: 'bulleted_list_item', bulleted_list_item: { rich_text: [{ type: 'text', text: { content: 'Render various block types (paragraphs, headings, lists)' } }] } },
  { id: '4', type: 'bulleted_list_item', bulleted_list_item: { rich_text: [{ type: 'text', text: { content: 'Support for images and code blocks' } }] } },
  { id: '5', type: 'code', code: { rich_text: [{ type: 'text', text: { content: 'function hello() { console.log("Vue-Notion"); }' } }], language: 'javascript' } },
  { id: '6', type: 'equation', equation: { expression: 'x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}' } },
  { id: '7', type: 'image', image: { type: 'external', external: { url: 'https://picsum.photos/id/237/200/100' } } },
  { id: '8', type: 'paragraph', paragraph: { rich_text: [{ type: 'text', text: { content: 'Remember to fetch actual Notion data from their API and pass it to the renderer.' } }] } }
];

const App = defineComponent({
  components: { NotionRenderer },
  data() {
    return {
      notionPageBlocks: mockNotionBlocks
    };
  },
  template: `
    <div id="app" style="font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px;">
      <h1>My Notioned Blog Post</h1>
      <NotionRenderer :blockMap="notionPageBlocks" fullPage />
    </div>
  `,
});

createApp(App).mount('#app');

view raw JSON →