api


# API Reference

Complete API documentation for MarkoPress.

# Config API

# defineConfig

Define your MarkoPress configuration.

import { defineConfig } from 'markopress';

export default defineConfig({
  site: {
    title: 'My Site',
    description: 'My awesome site',
  },
});

# MarkoPressConfig

Main configuration interface.

interface MarkoPressConfig {
  site: SiteConfig;
  content?: ContentConfig;
  theme?: string | ThemeConfig;
  themeConfig?: ThemeOptions;
  markdown?: MarkdownConfig;
  build?: BuildConfig;
  plugins?: PluginConfig[];
}

# SiteConfig

Site metadata and configuration.

interface SiteConfig {
  // Site title (required)
  title: string;

  // Site description for SEO
  description?: string;

  // Base URL (if deploying to subdirectory)
  base?: string; // Default: '/'

  // Site language
  lang?: string; // Default: 'en-US'

  // Full site URL (for sitemap, canonical URLs)
  url?: string;

  // Logo path
  logo?: string;

  // Favicon path
  favicon?: string;

  // Custom head tags
  head?: HeadTag[];
}

Example:

export default defineConfig({
  site: {
    title: 'My Site',
    description: 'My awesome site built with MarkoPress',
    base: '/',
    lang: 'en-US',
    url: 'https://example.com',
    logo: '/logo.png',
    favicon: '/favicon.ico',
    head: [
      ['link', { rel: 'icon', href: '/favicon.ico' }],
      ['meta', { name: 'theme-color', content: '#667eea' }],
    ],
  },
});

# ContentConfig

Content directory configuration.

interface ContentConfig {
  // Pages directory (→ /route)
  pages?: string; // Default: 'content/pages'

  // Docs directory (→ /guides/route)
  docs?: string; // Default: 'content/docs'

  // Blog directory (→ /blog/route)
  blog?: string; // Default: 'content/blog'

  // Custom content directories
  custom?: Record<div data-marko-tag="0"></div>;

  // Build hooks
  beforeBuild?: (ctx: BuildContext) => void | Promise<div data-marko-tag="1"></div>;
  afterBuild?: (ctx: BuildContext) => void | Promise<div data-marko-tag="2"></div>;

  // Markdown hook
  extendMarkdown?: (md: MarkdownIt) => void | Promise<div data-marko-tag="3"></div>;

  // Route hook
  extendRoutes?: (routes: RouteManifest) => RouteManifest | Promise<RouteManifest>;
}

# PluginContext

Base context provided to all plugin hooks.

interface PluginContext {
  config: ResolvedConfig;
  utils: {
    log: (msg: string) => void;
    warn: (msg: string) => void;
    error: (msg: string) => void;
  };
}

# ContentContext

Context for content loading hook.

interface ContentContext extends PluginContext {
  addPage: (page: PageData) => void;
  addPost: (post: PostData) => void;
  getPages: () => PageData[];
  getPosts: () => PostData[];
}

# BuildContext

Context for build hooks.

interface BuildContext extends PluginContext {
  content: {
    pages: PageData[];
    docs: PageData[];
    blog: PostData[];
  };
  routes: RouteManifest;
}

# PageData

Page data structure.

interface PageData {
  id: string;
  filePath: string;
  routePath: string;
  frontmatter: Record<string, unknown>;
  content: string;
  html: string;
  headers: ProcessedMarkdown['headers'];
  excerpt?: string;
}

# PostData

Blog post data structure (extends PageData).

interface PostData extends PageData {
  date: Date;
  author?: string;
  tags?: string[];
  categories?: string[];
}

# RouteManifest

Generated routes.

interface RouteManifest {
  [path: string]: RouteData;
}

# RouteData

Route data structure.

interface RouteData {
  path: string;
  component?: string;
  layout?: string;
  redirect?: string;
  meta?: Record<string, unknown>;
}

# Content API

# ContentFile

Content file metadata.

interface ContentFile {
  id: string;
  filePath: string;
  relativePath: string;
  type: 'page' | 'doc' | 'blog';
  urlPath: string;
  processed: ProcessedMarkdown;
}

# ContentManifest

All content files.

interface ContentManifest {
  pages: ContentFile[];
  docs: ContentFile[];
  blog: ContentFile[];
  all: ContentFile[];
}

# ProcessedMarkdown

Processed markdown content.

interface ProcessedMarkdown {
  content: string;
  html: string;
  frontmatter: Record<string, unknown>;
  headers: Header[];
  excerpt?: string;
}

Markdown header (heading).

interface Header {
  level: number;
  title: string;
  slug: string;
}

# Theme API

# Theme

Theme interface.

interface Theme {
  name: string;
  layout: string;
  components?: Record<string, string>;
  styles?: string[];
  layouts?: Record<string, string>;
}

# ResolvedTheme

Resolved theme configuration.

interface ResolvedTheme extends Theme {
  path: string;
  options: ThemeOptions;
}

# loadTheme

Load a theme.

function loadTheme(
  theme: string | Theme,
  rootDir: string
): Promise<ResolvedTheme>;

