---
title: Notion
description: >-
  Importiere eine Notion-Datenbank mit der Quelle notion() – Zeilen werden zu Seiten, Eigenschaften zu Frontmatter und Blöcke zu Blume-Komponenten.
---

Der eingebaute `notion()`-Adapter macht aus einer Notion-Datenbank eine Collection: Jede Zeile wird zu einer Seite, ihre Eigenschaften werden zu Frontmatter und ihr Blockbaum wird zu MDX. Callouts, Toggles, Spalten und Codeblöcke werden den passenden Blume-Komponenten zugeordnet. Der Text, den du in Notion tippst, wird genau so dargestellt, wie du ihn geschrieben hast: Ein `{`, `<` oder Markdown-Zeichen auf einer Seite wird maskiert und nicht als MDX, JSX oder Formatierung interpretiert. Videoblöcke werden zu einem `<YouTube>`-Embed, wenn sie einen YouTube-Link enthalten, und sonst zu einem `<video>`-Player. In beiden Fällen wird die Beschriftung des Blocks zur `<Frame>`-Beschriftung. Ein Link auf eine Videoseite statt auf eine Mediendatei (zum Beispiel eine Vimeo- oder Loom-URL) wird als Build-Warnung gemeldet. Der `<video>`-Player zeigt dann weiterhin auf die Seite und kann sie nicht abspielen. Verlinke so ein Video deshalb lieber im Text. Der Adapter deklariert `@notionhq/client` (v5 oder neuer) als Laufzeitabhängigkeit, und zwar als optionale Peer-Dependency. Blume liest die Datenbank über ihre erste Datenquelle.

```ts blume.config.ts
import { defineConfig } from "blume";
import { filesystem, notion } from "blume/sources";

export default defineConfig({
  content: {
    sources: [
      filesystem({ root: "docs" }),
      notion({
        prefix: "handbook",
        database: "8f2c1e0a4b7d4f3c9e6a5d2b1c0f9e8d", // the id in the database URL
        // Property names default to the title-typed prop / Description / Slug / Order / Status
        // Pages whose Status isn't publishedValue (default "Published") import as drafts
        publishedValue: "Done",
      }),
    ],
  },
});
```

Das Integrations-Token kommt aus der Umgebungsvariable `NOTION_TOKEN`. Teile die Datenbank dafür mit deiner Integration. Der Adapter deklariert die Variable, deshalb gibt ein Build ohne sie eine Warnung aus.

Die Eigenschaft `Status` steuert standardmäßig, ob eine Seite veröffentlicht wird. Hat der Status einer Seite (eine Status- oder Select-Eigenschaft) einen anderen Wert als `publishedValue`, wird sie mit `draft: true` importiert. Der Standardwert von `publishedValue` ist `Published`. Produktions-Builds lassen Entwürfe weg. Eine Seite ohne Status-Wert wird veröffentlicht, und in einer Datenbank ohne diese Eigenschaft wird jede Seite veröffentlicht. Die Standard-Statusoptionen von Notion sind Not started, In progress und Done. Eine Datenbank mit diesen Optionen hat also keinen Wert `Published` und veröffentlicht nichts, bis du `publishedValue: "Done"` setzt (oder die Option, die bei dir für „veröffentlicht“ steht). Heißt die Eigenschaft bei dir anders, gib ihren Namen mit `properties.status` an. Wenn du jede Seite unabhängig von ihrem Status importieren willst, lass `properties.status` auf eine Eigenschaft zeigen, die es in der Datenbank nicht gibt.

**Bild- und Video-URLs von Notion sind signiert und laufen ab.** Deshalb lädt der Adapter die Dateien beim Build in die Assets deiner Site herunter und schreibt die Verweise um. So kann ein CMS-Asset in einem statischen Build nie verfallen. Gespeichert wird nur eine Datei, die der Server als Bild oder Video meldet. Macht die Antwort dazu keine Angabe, zählt die Dateiendung in der URL: Sie muss auf ein Bild oder Video hinweisen. Alles andere behält seine ursprüngliche URL und löst eine Build-Warnung aus. So wird vom Origin deiner Site nie etwas anderes als Medien ausgeliefert. API-Aufrufe laufen über einen kleinen Request-Pool mit 3 gleichzeitigen Anfragen, passend zum Rate Limit, das Notion pro Integration setzt. So lassen sich auch Datenbanken mit Hunderten von Seiten importieren, ohne `429`-Antworten auszulösen. Mit `concurrency` an der Quelle kannst du den Wert anpassen.
