Nitro
Set up Comark Content in a standalone Nitro server.
Nitro is the thinnest server home for the Content instance: one instance, one catch-all route, and every other route or task can read content in-process.
Install the package
pnpm add comark-contentnpm install comark-contentyarn add comark-contentbun add comark-contentCreate the Content instance
As Nitro builds the server in production, we want to leverage Nitro server assets to add the content/ directory to the server bundle.
server/content.ts
import { comarkContent } from 'comark-content'
import unstorage from 'comark-content/sources/unstorage'
export const content = comarkContent({
source: unstorage({ driver: useStorage('assets/content') }),
cache: import.meta.env.DEV ? false : { driver: useStorage('cache') },
})Note that we also leverage Nitro cache to cache content in production.
Make sure to set the content dir in your Nitro config:
nitro.config.ts
import { defineConfig } from 'nitro'
export default defineConfig({
serverAssets: [{ baseName: 'content', dir: 'content' }],
})Mount the handler
A catch-all route converts the h3 event to a web-standard Request and forwards it to content.handler():
server/routes/api/content/[...path].ts
import { defineHandler } from 'nitro'
import { content } from '../../content'
export default defineHandler((event) => content.handler(event.request))That's the whole data surface: GET /api/content/get/<path>, /api/content/list/..., /api/content/navigation, plus any custom serve handlers you register.
Read content from other routes
Other routes skip HTTP and call the instance directly:
server/routes/[...slug].ts
import { defineHandler, HTTPError } from 'nitro'
import { content } from '../content'
export default defineHandler(async (event) => {
const page = await content.get(event.path)
if (!page) throw new HTTPError({ status: 404, message: 'Page not found' })
return page
})