import type { ComponentType, ReactNode } from 'react' /** * Top-level mkdnsite configuration. * * Can be defined in mkdnsite.config.ts at the project root, * or passed programmatically when creating a handler. */ export interface MkdnSiteConfig { /** Directory containing .md files (default: ./content) */ contentDir: string /** Site metadata */ site: SiteConfig /** Server options (local dev / self-hosted only) */ server: ServerConfig /** Theme and rendering configuration */ theme: ThemeConfig /** Content negotiation options */ negotiation: NegotiationConfig /** Auto-generate /llms.txt */ llmsTxt: LlmsTxtConfig /** Client-side enhancement modules */ client: ClientConfig /** * Preset that configures sensible defaults for common use cases. * Applied before user config — any explicit user setting overrides the preset. * - 'docs': nav + TOC + prev/next (default-like, best for documentation sites) * - 'blog': page title + date + reading time + prev/next, no nav sidebar */ preset?: 'docs' | 'blog' /** Markdown renderer engine (default: 'portable') */ renderer: RendererEngine /** Static files directory for images, videos, etc. */ staticDir?: string /** * Glob patterns to include. Only matching files will be served. * Mutually exclusive with `exclude` — define one or the other, not both. * e.g. ['docs', 'guides/*.md'] */ include?: string[] /** * Glob patterns to exclude. Matching files will not be served. * Mutually exclusive with `include` — define one or the other, not both. * e.g. ['private', '*.draft.md'] */ exclude?: string[] /** GitHub repository source (alternative to local contentDir) */ github?: import('../content/types.ts').GitHubSourceConfig /** MCP (Model Context Protocol) server configuration */ mcp: McpConfig /** Analytics configuration (disabled by default) */ analytics?: AnalyticsConfig /** Content Security Policy configuration */ csp?: CspConfig /** Response caching and CDN header configuration */ cache?: CacheConfig } /** MCP (Model Context Protocol) server configuration */ export interface McpConfig { /** Enable the built-in MCP server (default: true) */ enabled: boolean /** MCP endpoint path (default: '/mcp') */ endpoint?: string } /** Content Security Policy configuration */ export interface CspConfig { /** Enable the Content-Security-Policy header on HTML responses (default: true) */ enabled: boolean /** Additional script-src sources */ extraScriptSrc?: string[] /** Additional style-src sources */ extraStyleSrc?: string[] /** Additional img-src sources */ extraImgSrc?: string[] /** Additional connect-src sources */ extraConnectSrc?: string[] /** Additional font-src sources */ extraFontSrc?: string[] /** Report URI for CSP violation reports */ reportUri?: string } /** Response caching and CDN header configuration */ export interface CacheConfig { /** Enable response caching (default: false — opt-in) */ enabled?: boolean /** Cache-Control max-age in seconds for HTML responses (default: 300) */ maxAge?: number /** Cache-Control max-age in seconds for markdown responses (default: 300) */ maxAgeMarkdown?: number /** stale-while-revalidate in seconds (default: 0, meaning omitted) */ staleWhileRevalidate?: number /** Version tag for ETag and CDN cache busting (e.g. 'v1.2.3' or git SHA) */ versionTag?: string } /** Analytics configuration */ export interface AnalyticsConfig { /** Google Analytics 4 (GA4) configuration */ googleAnalytics?: { /** GA4 measurement ID, e.g. 'G-XXXXXXXXXX' */ measurementId: string } /** Server-side traffic analytics (default: disabled) */ traffic?: TrafficAnalyticsConfig } /** Server-side traffic analytics configuration */ export interface TrafficAnalyticsConfig { /** * Enable server-side traffic analytics. * When false (default) the analytics hook is skipped entirely. */ enabled?: boolean /** * Log each request as a JSON line to stdout. * Useful for development / debugging. Requires enabled: true. */ console?: boolean } /** OpenGraph / social sharing meta tag configuration */ export interface OgConfig { /** Default OG image URL (can be overridden per-page via frontmatter `og_image`) */ image?: string /** Default OG type (default: 'website' for index, 'article' for other pages) */ type?: string /** Twitter card type: 'summary' or 'summary_large_image' (default: 'summary') */ twitterCard?: 'summary' | 'summary_large_image' /** Twitter @handle for the site (e.g. '@mkdnsite') */ twitterSite?: string } /** Favicon configuration */ export interface FaviconConfig { /** Path or URL to the favicon file (.ico, .png, .svg) */ src: string } export interface SiteConfig { title: string description?: string url?: string lang?: string /** OpenGraph / social sharing meta tag configuration */ og?: OgConfig /** Favicon configuration */ favicon?: FaviconConfig } export interface ServerConfig { port: number hostname: string } /** CSS color token overrides for the built-in theme */ export interface ColorTokens { /** Primary accent color (links, highlights) */ accent?: string /** Main text color */ text?: string /** Muted text color */ textMuted?: string /** Page background color */ bg?: string /** Alternate background (nav, code blocks) */ bgAlt?: string /** Border color */ border?: string /** Link color */ link?: string /** Link hover color */ linkHover?: string /** Inline code background */ codeBg?: string /** Code block (pre) background */ preBg?: string } /** Font stack overrides for the built-in theme */ export interface FontTokens { /** Body/prose font stack */ body?: string /** Monospace font stack */ mono?: string /** Heading font stack (defaults to body font) */ heading?: string } /** Logo image configuration */ export interface LogoConfig { /** Path or URL to the logo image */ src: string /** Alt text for the logo image */ alt?: string /** Logo display width in pixels (default: 32) */ width?: number /** Logo display height in pixels (default: 32) */ height?: number } export interface ThemeConfig { /** * Rendering mode for markdown content. * - 'prose': Uses @tailwindcss/typography prose classes (default) * - 'components': Full custom React component overrides per element */ mode: 'prose' | 'components' /** Custom React components to override default element rendering */ components?: ComponentOverrides /** * Inline CSS string appended after the built-in theme styles. * Use this for small tweaks. For full replacement, set builtinCss: false. */ customCss?: string /** URL to an external stylesheet loaded via */ customCssUrl?: string /** * Include the built-in theme CSS. Set to false to strip all default * styles and start from a blank slate. (default: true) */ builtinCss?: boolean /** Light mode CSS color token overrides */ colors?: ColorTokens /** Dark mode CSS color token overrides */ colorsDark?: ColorTokens /** Font stack overrides */ fonts?: FontTokens /** Logo image displayed in the nav header */ logo?: LogoConfig /** Site name / text logo displayed in the nav header */ logoText?: string /** Render page title from frontmatter as