JSPM

@cogita/plugin-posts-frontmatter

0.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q21005F
  • License MIT

Core plugin that automatically scans posts and extracts frontmatter data for Cogita themes.

Package Exports

  • @cogita/plugin-posts-frontmatter
  • @cogita/plugin-posts-frontmatter/client

Readme

@cogita/plugin-posts-frontmatter

npm version TypeScript

中文 | English

Core plugin that automatically scans posts and extracts frontmatter data for Cogita themes.

What is it?

This plugin automatically scans your posts/ directory, extracts frontmatter from Markdown files, and makes the data available to themes through a virtual module. It's the foundation for blog post lists, archives, and other content-driven features.

Installation

pnpm add @cogita/plugin-posts-frontmatter

Note: In the Cogita framework, this plugin is automatically included by themes that need it (like @cogita/theme-lucid). Manual installation is typically not required.

How It Works

  1. Scans all .md and .mdx files in the posts directory
  2. Extracts frontmatter metadata from each file
  3. Generates routes for each post
  4. Creates a virtual module with all posts data
  5. Provides data to themes via virtual-posts-data

Usage

Simply use a compatible Cogita theme:

// cogita.config.ts
import { defineConfig } from '@cogita/core';

export default defineConfig({
  theme: 'lucid', // Theme automatically loads this plugin
});

Manual Configuration (Advanced)

For custom setups or Rspress projects:

import { defineConfig } from '@rspress/core';
import { pluginPostsFrontmatter } from '@cogita/plugin-posts-frontmatter';

export default defineConfig({
  plugins: [
    (config) => pluginPostsFrontmatter({
      ...config,
      postsDir: 'posts',
      routePrefix: 'posts',
      cwd: process.cwd(),
    })
  ],
});

Virtual Module

The plugin creates virtual-posts-data module:

// Available in theme components
import { allPosts } from 'virtual-posts-data';

function BlogHome() {
  const recentPosts = allPosts.slice(0, 5);
  
  return (
    <div>
      {recentPosts.map(post => (
        <article key={post.url}>
          <h2>{post.title}</h2>
          <time>{post.createDate}</time>
          <p>{post.description}</p>
        </article>
      ))}
    </div>
  );
}

Post Format

Frontmatter Example

---
title: "Your Post Title"
description: "Brief description for SEO and sharing"
createDate: "2024-01-01"
updateDate: "2024-01-15"
tags: ["tag1", "tag2"]
categories: ["category1"]
author: "Author Name"
draft: false
featured: true
---

# Your post content starts here

Write your Markdown content...

Supported Fields

Field Type Description Default
title string Post title Filename
description string Post description -
createDate string Creation date (YYYY-MM-DD) File creation time
updateDate string Last update date File modification time
tags string[] Post tags -
categories string[] Post categories -
author string Author name -
draft boolean Draft status false
featured boolean Featured post false

Date Formats

Supports various date formats:

# Recommended
createDate: "2024-01-01"
createDate: "2024-01-01T10:30:00Z"

# Also supported
date: "2024-01-01"          # Alias for createDate
createDate: "Jan 1, 2024"
createDate: "2024/01/01"

Configuration

Plugin Options

interface PluginConfig {
  postsDir?: string;        // Posts directory (default: 'posts')
  routePrefix?: string;     // Route prefix (default: 'posts')
  cwd?: string;            // Project root directory
  sortBy?: string;         // Sort field (default: 'createDate')
  sortOrder?: string;      // Sort order (default: 'desc')
}

Directory Structure

posts/
├── hello-world.md        → /posts/hello-world
├── 2024/
│   └── new-year.md      → /posts/2024/new-year
└── tech/
    └── react-tips.md    → /posts/tech/react-tips

Data Structure

PostFrontmatter Interface

interface PostFrontmatter {
  title: string;
  description?: string;
  filePath: string;         // Absolute file path
  route: string;           // Route path (e.g., '/posts/hello-world')
  url: string;             // Same as route (compatibility)
  createDate: string;      // ISO date string
  updateDate: string;      // ISO date string
  tags?: string[];
  categories?: string[];
  [key: string]: any;      // Additional frontmatter fields
}

TypeScript Support

Add client type definitions:

/// <reference types="@cogita/plugin-posts-frontmatter/client" />

Or in tsconfig.json:

{
  "compilerOptions": {
    "types": ["@cogita/plugin-posts-frontmatter/client"]
  }
}

Customization

Custom Sort Order

// Sort by update date
pluginPostsFrontmatter({
  sortBy: 'updateDate',
  sortOrder: 'desc'
});

Filter Posts

// Custom plugin wrapper
export const myPostsPlugin = (config) => {
  const plugin = pluginPostsFrontmatter(config);
  const originalBeforeBuild = plugin.beforeBuild;
  
  plugin.beforeBuild = async function() {
    await originalBeforeBuild?.call(this);
    // Filter out draft posts in production
    if (process.env.NODE_ENV === 'production') {
      allPosts = allPosts.filter(post => !post.draft);
    }
  };
  
  return plugin;
};

Troubleshooting

Posts Not Showing

Check these common issues:

  1. File location: Ensure files are in posts/ directory
  2. File extension: Use .md or .mdx extensions
  3. Frontmatter format: Valid YAML frontmatter
  4. Draft status: Check if draft: true is set
# Debug: Check posts directory
ls -la posts/

# Debug: Validate frontmatter
head -10 posts/your-post.md

Route Issues

  • Avoid special characters in filenames
  • Use kebab-case for best SEO
  • Check for conflicting routes

Performance

For large numbers of posts:

// Enable caching
export default defineConfig({
  builderConfig: {
    cache: { type: 'filesystem' }
  }
});

Development

# Clone repository
git clone https://github.com/wu9o/cogita.git
cd cogita/plugins/posts-frontmatter

# Install dependencies
pnpm install

# Build plugin
pnpm build

# Run tests
pnpm test

Learn More

License

MIT © wu9o