Refactor to support custom Markdoc components (#52)
* Refactor to support custom Markdoc components Introduced a new file for custom Markdoc components and updated the client to render Markdoc content using React components. Modified content renderer to handle React nodes instead of dangerously setting inner HTML. * Add custom Markdoc tags support in Keystatic Introduced `CustomMarkdocTags` for defining user tags. Updated `transform` to accommodate the new custom tags, enhancing tag customization in the CMS.
This commit is contained in:
committed by
GitHub
parent
2afa736f4c
commit
1d10dd210a
@@ -1,3 +1,3 @@
|
|||||||
export function KeystaticContentRenderer(props: { content: unknown }) {
|
export function KeystaticContentRenderer(props: { content: unknown }) {
|
||||||
return <div dangerouslySetInnerHTML={{ __html: props.content as string }} />;
|
return <div>{props.content as React.ReactNode}</div>;
|
||||||
}
|
}
|
||||||
|
|||||||
32
packages/cms/keystatic/src/custom-components.tsx
Normal file
32
packages/cms/keystatic/src/custom-components.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @name CustomMarkdocComponents
|
||||||
|
* @description Custom components for Markdoc. Please define your custom components here.
|
||||||
|
* @example
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* function Youtube(props: { src: string }) { ... }
|
||||||
|
*
|
||||||
|
* export const CustomMarkdocComponents: Record<string, React.ComponentType<never>> = {
|
||||||
|
* Youtube,
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
export const CustomMarkdocComponents: Record<
|
||||||
|
string,
|
||||||
|
React.ComponentType<never>
|
||||||
|
> = {
|
||||||
|
// define your custom components here
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name CustomMarkdocTags
|
||||||
|
* @description Custom tags for Markdoc. Please define your custom tags here.
|
||||||
|
* @example
|
||||||
|
* export const CustomMarkdocTags = {
|
||||||
|
* youtube: {
|
||||||
|
* render: "Youtube",
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
export const CustomMarkdocTags = {
|
||||||
|
// define your custom tags here
|
||||||
|
};
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
import { Cms, CmsClient } from '@kit/cms';
|
import { Cms, CmsClient } from '@kit/cms';
|
||||||
|
|
||||||
import { createKeystaticReader } from './create-reader';
|
import { createKeystaticReader } from './create-reader';
|
||||||
|
import {
|
||||||
|
CustomMarkdocComponents,
|
||||||
|
CustomMarkdocTags,
|
||||||
|
} from './custom-components';
|
||||||
import { PostEntryProps } from './keystatic.config';
|
import { PostEntryProps } from './keystatic.config';
|
||||||
|
|
||||||
export function createKeystaticClient() {
|
export function createKeystaticClient() {
|
||||||
@@ -158,8 +164,14 @@ class KeystaticClient implements CmsClient {
|
|||||||
: new Date();
|
: new Date();
|
||||||
|
|
||||||
const markdoc = await item.entry.content();
|
const markdoc = await item.entry.content();
|
||||||
const content = transform(markdoc.node);
|
|
||||||
const html = renderers.html(content);
|
const content = transform(markdoc.node, {
|
||||||
|
tags: CustomMarkdocTags,
|
||||||
|
});
|
||||||
|
|
||||||
|
const html = renderers.react(content, React, {
|
||||||
|
components: CustomMarkdocComponents,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: item.slug,
|
id: item.slug,
|
||||||
@@ -168,7 +180,7 @@ class KeystaticClient implements CmsClient {
|
|||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
description: item.entry.description,
|
description: item.entry.description,
|
||||||
publishedAt: publishedAt.toISOString(),
|
publishedAt: publishedAt.toISOString(),
|
||||||
content: html,
|
content: html as string,
|
||||||
image: item.entry.image ?? undefined,
|
image: item.entry.image ?? undefined,
|
||||||
status: item.entry.status,
|
status: item.entry.status,
|
||||||
categories:
|
categories:
|
||||||
|
|||||||
Reference in New Issue
Block a user