Skip to content

Validation

Syntax validation

Markdoc supports syntax validation out of the box using the validate function.

validate(AstNode, ?Config) => ValidateError[]


Calling validate is an optional step that you can use to validate your abstract syntax tree (AST) before rendering. This is useful during testing, continuous integration, or in dev-tools like editor extensions.

const doc = `# Heading`;

const ast = Markdoc.parse(doc);

const errors = Markdoc.validate(ast, config);

// Do something with the errors

If your document contains a syntax error, the output of validate looks like this:

const doc = `
{% callout %}
Here!
`;

const ast = Markdoc.parse(doc);

const errors = Markdoc.validate(ast, config);
// errors
[
  {
    type: 'tag',
    lines: [1, 2],
    location: {
      start: { line: 1 },
      end: { line: 2 }
    },
    error: {
      id: 'missing-closing',
      level: 'critical',
      message: "Node 'callout' is missing closing"
    }
  }
];

Schema validation

You can also extend Markdoc with custom validation rules, by adding a validate function to Node or Tag definitions, or to your custom attribute types.

Validating content

Use Node or Tag validate functions to verify the contents are correct, particularly the children.

/** @type {import('@markdoc/markdoc').Config} */
const config = {
  tags: {
    provider: {
      render: 'Provider',
      // ...
      validate(node) {
        if (node.children.length !== 1) {
          return [
            {
              id: 'provider-children',
              level: 'critical',
              message: 'Providers must only have one child.'
            }
          ];
        }
        return [];
      }
    }
  }
};

Validating attributes

Use custom Attribute types to validate that the attributes passed to your tags and nodes are correct.

export class ImageSrc {
  validate(value, config) {
    if (!value.startsWith('https://')) {
      return [
        {
          id: 'image-src',
          level: 'error',
          message: 'All image srcs should contain fully qualified URLs.'
        }
      ];
    }
    return [];
  }
}

/** @type {import('@markdoc/markdoc').Config} */
const config = {
  image: {
    render: 'img',
    attributes: {
      src: {
        type: ImageSrc,
        required: true
        // ...
      }
      // ...
    }
  }
};

Next steps