Skip to content

ryoonwithinwisdomlights/MdxNorkive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

451 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

logo logo

Norkive

Next.js TypeScript React Tailwind CSS TanStack Query License

A type-safe knowledge archive platform that converts Notion content to MDX and deploys as a static Next.js 15 blog

🌐 Live Demo: https://mdx-norkive.vercel.app/
πŸ“¦ Repository: https://github.com/ryoonwithinwisdomlights/MdxNorkive


Overview

Norkive is a modern knowledge management platform that bridges the gap between Notion's intuitive editing experience and a high-performance static blog. It automatically converts Notion databases into type-safe MDX content, optimizes images through Cloudinary CDN, and deploys as a blazing-fast Next.js application with advanced rendering optimizations.

Key Features

  • πŸ”„ Automated Pipeline: Notion β†’ MDX conversion with full metadata preservation
  • πŸ–ΌοΈ Image Optimization: Cloudinary integration with 70% size reduction
  • 🎨 MDX Components: Rich interactive components with Shiki syntax highlighting
  • 🎬 Rich Media Support: YouTube, PDF, Google Drive, Embeds, Bookmarks with custom wrappers
  • πŸ” Advanced Search: Command palette (⌘K) with fuzzy search (Orama)
  • ⚑ Performance: Lighthouse 96/100, < 1s initial load, 89% rendering reduction
  • 🎯 Type Safety: Zod schemas + Content Collections for runtime validation
  • πŸš€ React Optimization: Comprehensive memoization with React.memo, useMemo, useCallback
  • πŸ“± Responsive: Mobile-first design with dark mode support (Zustand)
  • πŸ”„ State Management: TanStack Query for server state, Zustand for client state
  • πŸ›‘οΈ Safe MDX Processing: Advanced link transformation, code block protection, XSS prevention

Tech Stack

  • Framework: Next.js 15 (App Router), React 19
  • Language: TypeScript 5.6 (87.3% of codebase)
  • Styling: Tailwind CSS 4.1
  • Content: MDX + Content Collections + Fumadocs
  • State: TanStack Query (server), Zustand (client)
  • Search: Orama (full-text search engine)
  • Infrastructure: Vercel, Cloudinary, Upstash Redis
  • Quality: ESLint, Prettier, Zod validation

Quick Start

Prerequisites

  • Node.js >= 20.17.0
  • npm/pnpm/yarn

Installation

# Clone the repository
git clone https://github.com/ryoonwithinwisdomlights/MdxNorkive.git
cd MdxNorkive

# Install dependencies
npm install
# or
pnpm install

# Set up environment variables
cp .env.example .env.local

# Run development server
npm run dev

Visit http://localhost:3000

Environment Variables

# Notion API (optional - for MDX conversion)
NOTION_API_KEY=your_notion_integration_token
NOTION_DATABASE_ID=your_database_id

# Cloudinary (for image optimization)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

# Upstash Redis (for caching)
UPSTASH_REDIS_REST_URL=your_redis_url
UPSTASH_REDIS_REST_TOKEN=your_redis_token

# Site configuration
NEXT_PUBLIC_SITE_URL=https://your-domain.com
NEXT_PUBLIC_LANG=kr-KR

Supported Blocks & Components

Norkive provides comprehensive support for Notion blocks through custom MDX components and safe content processing.

Media Blocks

Block Type Component Status Description
YouTube YoutubeWrapper βœ… Supported Lite YouTube embed with lazy loading
Video Native iframe βœ… Supported Generic video embeds
Audio Native audio βœ… Supported HTML5 audio player
Image Next Image βœ… Supported Optimized with Cloudinary
PDF File wrapper βœ… Supported PDF preview and download
Figma EmbededWrapper βœ… Supported Figma design embeds
Google Maps EmbededWrapper βœ… Supported iframe embed

File & Drive Blocks

Block Type Component Status Extensions
PDF Files FileWrapper βœ… Supported .pdf
Documents FileWrapper βœ… Supported .doc, .docx, .rtf, .txt, .md, .odt
Spreadsheets FileWrapper βœ… Supported .xls, .xlsx, .key, .numbers
Presentations FileWrapper βœ… Supported .ppt, .pptx
Google Drive GoogleDriveWrapper βœ… Supported Docs, Sheets, Slides

Link & Embed Blocks

Block Type Component Status Features
Bookmark BookMarkWrapper βœ… Supported Rich link preview with metadata
Embed EmbededWrapper βœ… Supported Generic iframe embeds
External Link Custom component βœ… Supported SEO-friendly external links
Page Link Native link βœ… Supported Internal page navigation

Content Blocks

