diff --git a/packages/integrations/markdoc/components/Renderer.astro b/packages/integrations/markdoc/components/Renderer.astro
index 2079a5168..4a78fda95 100644
--- a/packages/integrations/markdoc/components/Renderer.astro
+++ b/packages/integrations/markdoc/components/Renderer.astro
@@ -1,6 +1,7 @@
---
import type { RenderableTreeNode } from '@markdoc/markdoc';
import type { AstroInstance } from 'astro';
+import { validateComponentsProp } from '../dist/utils.js';
import { createAstroNode } from './astroNode';
import RenderNode from './RenderNode.astro';
@@ -10,6 +11,9 @@ type Props = {
};
const { content, components } = Astro.props as Props;
+
+// Will throw if components is invalid
+validateComponentsProp(components);
---
diff --git a/packages/integrations/markdoc/components/astroNode.ts b/packages/integrations/markdoc/components/astroNode.ts
index da0ccbd21..12a0cd0a6 100644
--- a/packages/integrations/markdoc/components/astroNode.ts
+++ b/packages/integrations/markdoc/components/astroNode.ts
@@ -1,8 +1,7 @@
import type { AstroInstance } from 'astro';
import type { RenderableTreeNode } from '@markdoc/markdoc';
import Markdoc from '@markdoc/markdoc';
-import { MarkdocError } from '../dist/utils.js';
-import z from 'astro/zod';
+import { MarkdocError, isCapitalized } from '../dist/utils.js';
export type AstroNode =
| string
@@ -21,15 +20,13 @@ export function createAstroNode(
node: RenderableTreeNode,
components: Record = {}
): AstroNode {
- components = validateComponentsProp(components);
-
if (typeof node === 'string' || typeof node === 'number') {
return String(node);
} else if (node === null || typeof node !== 'object' || !Markdoc.Tag.isTag(node)) {
return '';
}
- if (isCapitalized(node.name) && node.name in components) {
+ if (node.name in components) {
const component = components[node.name];
const props = node.attributes;
const children = node.children.map((child) => createAstroNode(child, components));
@@ -52,35 +49,3 @@ export function createAstroNode(
};
}
}
-
-const componentsPropValidator = z.record(
- z
- .string()
- .min(1, 'Invalid `components` prop. Component names cannot be empty!')
- .refine(
- (value) => isCapitalized(value),
- (value) => ({
- message: `Invalid \`components\` prop: ${JSON.stringify(
- value
- )}. Component name must be capitalized. If you want to render HTML elements as components, try using a Markdoc node [TODO: DOCS LINK]`,
- })
- ),
- z.any()
-);
-
-function validateComponentsProp(components: Record) {
- try {
- return componentsPropValidator.parse(components);
- } catch (e) {
- throw new MarkdocError({
- message:
- e instanceof z.ZodError
- ? e.issues[0].message
- : 'Invalid `components` prop. Ensure you are passing an object of components to ',
- });
- }
-}
-
-function isCapitalized(str: string) {
- return str.length > 0 && str[0] === str[0].toUpperCase();
-}
diff --git a/packages/integrations/markdoc/src/utils.ts b/packages/integrations/markdoc/src/utils.ts
index e4150075b..d9d728a09 100644
--- a/packages/integrations/markdoc/src/utils.ts
+++ b/packages/integrations/markdoc/src/utils.ts
@@ -2,6 +2,8 @@ import matter from 'gray-matter';
import path from 'node:path';
import type fsMod from 'node:fs';
import type { ErrorPayload as ViteErrorPayload } from 'vite';
+import type { AstroInstance } from 'astro';
+import z from 'astro/zod';
/**
* Match YAML exception handling from Astro core errors
@@ -109,3 +111,35 @@ export function getAstroConfigPath(fs: typeof fsMod, root: string): string | und
export function prependForwardSlash(str: string) {
return str[0] === '/' ? str : '/' + str;
}
+
+export function validateComponentsProp(components: Record) {
+ try {
+ return componentsPropValidator.parse(components);
+ } catch (e) {
+ throw new MarkdocError({
+ message:
+ e instanceof z.ZodError
+ ? e.issues[0].message
+ : 'Invalid `components` prop. Ensure you are passing an object of components to ',
+ });
+ }
+}
+
+const componentsPropValidator = z.record(
+ z
+ .string()
+ .min(1, 'Invalid `components` prop. Component names cannot be empty!')
+ .refine(
+ (value) => isCapitalized(value),
+ (value) => ({
+ message: `Invalid \`components\` prop: ${JSON.stringify(
+ value
+ )}. Component name must be capitalized. If you want to render HTML elements as components, try using a Markdoc node [TODO: DOCS LINK]`,
+ })
+ ),
+ z.any()
+);
+
+export function isCapitalized(str: string) {
+ return str.length > 0 && str[0] === str[0].toUpperCase();
+}