Nuxt
Comark Content fits Nuxt's server/client split naturally: the Content instance lives in server/, a single catch-all route exposes it under /api/content, and pages read it through the browser client with useAsyncData.
Install the packages
pnpm add comark-content @comark/vuenpm install comark-content @comark/vueyarn add comark-content @comark/vuebun add comark-content @comark/vueCreate the Content instance
The instance lives on the server, next to your Nitro routes:
import { comarkContent } from 'comark-content'
import fs from 'comark-content/sources/fs'
export const content = comarkContent({
source: fs('./content'),
})Mount the handler
A catch-all API route forwards the h3 event to content.handler() as a web-standard Request:
// defineEventHandler, content and toWebRequest are auto-imported
export default defineEventHandler((event) => content.handler(toWebRequest(event)))Create the client
Expose a shared createContentClient() as a composable. Passing Nuxt's $fetch means data fetched during SSR is hydrated on the client without a refetch:
import { createContentClient } from 'comark-content/client'
export const clientContent = createContentClient({
// Nuxt's $fetch so during SSR we have direct function calling
// Saving additional API call
fetch: $fetch,
})Render a page
Fetch the entry with useAsyncData and hand the page to <MarkdownDocument> from @comark/vue:
<script setup lang="ts">
import { MarkdownDocument } from '@comark/vue'
const { data: page } = await useAsyncData('home', () => clientContent.get('/'))
if (!page.value) {
throw createError({ statusCode: 404, message: 'content not found' })
}
useSeoMeta({
title: () => page.value!.data.title,
description: () => page.value!.data.description,
})
</script>
<template>
<MarkdownDocument :value="page" />
</template>Map Markdown components to your own (Nuxt UI, custom components) through the components prop, read more in Comark's Vue renderer.
Generate source types
Type clientContent.get() from your frontmatter by generating source types, then commit-ignore the output:
npx comark-content preparecontent.ts file, including the ./server/utils/ directory and generate a comark-content.d.ts file.Add comark-content.d.ts to your tsconfig.json include, see Type Safety.
Prerender content pages
If you want to pre-render the content pages when running nuxt build without having to use the nitro.prerender.crawlLinks option, you can import your content instance and use the prerender:routes hook:
import { content } from './server/utils/content'
export default defineNuxtConfig({
hooks: {
'prerender:routes': async (ctx) => {
const pages = await content.list()
for (const page of pages) {
ctx.routes.add(page.path)
}
}
},
})