Integrate Markdoc library with Keystatic CMS.
The commit introduces the '@markdoc/markdoc' library to the Keystatic CMS. It modifies related functions and components such as 'KeystaticDocumentRenderer' and 'keystatic-client' to transform and render content using Markdoc. Additionally, the commit refactors 'keystatic.config.ts' file for more legible content field setup and adds related dependencies in the package.
This commit is contained in:
@@ -16,7 +16,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@keystatic/core": "0.5.14",
|
||||
"@keystatic/next": "5.0.0"
|
||||
"@keystatic/next": "5.0.0",
|
||||
"@markdoc/markdoc": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kit/cms": "workspace:^",
|
||||
@@ -25,6 +26,8 @@
|
||||
"@kit/tsconfig": "workspace:*",
|
||||
"@kit/ui": "workspace:^",
|
||||
"@types/node": "^20.12.8",
|
||||
"@types/react": "^18.3.1",
|
||||
"react": "18.3.1",
|
||||
"zod": "^3.23.6"
|
||||
},
|
||||
"eslintConfig": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { DocumentElement } from '@keystatic/core';
|
||||
import { DocumentRenderer } from '@keystatic/core/renderer';
|
||||
import * as React from 'react';
|
||||
|
||||
export function KeystaticDocumentRenderer(props: { content: unknown }) {
|
||||
return <DocumentRenderer document={props.content as DocumentElement[]} />;
|
||||
import Markdoc from '@markdoc/markdoc';
|
||||
|
||||
export function KeystaticDocumentRenderer({ content }: { content: unknown }) {
|
||||
return Markdoc.renderers.react(content as string, React);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import Markdoc from '@markdoc/markdoc';
|
||||
|
||||
import { Cms, CmsClient } from '@kit/cms';
|
||||
|
||||
import { createKeystaticReader } from './create-reader';
|
||||
@@ -138,7 +140,8 @@ class KeystaticClient implements CmsClient {
|
||||
? new Date(item.entry.publishedAt)
|
||||
: new Date();
|
||||
|
||||
const content = await item.entry.content();
|
||||
const markdoc = await item.entry.content();
|
||||
const content = Markdoc.transform(markdoc.node);
|
||||
|
||||
return {
|
||||
id: item.slug,
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
import { collection, config, fields } from '@keystatic/core';
|
||||
import {
|
||||
CloudConfig,
|
||||
GitHubConfig,
|
||||
LocalConfig,
|
||||
collection,
|
||||
config,
|
||||
fields,
|
||||
} from '@keystatic/core';
|
||||
import { Entry } from '@keystatic/core/reader';
|
||||
import { z } from 'zod';
|
||||
|
||||
type ZodOutputFor<T> = z.ZodType<T, z.ZodTypeDef, unknown>;
|
||||
|
||||
const local = z.object({
|
||||
kind: z.literal('local'),
|
||||
});
|
||||
}) satisfies ZodOutputFor<LocalConfig['storage']>;
|
||||
|
||||
const cloud = z.object({
|
||||
kind: z.literal('cloud'),
|
||||
project: z.string(),
|
||||
});
|
||||
}) satisfies ZodOutputFor<CloudConfig['storage']>;
|
||||
|
||||
const github = z.object({
|
||||
kind: z.literal('github'),
|
||||
@@ -19,7 +28,7 @@ const github = z.object({
|
||||
githubToken: z.string({
|
||||
required_error: 'Please provide a GitHub token',
|
||||
}),
|
||||
});
|
||||
}) satisfies ZodOutputFor<GitHubConfig['storage']>;
|
||||
|
||||
const storage = z.union([local, cloud, github]).parse({
|
||||
kind: process.env.KEYSTATIC_STORAGE_KIND ?? 'local',
|
||||
@@ -34,6 +43,34 @@ const keyStaticConfig = createKeyStaticConfig();
|
||||
|
||||
export default keyStaticConfig;
|
||||
|
||||
function getContentField() {
|
||||
return fields.markdoc({
|
||||
label: 'Content',
|
||||
options: {
|
||||
link: true,
|
||||
blockquote: true,
|
||||
bold: true,
|
||||
divider: true,
|
||||
orderedList: true,
|
||||
unorderedList: true,
|
||||
strikethrough: true,
|
||||
heading: true,
|
||||
code: true,
|
||||
italic: true,
|
||||
image: {
|
||||
directory: 'public/site/images',
|
||||
publicPath: '/site/images',
|
||||
schema: {
|
||||
title: fields.text({
|
||||
label: 'Caption',
|
||||
description: 'The text to display under the image in a caption.',
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export type PostEntryProps = Entry<
|
||||
(typeof keyStaticConfig)['collections']['posts']
|
||||
>;
|
||||
@@ -64,23 +101,7 @@ function createKeyStaticConfig() {
|
||||
}),
|
||||
language: fields.text({ label: 'Language' }),
|
||||
order: fields.number({ label: 'Order' }),
|
||||
content: fields.document({
|
||||
label: 'Content',
|
||||
formatting: true,
|
||||
dividers: true,
|
||||
links: true,
|
||||
images: {
|
||||
directory: 'public/site/images',
|
||||
publicPath: '/site/images',
|
||||
schema: {
|
||||
title: fields.text({
|
||||
label: 'Caption',
|
||||
description:
|
||||
'The text to display under the image in a caption.',
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
content: getContentField(),
|
||||
},
|
||||
}),
|
||||
documentation: collection({
|
||||
@@ -90,23 +111,7 @@ function createKeyStaticConfig() {
|
||||
format: { contentField: 'content' },
|
||||
schema: {
|
||||
title: fields.slug({ name: { label: 'Title' } }),
|
||||
content: fields.document({
|
||||
label: 'Content',
|
||||
formatting: true,
|
||||
dividers: true,
|
||||
links: true,
|
||||
images: {
|
||||
directory: 'public/site/images',
|
||||
publicPath: '/site/images',
|
||||
schema: {
|
||||
title: fields.text({
|
||||
label: 'Caption',
|
||||
description:
|
||||
'The text to display under the image in a caption.',
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
content: getContentField(),
|
||||
image: fields.image({
|
||||
label: 'Image',
|
||||
directory: 'public/site/images',
|
||||
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -426,6 +426,9 @@ importers:
|
||||
'@keystatic/next':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(@keystatic/core@0.5.14)(next@14.2.3)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@markdoc/markdoc':
|
||||
specifier: ^0.4.0
|
||||
version: 0.4.0(@types/react@18.3.1)(react@18.3.1)
|
||||
devDependencies:
|
||||
'@kit/cms':
|
||||
specifier: workspace:^
|
||||
@@ -445,6 +448,12 @@ importers:
|
||||
'@types/node':
|
||||
specifier: ^20.12.8
|
||||
version: 20.12.10
|
||||
'@types/react':
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
react:
|
||||
specifier: 18.3.1
|
||||
version: 18.3.1
|
||||
zod:
|
||||
specifier: ^3.23.6
|
||||
version: 3.23.6
|
||||
|
||||
Reference in New Issue
Block a user