Architecture Overview

Ptero is built on a modular architecture that integrates deeply with SvelteKit while maintaining flexibility and extensibility. This guide explains how the pieces fit together.

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Your SvelteKit App                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  ptero-        │────│  UI components          β”‚ β”‚
β”‚  β”‚  core          β”‚    β”‚  (added via CLI)        β”‚ β”‚
β”‚  β”‚                β”‚    β”‚                         β”‚ β”‚
β”‚  β”‚ - Content      β”‚    β”‚ - Layout primitives     β”‚ β”‚
β”‚  β”‚ - Navigation   β”‚    β”‚ - UI elements           β”‚ β”‚
β”‚  β”‚ - Search       β”‚    β”‚ - Styles                β”‚ β”‚
β”‚  β”‚ - Versioning   β”‚    β”‚                         β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚           β”‚                      β”‚                  β”‚
β”‚           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β”‚                      β”‚                              β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚
β”‚              β”‚   MDsveX       β”‚                     β”‚
β”‚              β”‚   + Shiki      β”‚                     β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                     β”‚
β”‚                      β”‚                              β”‚
β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚
β”‚              β”‚  Markdown      β”‚                     β”‚
β”‚              β”‚  Content       β”‚                     β”‚
β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Core Packages

Bundled Core

Ptero ships its content/navigation/search logic inside the app (no separate ptero-core install). It provides the fundamental functionality for documentation sites:

Content Management:

  • Parses Markdown files with frontmatter validation
  • Loads and processes documentation content
  • Handles versioned content directories
  • Provides content APIs for SvelteKit routes

Navigation:

  • Generates sidebar navigation from content structure
  • Creates breadcrumb trails
  • Provides prev/next page navigation
  • Supports custom navigation configuration

Search:

  • Builds search indices at compile time
  • Provides search API for client-side querying
  • Supports version-scoped search
  • Uses Fuse.js for fuzzy matching

Versioning:

  • Manages multiple documentation versions
  • Handles version aliases (latest, next, etc.)
  • Routes version-specific content requests

UI Components

Use ptero add <component> to pull prebuilt components into your app (shadcn-style). You can also bring your own layouts and styles; Ptero core is UI-agnostic.

ptero-cli

The CLI package provides tooling for setup and management:

  • ptero init - Initialize Ptero in existing projects
  • ptero version create - Create new documentation versions
  • ptero search build - Build search indices
  • Template scaffolding

Content Processing Pipeline

1. File Discovery

When SvelteKit builds or runs in dev mode, Ptero scans the src/content/docs directory:

src/content/docs/
β”œβ”€β”€ intro/
β”‚   └── getting-started.md
└── guides/
    └── configuration.md

2. Frontmatter Parsing

Each file’s frontmatter is validated using Zod schemas:

import &#123; z &#125; from 'zod';

