name: notion-to-blog description: Transfer a blog post from Notion to the Wasp blog. Fetches content, downloads and optimizes images, and creates a properly formatted MDX file. argument-hint: "[notion-page-url]"
Transfer a Notion page to the Wasp blog
Given a Notion page URL, convert it into an MDX blog post for the Wasp website at web/blog/.
Step 1: Fetch the Notion page
- Extract the page ID from the URL (the UUID at the end, formatted with dashes:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). - Use
mcp__notion__API-retrieve-a-pageto get page metadata (title, properties). - Use
mcp__notion__API-get-block-childrento fetch all content blocks. Notion paginates at 100 blocks — checkhas_moreandnext_cursorto fetch all pages.
Step 2: Parse the content
The Notion page may contain WIP/working notes before and after the actual blog post. Ask the user where the actual post starts and ends if unclear. Typically:
- The post starts at the first
heading_1block - WIP sections are often marked with a
## WIPheading or appear after adividernear the end
Use a Python script (via Bash) to parse the JSON block data because it can be very large (50K+ tokens). The script should:
- Extract blocks in the post range
- Convert each block to markdown based on its type:
heading_1/2/3→# / ## / ###paragraph→ plain text with formattingbulleted_list_item→-numbered_list_item→1.code→ fenced code block with languageimage→ collect URL and captionquote→>callout→> {emoji}divider→---table_of_contents→ skip (Docusaurus handles this)
- Preserve rich text formatting: bold (
**), italic (*), code (`), strikethrough (~~), links ([text](url)) - Collect all image URLs and captions separately
Step 3: Download and optimize images
- Create directory:
web/static/img/<post-slug>/ - Download all images using
curl(Notion URLs are temporary signed S3 URLs — download immediately). - Give images descriptive names based on their context/caption.
- Convert all images to WebP using
cwebp -q 85for smaller file sizes. - Remove the original files after conversion.
Step 4: Create the MDX file
Create web/blog/YYYY-MM-DD-<slug>.mdx following these conventions:
Frontmatter:
---
title: "Post Title"
authors: [authorHandle] # from web/blog/authors.yml
image: /img/<post-slug>/banner.webp
tags: [wasp, tag2, tag3] # 3-6 lowercase tags
keywords: ["keyword1", "keyword2", ...] # 10+ for SEO
description: "SEO summary under 160 chars."
---
Content rules:
- Add
import { ImgWithCaption } from './components/ImgWithCaption';after frontmatter - Add
{/* truncate */}after the opening hook paragraph (this controls the blog listing excerpt) - Use
<ImgWithCaption source="..." caption="..." alt="..." />for ALL images. Omitcaptionprop if there's no caption. When a caption contains double quotes, use single quotes for the prop value instead:caption='text with "quotes" in it' - Make ALL URLs pointing to wasp.sh or wasp-lang.dev relative (e.g.,
https://wasp.sh/blog/...→/blog/...,https://wasp.sh/docs/...→/docs/...,https://wasp-lang.dev/docs/...→/docs/...). This applies to both markdown links and any other references throughout the entire post. - Keep external URLs (GitHub, Twitter, etc.) as-is
Step 5: Verify with the user
Show a summary of what was created:
- File path
- Number of images downloaded and total size savings from WebP conversion
- Any decisions made (title choice, skipped sections, etc.)
- Remind user to review anchor links in TL;DR sections