# loadThemeWithOverrides

Load theme with custom overrides.

function loadThemeWithOverrides(
  theme: string | Theme,
  rootDir: string,
  overridesPath: string
): Promise<ResolvedTheme>;

# getLayoutPath

Get path to layout file.

function getLayoutPath(
  theme: ResolvedTheme,
  layout: string
): string;

# getSlotPath

Get path to slot component.

function getSlotPath(
  theme: ResolvedTheme,
  slot: string
): string;

# Utility Types

# HeadTag

HTML head tag.

type HeadTag =
  | [string, Record<string, string>]
  | [string, Record<string, string>, string];

Examples:

// Link tag
['link', { rel: 'icon', href: '/favicon.ico' }]

// Meta tag
['meta', { name: 'description', content: 'My site' }]

// Script tag
['script', { src: '/script.js' }, '']

# ConfigEnv

Configuration environment.

interface ConfigEnv {
  mode: 'development' | 'production';
  command: 'dev' | 'build' | 'preview';
}

# ConfigFn

Configuration function.

type ConfigFn = (env: ConfigEnv) => UserConfig | Promise<UserConfig>;

Example:

export default defineConfig(async (env) => {
  return {
    site: {
      title: env.mode === 'development' ? 'Dev Site' : 'Prod Site',
    },
  };
});

# CLI API

# MarkoPress CLI

Command-line interface commands.

# Start development server
markopress dev

# Build for production
markopress build

# Preview production build
markopress preview

# Create new site
markopress init [directory]

# Dev Server Options

interface DevServerOptions {
  port?: number;    // Default: 4173
  host?: string;    // Default: 'localhost'
  open?: boolean;   // Default: false
}

# Build Options

interface BuildOptions {
  mode?: 'production' | 'development';
  sourcemap?: boolean;
  minify?: boolean;
}

# Environment Variables

# SITE_URL

Full site URL for production.

SITE_URL="https://example.com"

# NODE_ENV

Build mode.

NODE_ENV="production"  # or "development"

# PORT

Dev server port.

PORT=3000

# TypeScript Types

# Importing Types

import type {
  MarkoPressConfig,
  SiteConfig,
  ContentConfig,
  ThemeConfig,
  MarkdownConfig,
  BuildConfig,
  PluginConfig,
  ResolvedConfig,
  UserConfig,
} from 'markopress/config';

import type {
  MarkoPressPlugin,
  PluginContext,
  ContentContext,
  BuildContext,
  PageData,
  PostData,
  RouteManifest,
} from 'markopress/plugin';

import type {
  ContentFile,
  ContentManifest,
  ContentType,
} from 'markopress/content';

import type {
  Theme,
  ResolvedTheme,
  ThemeOptions,
} from 'markopress/theme';

# Examples

# Basic Config

import { defineConfig } from 'markopress';

export default defineConfig({
  site: {
    title: 'My Site',
    description: 'My awesome site',
  },
});

# Complete Config

import { defineConfig } from 'markopress';

export default defineConfig({
  site: {
    title: 'My Site',
    description: 'My awesome site',
    base: '/',
    lang: 'en-US',
    url: 'https://example.com',
    logo: '/logo.png',
    favicon: '/favicon.ico',
  },

  content: {
    pages: 'content/pages',
    docs: 'content/docs',
    blog: 'content/blog',
  },

  theme: '@markopress/theme-default',

  themeConfig: {
    name: 'My Site',
    navbar: [
      { text: 'Home', link: '/' },
      { text: 'Docs', link: '/docs' },
      { text: 'Blog', link: '/blog' },
    ],
    sidebar: {
      '/guides/': [
        {
          text: 'Guide',
          items: [
            { text: 'Intro', link: '/guides/intro' },
            { text: 'Config', link: '/guides/config' },
          ],
        },
      ],
    },
  },

  markdown: {
    lineNumbers: true,
    theme: {
      light: 'github-light',
      dark: 'github-dark',
    },
  },

  build: {
    outDir: 'dist',
    minify: true,
    sourcemap: false,
  },

  plugins: [
    '@markopress/plugin-content-pages',
    '@markopress/plugin-content-docs',
    '@markopress/plugin-content-blog',
  ],
});

# Plugin with Hooks

import type { MarkoPressPlugin, ContentContext } from 'markopress/plugin';

export default function myPlugin(): MarkoPressPlugin {
  return {
    name: 'my-plugin',

    config(config) {
      // Transform config
      config.site.title = 'Modified';
      return config;
    },

    contentLoaded(ctx: ContentContext) {
      // Process content
      const pages = ctx.getPages();
      for (const page of pages) {
        ctx.utils.log(`Processing: ${page.routePath}`);
      }
    },

    async beforeBuild(ctx) {
      ctx.utils.log('Build starting...');
    },

    async afterBuild(ctx) {
      ctx.utils.log('Build complete!');
    },

    extendMarkdown(md) {
      // Add markdown-it plugins
    },

    extendRoutes(routes) {
      // Add custom routes
      return routes;
    },
  };
}

# Next Steps