How can I load content from a database? #1541
-
Hello everyone! I would like to render some MDC string (coming from a database) on my website, and as a preview also in my dashboard. Here's what I managed to put together after a morning of struggle: This server API endpoint to render the MDC source code into a import {appendHeader, defineEventHandler, isMethod, readBody} from 'h3'
import {parseContent} from '#content/server'
import logger from 'debug'
const debug = logger('website:server:parse')
export default defineEventHandler(async (event) => {
appendHeader(event, 'Access-Control-Allow-Origin', '*');
appendHeader(event, 'Access-Control-Allow-Credentials', 'true');
appendHeader(event, 'Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
appendHeader(event, 'Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept")
if (!isMethod(event, 'POST')) {
debug('The request is not POST!')
return {}
}
const body = await readBody(event)
debug('Received parse request with body: %O', body)
const content = await parseContent(body.id || 'content:_file.md', body.content)
debug('Generated content: %O', content)
return content
}) This plugin in import {defineNuxtPlugin, useFetch, useRouter} from "#imports";
import logger from 'debug';
const debug = logger('website:plugin:content')
import test from '~/components/test.vue'
export default defineNuxtPlugin(async (nuxtApp) => {
const parsedContent = await useFetch( '/api/parse', {
method: 'POST',
body: {
_id: '1',
_path: '/test-page',
_type: 'markdown',
title: 'Hello World',
body: '---\n' +
'title: MDC\n' +
'---\n' +
'\n' +
'# {{ $doc.title}}\n' +
'\n' +
'MDC stands for _**M**ark**D**own **C**omponents_.\n' +
'\n' +
'This syntax supercharges regular Markdown to write documents interacting deeply with any Vue component from your `components/content/` directory or provided by a module.'
}
} );
debug('Received parsed content %O', parsedContent);
/*
* This is how we'll register the custom routes from the content module.
*/
const router = useRouter();
router.addRoute({
name: 'test-route',
path: '/test-page',
component: test,
props: {
parsed: parsedContent
}
})
}) And this component to render the content, inspired by what I could find in the documentation: <template>
<div>
This is the test page<br>
Prop: {{ parsed }}
<ContentRenderer :value="parsed">
<h1>{{ parsed.title }}</h1>
<ContentRendererMarkdown :value="parsed" />
</ContentRenderer>
</div>
</template>
<script setup lang="ts">
defineProps({
parsed: Object,
})
</script> This doesn't work (error below) and wouldn't be ideal even if it worked, since I should pass through the
The parsed content is null. Why? Sorry for the wall of text but I could find very little documentation for this use case. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hello @riccardofagiolo Same use case here, wanting to process markdown from Directus (though it could be from anywhere). I think the strategy of having an API endpoint for this makes sense as you can process markdown retrieved in the backend (Nuxt 3 does this nicely without making an extra http call) and also process markdown to preview in Directus. You may have noticed that such an endpoint actually is available in the content playground at playground/shared/server/api/parse.ts. My inclination would be to see if we could officially get this endpoint exposed in the project. This can be done by moving parse.ts to src/runtime/server/api and registering the route in module.ts, which could be conditionally based on an option, e.g.:
This way the endpoint would not be added by default and the option could include an api token to limit use to the web app and Directus. If there is a straightforward, future-proof way to add the /parse endpoint in app code, I haven't found it, but I'd be glad to try that as well. |
Beta Was this translation helpful? Give feedback.
-
Hey @warflash @jcolpal, |
Beta Was this translation helpful? Give feedback.
Hey @warflash @jcolpal,
Just to give you an update, In the end I wasn't satisfied with what was available so I built my own renderer.
I'm making it open source since a lot of people seem to be needing this kind of thing.
Here it is: https://gitlab.com/hermes-renderer/core
You're welcome to check it out, ask me any question and help out :)
Have a good day,
Riccardo