Skip to content

import — notion

Notion

Functions

importNotion

function importNotion(dir: string, name?: string): ImportResult
TypeScript

Use importNotion to convert a Notion export folder into structured, MDX-ready documentation that skrypt can publish to your doc site.

When you export content from Notion and extract the zip, you're left with a folder of UUID-suffixed Markdown files in a flat, hard-to-use structure. Reach for importNotion to normalize that mess — stripping UUIDs, transforming Notion-specific callouts and toggles into MDX components, and grouping pages so they're ready to pass to skrypt generate.

The function walks the export directory, discovers page groups, and applies a series of transforms (callouts → MDX <Callout>, toggles → <Accordion>, frontmatter normalization) before returning a structured result you can write to disk or pipe into the rest of the skrypt pipeline.

Parameters

NameTypeRequiredDescription
dirstringYesPath to the extracted Notion export folder — the directory containing UUID-named .md files, not the zip itself.
namestringNoDisplay name for the imported doc set. Appears as the root title in the generated output. Defaults to the folder name if omitted.

Returns

Returns an ImportResult object containing the transformed pages and a stats summary of how many callouts, tabs, code groups, and other Notion elements were converted. Pass result.pages to your output writer to generate MDX files, and inspect result.stats to verify the import caught everything you expected.

Heads up

  • dir must point to the extracted folder, not the .zip Notion gives you — unzip it first.
  • UUID stripping is applied to both filenames and internal links, so cross-page references will break if you rename files before importing.

Example:

const { execSync } = require("child_process");
const fs = require("fs");
const path = require("path");

// --- Inline types (not imported from autodocs) ---

/**
 * @typedef {{ title: string, slug: string, content: string }} ImportedPage
 * @typedef {{ callouts: number, tabs: number, codeGroups: number, steps: number, accordions: number, images: number, other: number }} TransformStats
 * @typedef {{ name: string, pages: ImportedPage[], stats: TransformStats }} ImportResult
 */

// --- Mock implementation of importNotion for a self-contained example ---

function stripUUID(str) {
  return str.replace(/\s[0-9a-f]{32}/gi, "").replace(/-[0-9a-f]{32}/gi, "");
}

function importNotion(dir, name) {
  const resolvedName = name ?? path.basename(dir);
  const pages = [];
  const stats = { callouts: 0, tabs: 0, codeGroups: 0, steps: 0, accordions: 0, images: 0, other: 0 };

  const entries = fs.readdirSync(dir);

  for (const entry of entries) {
    const fullPath = path.join(dir, entry);
    const stat = fs.statSync(fullPath);

    if (stat.isFile() && path.extname(entry) === ".md") {
      const raw = fs.readFileSync(fullPath, "utf-8");

      // Strip Notion UUIDs from the title
      const slug = stripUUID(path.basename(entry, ".md"))
        .toLowerCase()
        .replace(/\s+/g, "-");

      // Transform Notion callouts ("> 💡 ..." → MDX <Callout>)
      const content = raw.replace(/^>\s*(💡|⚠️|ℹ️)\s*/gm, () => {
        stats.callouts++;
        return "<Callout>\n";
      });

      pages.push({ title: stripUUID(path.basename(entry, ".md")), slug, content });
    }
  }

  return { name: resolvedName, pages, stats };
}

// --- Example usage ---

async function main() {
  // Simulate a Notion export folder with UUID-named files
  const exportDir = path.join("/tmp", "notion-export-demo");
  fs.mkdirSync(exportDir, { recursive: true });

  fs.writeFileSync(
    path.join(exportDir, "Getting Started 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d.md"),
    `# Getting Started\n\n> 💡 Install the SDK before proceeding.\n\nRun \`npm install my-sdk\` to begin.\n`
  );

  fs.writeFileSync(
    path.join(exportDir, "Authentication 9f8e7d6c5b4a3210fedcba9876543210.md"),
    `# Authentication\n\nPass your API key in the \`Authorization\` header.\n`
  );

  try {
    const result = importNotion(exportDir, "My API Docs");

    console.log("Import complete:");
    console.log(`  Doc set name : ${result.name}`);
    console.log(`  Pages found  : ${result.pages.length}`);
    console.log(`  Callouts     : ${result.stats.callouts}`);
    console.log("\nPages:");
    for (const page of result.pages) {
      console.log(`  [${page.slug}] ${page.title}`);
    }
  } catch (err) {
    console.error("Import failed:", err.message);
  }
}

main();

// Expected output:
// Import complete:
//   Doc set name : My API Docs
//   Pages found  : 2
//   Callouts     : 1
//
// Pages:
//   [getting-started] Getting Started
//   [authentication] Authentication
TypeScript
Was this helpful?