On this page
· 2 min read
Overview
This example is a static site built from @pagesmith/site: no React, Solid, or Svelte, and no pagesmithContent Vite plugin. You define collections with defineCollection / defineConfig, construct a layer with createContentLayer, load entries with layer.getCollection(...), and turn Markdown into HTML with await entry.render() (the same markdown pipeline other examples use — this path does not call processMarkdown directly in app code).
End-to-end flow
- Vite loads
vite.config.ts:sharedAssetsPlugin()pluspagesmithSsg({ entry: './src/entry-server.tsx', contentDirs: ['./content'] }). - SSG imports the entry module and calls
getRoutes(renderConfig)to enumerate URLs, thenrender(url, renderConfig)per route. Those two exports are the contractpagesmithSsgexpects. - Content — Inside
render, this example’sloadSite()builds a content layer forconfig.root, fetches each collection, and pre-renders Markdown viarenderEntries()→entry.render()so layout code receiveshtml,headings, andreadTime. - Shell — Layout is JSX from
@pagesmith/site/jsx-runtime, converted to strings and wrapped byrenderDocument()(full HTML document including CSS/JS links and optional Pagefind markup). - Browser —
client.jsimports bundled CSS andsrc/runtime.tsfor TOC, sidebar modal, theme persistence, and search UI affordances.
See content/guide/build-and-deploy.md for build output paths and dev commands.
How it differs from framework examples
The React example wires three plugins:
plugins: [ sharedAssetsPlugin(), pagesmithContent({ collections }), ...pagesmithSsg({ entry: "./src/entry-server.tsx", contentDirs: ["./content"] }),];This example uses two — no pagesmithContent:
plugins: [ sharedAssetsPlugin(), ...pagesmithSsg({ entry: "./src/entry-server.tsx", contentDirs: ["./content"] }),];Framework-style (pagesmithContent) |
Direct API (this example) |
|---|---|
Collections often live in content.config.ts and load through virtual modules |
Collections are defined in src/content.ts alongside createContentLayer |
| Bundler imports typed collection modules | Node-side getCollection + entry.render() at SSG time |
| Same markdown pipeline once content is loaded | Same pipeline via entry.render() |
Why use this approach?
- No framework —
@pagesmith/site/jsx-runtimeSSRs static HTML; no hydration model. - Explicit data flow — You choose when to call
getCollection, how to sort, and how to map entries to routes. - Smaller plugin surface — Fewer moving parts in Vite; trade-off is more entry-file code than virtual imports.