{"repo":"souvikinator/notion-to-md","free":true,"listed":false,"github":"https://github.com/souvikinator/notion-to-md","clone":"git clone https://github.com/souvikinator/notion-to-md.git","description":"Convert Notion pages, blocks, or entire lists into any format: Markdown, MDX, JSX, HTML, LaTeX, and more. A powerful Notion conversion engine that lets you write once in Notion and publish seamlessly anywhere, in any format. Compatible with your favorite CMS, workflow, static site generator, and beyond.","language":"TypeScript","stars":1728,"topics":["exporter","hacktoberfest","markdown","md","nodejs","notion","notion-api","notion-client","notion-convert","notion-database","notion-export","notion-exporter","notion-markdown","notion-to-anything","notion-to-html","notion-to-md","notion2md"],"license":"MIT","category":"content_exporter","readme_excerpt":"\n\n<!-- \n💡 For better readability and detailed instructions head over to the [wiki](https://github.com/souvikinator/notion-to-md/wiki). \n-->\n<h1 align=\"center\">\n  <br>\n<img src=\"https://i.ibb.co/Pzyf13S/Group-168.png\" alt=\"notion-to-md banner\"  width=\"750\" />\n  <br>\n  <b>Notion-to-MD</b>\n  <br>\n  <sub><sup><b>(Notion to Markdown)</b></sup></sub>\n  <br>\n</h1>\n\n<div align=\"center\" style=\"display: flex; justify-content: center; align-items: center; gap: 20px; flex-wrap: wrap; margin: 20px 0;\">\n  <a href=\"https://notionconvert.com/docs/v4/getting-started?utm_source=github.com&utm_medium=readme\">\n    <img src=\"https://i.ibb.co/WW9zvyhD/Group-98.png\"  height=\"50\" style=\"border-radius: 8px; object-fit: contain;\" />\n  </a>\n  <a href=\"https://discord.gg/drWw5Ya535\">\n    <img src=\"https://i.ibb.co/nsdt7ZV3/Group-99.png\" width=\"140\" height=\"50\" style=\"border-radius: 8px; object-fit: contain;\" />\n  </a>\n  <a href=\"https://www.reddit.com/r/notion_to_md/\">\n    <img src=\"https://i.ibb.co/1Gm9ztvy/Group-87.png\" width=\"140\" height=\"50\" style=\"border-radius: 8px; object-fit: contain;\" />\n  </a>\n</div>\n\n<p align=\"center\">\n       Notion-to-MD is a Node.js package that allows you to convert Notion pages to Markdown format. \n</p>\n<p align=\"center\">\n  Convert notion pages, blocks and list of blocks to markdown (supports nesting) using <a href=\"https://github.com/makenotion/notion-sdk-js\">notion-sdk-js</a>\n</p>\n<p align=\"center\">\n<img src=\"https://img.shields.io/github/stars/souvikinator/notion-to-md?style=flat\" alt=\"github stars\">\n<img src=\"https://img.shields.io/twitter/follow/souvikinator?color=blue&logo=x&style=flat\" alt=\"twitter\" />\n<img src=\"https://komarev.com/ghpvc/?username=notion-to-md&abbreviated=true&label=REPO+VIEWS\" alt=\"repo views\" />\n</p>\n\n## Sponsored\n[![Sponsored by GitAds](https://gitads.dev/v1/ad-serve?source=souvikinator/notion-to-md@github)](https://gitads.dev/v1/ad-track?source=souvikinator/notion-to-md@github)\n\n> [!NOTE]\n> Looking to contribute to v4? Here is the [v4 branch](https://github.com/souvikinator/notion-to-md/tree/v4.0.0-alpha/)\n\n## 🗒️ Recent posts\n\n<!-- feed start -->\n- Apr 23 - [Mastering Media Handling in notion-to-md v4 - Download, Upload, and Direct Strategies](https://notionconvert.com/blog/mastering-media-handling-in-notion-to-md-v4/)\n- Mar 12 - [How to Convert Notion Properties to Frontmatter with notion-to-md v4](https://notionconvert.com/blog/how-to-convert-notion-properties-to-frontmatter/)\n- Mar 12 - [How to Handle Documents in Notion Using notion-to-md v4](https://notionconvert.com/blog/how-to-handle-documents-in-notion-using-notion-to-md-v4/)\n- Mar 11 - [How to Convert Notion Comments to Markdown Footnotes with notion-to-md v4](https://notionconvert.com/blog/how-to-use-notion-comments-as-footnotes-in-markdown/)\n<!-- feed end -->\n\n\n## Looking for Support in Other Languages?\n> If you've created a specific client, please open an issue to have it added here.\n\n- [notion-to-md-py](https://github.com/SwordAndTea/notion-to-md-py) by [@SwordAndTea](https://github.com/SwordAndTea)\n\n## Install\n\n```Bash\nnpm install notion-to-md\n```\n\n## Usage\n> ⚠️ **Note:** Before getting started, create [an integration and find the token](https://www.notion.so/my-integrations).\n>  Details on methods can be found in [API section](https://github.com/souvikinator/notion-to-md#api)\n\n> ⚠️ **Note:** Starting from v2.7.0, `toMarkdownString` no longer automatically saves child pages. \n> Now it provides an object containing the markdown content of child pages.\n\n## converting markdown objects to markdown string\n\nThis is how the notion page looks for this example:\n\n<img src=\"https://imgur.com/O6bKCmH.png\"  width=\"500\"  />\n\n```javascript\nconst { Client } = require(\"@notionhq/client\");\nconst { NotionToMarkdown } = require(\"notion-to-md\");\nconst fs = require('fs');\n// or\n// import {NotionToMarkdown} from \"notion-to-md\";\n\nconst notion = new Client({\n  auth: \"your integration token\",\n});\n\n// passing notion client to the option\nconst n2m = new NotionToMarkdown({ notionClient: notion });\n\n(async () => {\n  const mdblocks = await n2m.pageToMarkdown(\"target_page_id\");\n  const mdString = n2m.toMarkdownString(mdblocks);\n  console.log(mdString.parent);\n})();\n```\n<img src=\"https://imgur.com/XrUYrZ0.png\"  width=\"500\"  />\n\n## Separate child page content\n\n**parent page content:**\n\n<img src=\"https://github.com/souvikinator/notion-to-md/assets/64456160/531ef45d-2dc7-47f4-bbb3-12d6fd44d299\" width=\"500\" />\n\n**child page content:**\n\n<img src=\"https://github.com/souvikinator/notion-to-md/assets/64456160/7dde090b-7333-46f8-b6df-e6c9a7b62fa9\" width=\"500\" />\n\n`NotionToMarkdown` takes second argument, `config`\n\n```javascript\nconst { Client } = require(\"@notionhq/client\");\nconst { NotionToMarkdown } = require(\"notion-to-md\");\nconst fs = require('fs');\n// or\n// import {NotionToMarkdown} from \"notion-to-md\";\n\nconst notion = new Client({\n  auth: \"your integration token\",\n});\n\n// passing notion client to the option\nconst n2m = new NotionToMarkdown({ \n  notionClient: notion,\n    config:{\n     separateChildPage:true, // default: false\n  }\n });\n\n(async () => {\n  const mdblocks = await n2m.pageToMarkdown(\"target_page_id\");\n  const mdString = n2m.toMarkdownString(mdblocks);\n  \n  console.log(mdString);\n})();\n```\n\n**Output:**\n\n`toMarkdownString` returns an object with target page content corresponding to `parent` property and if any child page exists then it's included in the same object.\n\n<img src=\"https://github.com/souvikinator/notion-to-md/assets/64456160/99bcc14e-46e6-4bed-912d-8b9300c214c1\" width=\"500\" />\n\nUser gets to save the content separately.\n\n## Disable child page parsing\n\n```javascript\n...\n\nconst n2m = new NotionToMarkdown({ \n  notionClient: notion,\n    config:{\n     parseChildPages:false, // default: parseChildPages\n  }\n });\n\n...\n```\n\n## converting page to markdown object\n\n**Example notion page:**\n\n<img src=\"https://imgur.com/9iqRpBl.png\"  width=\"500\"  />\n\n```js\nconst { Client } = require(\"@notionhq/client\");\nconst { NotionToMarkdown } = require(\"notion-to-md\");\n\nconst notion = new Client({\n  auth: \"your integration token\",\n});\n\n// passing notion client to the option\nconst n2m = new NotionToMarkdown({ notionClient: notion });\n\n(async () => {\n  // notice second argument, totalPage.\n  const x = await n2m.pageToMarkdown(\"target_page_id\", 2);\n  console.log(x);\n})();\n```\n\n**Output:**\n\n```json\n[\n  {\n    \"parent\": \"# heading 1\",\n    \"children\": []\n  },\n  {\n    \"parent\": \"- bullet 1\",\n    \"children\": [\n      {\n        \"parent\": \"- bullet 1.1\",\n        \"children\": []\n      },\n      {\n        \"parent\": \"- bullet 1.2\",\n        \"children\": []\n      }\n    ]\n  },\n  {\n    \"parent\": \"- bullet 2\",\n    \"children\": []\n  },\n  {\n    \"parent\": \"- [ ] check box 1\",\n    \"children\": [\n      {\n        \"parent\": \"- [x] check box 1.2\",\n        \"children\": []\n      },\n      {\n        \"parent\": \"- [ ] check box 1.3\",\n        \"children\": []\n      }\n    ]\n  },\n  {\n    \"parent\": \"- [ ] checkbox 2\",\n    \"children\": []\n  }\n]\n```\n\n## converting list of blocks to markdown object\n\n```js\nconst { Client } = require(\"@notionhq/client\");\nconst { NotionToMarkdown } = require(\"notion-to-md\");\n\nconst notion = new Client({\n  auth: \"your integration token\",\n});\n\n// passing notion client to the option\nconst n2m = new NotionToMarkdown({ notionClient: notion });\n\n(async () => {\n  // get all blocks in the page\n  const { results } = await notion.blocks.children.list({\n    block_id,\n  });\n\n  //convert to markdown\n  const x = await n2m.blocksToMarkdown(results);\n  console.log(x);\n})();\n```\n\n**Output**: same as before\n\n## Converting a single block to markdown string\n\n- only takes a single notion block and returns corresponding markdown string\n- nesting is ignored\n- depends on @notionhq/client\n\n```js\nconst { NotionToMarkdown } = require(\"notion-to-md\");\n\n// passing notion client to the option\nconst n2m = new NotionToMarkdown({ notionClient: notion });\n\nconst result = n2m.blockToMarkdown(block);\nconsole.log(result);\n```\n\n**result**:\n\n```\n![image](https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif)\n```\n\n## Custom Transformers\n\nYou can define your own custom transformer for a notion type, to parse and return your own string.\n`setCustomTransformer(type, func)` will overload the parsing for the giving type.\n\n```ts\nconst { NotionToMarkdown } = require(\"notion-to-md\");\nconst n2m = new NotionToMarkdown({ notionClient: notion });\nn2m.setCustomTransformer(\"embed\", async (block) => {\n  const { embed } = block as any;\n  if (!embed?.url) return \"\";\n  return `<figure>\n  <iframe src=\"${embed?.url}\"></iframe>\n  <figcaption>${await n2m.blockToMarkdown(embed?.caption)}</figcaption>\n</figure>`;\n});\nconst result = n2m.blockToMarkdown(block);\n// Result will now parse the `embed` type with your custom function.\n```\n\n**Note** Be aware that `setCustomTransformer` will take only the last function for the given type. You can't set two different transforms for the same type.\n\nYou can also use the default parsing by returning `false` in your custom transformer.\n\n```ts\n// ...\nn2m.setCustomTransformer(\"embed\", async (block) => {\n  const { embed } = block as any;\n  if (embed?.url?.includes(\"myspecialurl.com\")) {\n    return `...`; // some special rendering\n  }\n  return false; // use default behavior\n});\nconst result = n2m.blockToMarkdown(block);\n// Result will now only use custom parser if the embed url matches a specific url\n```\n\n## Contribution\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\nPlease make sure to update tests as appropriate.\n\n## Contributers\n\n<a href=\"https://github.com/souvikinator/notion-to-md/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=souvikinator/notion-to-md\" />\n</a>\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n\n<!-- GitAds-Verify: BBBJJTN2GTIQDDAIVDL4L5TCLZMOE84C -->\n","default_branch":"master","files":18,"tree":[".github/FUNDING.yml",".github/workflows/show-blog-post-rss.yaml",".github/workflows/tweet-on-release.yml",".gitignore",".npmignore","CONTRIBUTING.md","LICENSE","README.md","jest.config.js","package.json","src/index.ts","src/notion-to-md.spec.ts","src/notion-to-md.ts","src/types/index.ts","src/utils/md.spec.ts","src/utils/md.ts","src/utils/notion.ts","tsconfig.json"],"storefront":"/r/souvikinator","claimed":false,"request_supported":{"post":"https://gitbuyer.com/r/souvikinator/notion-to-md/request-supported","requests":0},"note":"indexed from public GitHub; nothing is for sale on this page. Clone it from GitHub. Paid listings live at /search."}