const FrontmatterSchema = z.object(&#123;
	title: z.string(),
	description: z.string().optional(),
	section: z.string(),
	order: z.number().optional(),
	hidden: z.boolean().optional()
&#125;);

3. MDsveX Processing

Markdown content is processed by MDsveX:

  • Parses Markdown to HTML
  • Processes Svelte components
  • Applies syntax highlighting with Shiki
  • Generates component output

4. Route Generation

SvelteKit’s dynamic routing serves processed content:

/docs/[version]/[...slug]
  ↓
/docs/latest/guides/configuration
  ↓
Loads: src/content/docs/guides/configuration.md

Data Flow

Page Load Sequence

  1. User navigates to /docs/latest/guides/configuration

  2. SvelteKit calls +page.server.ts load function

    export async function load(&#123; params &#125;) &#123;
    	const doc = await loadDoc(params.version, params.slug);
    	return &#123; doc &#125;;
    &#125;
  3. loadDoc retrieves content from core

    • Checks version validity
    • Finds corresponding file
    • Returns parsed frontmatter + component
  4. Page renders with DocsLayout

    • Sidebar shows navigation
    • Content area displays MDsveX component
    • TOC extracts headings
  5. Client-side hydration enables

    • Instant navigation between pages
    • Search functionality
    • Theme switching

Routing Strategy

Ptero uses SvelteKit’s file-based routing with dynamic segments:

src/routes/
└── docs/
    └── [version]/
        β”œβ”€β”€ +layout.svelte          # Applies DocsLayout
        β”œβ”€β”€ +layout.server.ts       # Loads sidebar/config
        β”œβ”€β”€ +page.svelte            # Version index page
        └── [...slug]/
            β”œβ”€β”€ +page.svelte        # Doc page component
            └── +page.server.ts     # Loads doc content

Version Parameter

The [version] parameter supports:

  • Explicit versions: v1.0, v2.0
  • Aliases: latest, next
  • Resolution to actual version folders

Slug Catch-All

The [...slug] parameter captures the full page path:

  • guides/configuration β†’ ['guides', 'configuration']
  • intro/installation β†’ ['intro', 'installation']

Search Implementation

Index Building

Search indices are built at compile time:

  1. Scan all documentation files
  2. Extract searchable content
    • Title
    • Description
    • Headings
    • Body text (stripped of Markdown)
  3. Create Fuse.js index with weights
    &#123;
    	keys: [
    		&#123; name: 'title', weight: 3 &#125;,
    		&#123; name: 'description', weight: 2 &#125;,
    		&#123; name: 'content', weight: 1 &#125;
    	];
    &#125;
  4. Serialize index to JSON

The search component uses the pre-built index:

import Fuse from 'fuse.js';
import searchIndex from '$lib/search-index.json';

const fuse = new Fuse(searchIndex.docs, &#123;
	keys: ['title', 'description', 'content'],
	threshold: 0.3
&#125;);

const results = fuse.search(query);

Theme System

CSS Variables

The theme uses CSS custom properties for customization:

:root &#123;
	--color-primary: #3b82f6;
	--color-background: #ffffff;
	--color-text: #1f2937;
	--font-family-sans: system-ui, sans-serif;
	--font-family-mono: 'Fira Code', monospace;
&#125;

.dark &#123;
	--color-background: #0f172a;
	--color-text: #f1f5f9;
&#125;

Component Slots

Components provide slots for customization:

&lt;DocsLayout&gt;
	&lt;svelte:fragment slot="header"&gt;
		&lt;!-- Custom header content --&gt;
	&lt;/svelte:fragment&gt;

	&lt;svelte:fragment slot="sidebar-top"&gt;
		&lt;!-- Custom sidebar header --&gt;
	&lt;/svelte:fragment&gt;

	&#123;@render children()&#125;
&lt;/DocsLayout&gt;

Build Process

Development Mode

pnpm dev
  ↓
1. Vite starts dev server
2. SvelteKit processes routes
3. MDsveX preprocesses .md files
4. Content APIs load on-demand
5. HMR updates on file changes

Production Build

pnpm build
  ↓
1. SvelteKit builds routes
2. MDsveX processes all .md files
3. Search index is generated
4. Static assets are optimized
5. Client code is minified
6. Output to /build directory

Performance Optimizations

Code Splitting

Each page is code-split automatically:

  • Only load content for current page
  • Lazy load images and heavy components
  • Preload links on hover

Static Generation

Static content is pre-rendered:

  • Sidebar navigation computed at build time
  • Search index built once
  • Markdown processed during build

Client-Side Caching

Loaded content is cached:

  • SvelteKit caches loaded pages
  • Search index loaded once
  • Navigation state preserved

Extension Points

Ptero provides several ways to extend functionality:

Custom Components

Create and use custom Svelte components in docs

Custom Themes

Create themes by implementing the layout interface

Plugins (Planned)

Future plugin system for extending core functionality

MDsveX Plugins

Use remark/rehype plugins for advanced Markdown processing

Next Steps