Block Type Status Features
Heading βœ… Supported H1-H6 with TOC support
Paragraph βœ… Supported Rich text formatting
Quote / Callout βœ… Supported Fumadocs callout components
Code Block βœ… Supported Shiki syntax highlighting
Inline Code βœ… Supported Monospace formatting
Lists βœ… Supported Ordered, unordered, task lists
Tables βœ… Supported Responsive tables
Divider βœ… Supported Horizontal rules

Advanced MDX Processing

Norkive implements sophisticated MDX transformation pipeline for safe and robust content processing:

πŸ”— Link Transformation

# YouTube
[video](https://www.youtube.com/watch?v=xxx) β†’ <YoutubeWrapper />

# Files
[document.pdf](url) β†’ <FileWrapper />

# Google Drive
[My Doc](drive.google.com/...) β†’ <GoogleDriveWrapper />

# Embeds
[embed](url) β†’ <EmbededWrapper />

# Bookmarks
[bookmark](url) β†’ <BookMarkWrapper />

πŸ›‘οΈ Safety Features

  • XSS Prevention: Strict HTML tag whitelist
  • Code Block Protection: Prevents transformation of code content
  • Blockquote Protection: Preserves nested quotes
  • Nested Link Fixing: Handles complex link structures
  • Invalid HTML Cleaning: Removes unsafe attributes

⚑ Processing Pipeline

  1. Link Detection: Regex pattern matching
  2. Component Transformation: Markdown β†’ JSX components
  3. Code Protection: Preserve code blocks and quotes
  4. Safety Validation: XSS prevention
  5. Error Handling: Graceful degradation

Custom Component Architecture

All media components follow a consistent wrapper pattern:

// YoutubeWrapper.tsx
export default function YoutubeWrapper({ urls, names }: WrapperProps) {
  const youtubeId = getYoutubeId(urls);
  return <LiteYouTubeEmbed id={youtubeId} />;
}

// FileWrapper.tsx
export default function FileWrapper({ urls, names }: WrapperProps) {
  return (
    <a href={urls} download>
      <FileTextIcon /> {names}
    </a>
  );
}

Key Benefits:

  • ✨ Consistent API across all wrappers
  • πŸ”’ Type-safe with TypeScript
  • 🎨 Styled with Tailwind CSS
  • β™Ώ Accessible with ARIA labels
  • πŸ“± Responsive design
  • πŸŒ™ Dark mode support

Content Processing Pipeline

Notion MDX β†’ Link Detection β†’ Component Transform β†’ 
Code Protection β†’ Safety Validation β†’ Final MDX

Processing Types:

  • Functional Pipeline: Pure functions, pipe composition
  • Plugin Architecture: Modular transformation steps
  • Class-based: Object-oriented transformer pattern

See content-functional.ts for implementation details.


Usage

Adding Content

Option A: Using Notion (Recommended)

  1. Create content in your Notion database
  2. Run the conversion script:
    npm run generate:mdx
  3. MDX files are automatically generated in content/ directory

Option B: Direct MDX

Create a file in content/records/my-post.mdx:

---
notionId: "unique-id"
title: "My Post Title"
date: 2025-01-15
category: "Engineering"
tags: ["Next.js", "TypeScript"]
---

# Your content here

This is a paragraph with **bold** and *italic* text.

\`\`\`typescript
const example = "code block";
\`\`\`

Available Commands

npm run dev              # Start development server
npm run build            # Production build
npm start                # Start production server
npm run lint             # Run ESLint
npm run validate:mdx     # Validate MDX files
npm run prettier:write   # Format code
npm run analyze          # Analyze bundle size
npm run check:validity   # Run validity checks and tests

Documentation


Project Structure

norkive/
β”œβ”€β”€ app/                    # Next.js App Router
β”‚   β”œβ”€β”€ (home)/            # Home page
β”‚   β”œβ”€β”€ api/               # API routes
β”‚   β”œβ”€β”€ book/              # Book category
β”‚   β”œβ”€β”€ engineering/       # Engineering posts
β”‚   β”œβ”€β”€ project/           # Project showcase
β”‚   └── records/           # Personal records
β”œβ”€β”€ content/               # MDX content files
β”‚   β”œβ”€β”€ books/
β”‚   β”œβ”€β”€ engineerings/
β”‚   β”œβ”€β”€ projects/
β”‚   └── records/
β”œβ”€β”€ lib/                   # Utilities & libraries
β”‚   β”œβ”€β”€ cache/            # Caching system
β”‚   β”œβ”€β”€ context/          # React contexts
β”‚   β”œβ”€β”€ hooks/            # Custom hooks
β”‚   β”œβ”€β”€ stores/           # Zustand stores
β”‚   └── utils/            # Helper functions
β”œβ”€β”€ modules/               # UI components
β”‚   β”œβ”€β”€ common/           # Shared components
β”‚   β”œβ”€β”€ layout/           # Layout components
β”‚   β”œβ”€β”€ mdx/              # MDX components
β”‚   └── page/             # Page components (memoized)
β”œβ”€β”€ scripts/              # Build & conversion scripts
└── types/                # TypeScript definitions

Performance

Lighthouse Scores

Performance:     96/100 ⚑
Accessibility:   98/100 β™Ώ
Best Practices: 100/100 βœ…
SEO:            100/100 πŸ”

Core Web Vitals

Metric Score Target Status
LCP 1.2s < 2.5s βœ…
FID 12ms < 100ms βœ…
CLS 0.02 < 0.1 βœ…

Rendering Optimization

  • React.memo: Applied to 6+ list item components
  • useMemo: Complex calculations and filtering cached
  • useCallback: Event handlers stabilized
  • Result: 89% reduction in unnecessary re-renders

See PERFORMANCE.md for detailed optimization strategies.


Key Technical Decisions

Why MDX over Direct Notion Rendering?

  • Performance: Static generation vs. runtime API calls (60% faster)
  • SEO: Complete HTML for crawlers (100% indexing)
  • Customization: Full control over React components
  • Reliability: No dependency on Notion API availability

Why TanStack Query + Zustand?

  • TanStack Query: Automatic caching, revalidation, and server state management
  • Zustand: Simple, performant client state (replaces complex Context)
  • Separation of Concerns: Server state vs client state

Why Comprehensive Memoization?

  • Large Lists: 100+ items in records list
  • Complex Filtering: Multi-criteria filtering and sorting
  • Performance Goal: <100ms interaction response time
  • Result: 89% rendering reduction achieved

See ARCHITECTURE.md for detailed analysis.


Benchmarks

Migration Results

Metric Before (react-notion-x) After (MDX) Improvement
Initial Load 2.5s 1.0s ↓ 60%
Bundle Size 2.3MB 890KB ↓ 61%
Build Time 3m+ 45s ↓ 75%
Lighthouse 60 96 ↑ 60%
Component Renders 112 12 ↓ 89%

Rendering Optimization

Component Before After Improvement
DateSortedRecords 100 renders 10 renders ↓ 90%
LatestRecords 3 renders 1 render ↓ 67%
FeaturedRecords Optimized Optimized βœ…
EntireRecords Optimized Optimized βœ…

Roadmap

v1.1 (Q1 2025)

  • Service Worker & PWA support
  • React memoization optimization
  • RSS/Atom feeds
  • Comment system (Giscus)

v2.0 (Q2 2025)

  • Full i18n support (Korean/English)
  • Web-based MDX editor
  • Analytics dashboard
  • Advanced search filters

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Development Setup

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Run tests: npm run check:validity
  5. Commit: git commit -m 'feat: add new feature'
  6. Push: git push origin feature/my-feature
  7. Open a Pull Request

License

This project is licensed under the MIT License.


Author

Ryoon with Wisdom Lights


πŸ“¦ Published npm Packages

This project includes reusable packages published to npm:

@norkive/mdx-ui

npm version

MDX UI components for rendering content in browsers. Includes YouTube embeds, file links, bookmarks, Google Drive links, and embedded content.

npm install @norkive/mdx-ui
import { getYoutubeId, LiteYouTubeEmbed, YoutubeWrapper } from '@norkive/mdx-ui';
import '@norkive/mdx-ui/styles.css';

const id = getYoutubeId('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
// 'dQw4w9WgXcQ'

Features:

  • βœ… YouTube embeds with lazy loading
  • βœ… File, Google Drive, Bookmark wrappers
  • βœ… YouTube URL utilities
  • βœ… TypeScript Support
  • βœ… Zero dependencies (peer dependencies only)

πŸ“– Full Documentation

Note: @norkive/youtube-utils and @norkive/lite-youtube-embed have been merged into @norkive/mdx-ui. See migration guide.

More Packages Coming Soon

  • @norkive/mdx-safe-processor - Safe MDX content processor
  • @norkive/mdx-validator - MDX file validator
  • @norkive/image-optimizer - Image optimization utilities

See packages-guide for more information.


Acknowledgments

Built with these amazing open-source projects:


⭐ If you find this project helpful, please consider giving it a star!

Made with ❀️ by Ryoon with Wisdom Lights

About

Norkive- Notion based archive - is a static blogging platform based on Next.js 15 + Typescript, serving Notion content converted to type-safe MDX content with Fumadocs

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors