Skip to content
Langnostic
Esc
↑↓navigate↵open⌘Jpreview
On this page

Markdown / MDX

Translate Markdown and MDX documents, configure frontmatter options, and preserve translation registries.

The MDX plugin handles both Markdown and MDX files. It translates document blocks and frontmatter fields, using a registry beside each source document to track which source content has been translated.

See Using plugins for shared setup, groups, paths, and batching.

Installation

npm install langnostic @ai-sdk/openai @langnostic/plugin-mdx -D
pnpm add langnostic @ai-sdk/openai @langnostic/plugin-mdx -D
yarn add langnostic @ai-sdk/openai @langnostic/plugin-mdx -D
bun add langnostic @ai-sdk/openai @langnostic/plugin-mdx -D
nub add langnostic @ai-sdk/openai @langnostic/plugin-mdx -D
aube add langnostic @ai-sdk/openai @langnostic/plugin-mdx -D

Configuration

Use this complete configuration to translate Markdown documents while keeping non-translatable metadata out of AI requests:

import { openai } from '@ai-sdk/openai';
import MdxPlugin from '@langnostic/plugin-mdx';
import type { ConfigType } from 'langnostic';

export default {
  ai: {
    model: openai('gpt-6.1-sol'),
  },
  localeConfig: {
    source: 'en-US',
    target: ['zh-CN'],
  },
  groups: [
    {
      name: 'docs',
      plugin: MdxPlugin({
        frontmatterExcludedKeys: ['slug', 'date', 'tags'],
      }),
      paths: [
        {
          source: './docs/en-US/**/*.md',
          target: './docs/{locale}/**/*.md',
        },
      ],
    },
  ],
} satisfies ConfigType;

The same plugin handles .mdx; change both path patterns to that extension. The default stringsPerRequest is 20. The factory accepts optional PluginOptions and returns a plugin with type: 'mdx'.

Frontmatter options

frontmatterExcludedKeys?: string[] names top-level frontmatter fields to exclude from translation requests. It defaults to no excluded keys.

The package exports PluginOptions for reusable typed options:

import type { PluginOptions } from '@langnostic/plugin-mdx';

export const options = {
  frontmatterExcludedKeys: ['slug', 'date', 'tags'],
} satisfies PluginOptions;

Use it for identifiers, slugs, dates, numbers, arrays, and objects that should not be translated. Translatable frontmatter values should be strings. Exclusion keeps a field out of AI requests; review generated metadata when source fields change.

MDX change detection

The plugin parses a document into top-level Markdown/MDX blocks and hashes the serialized source blocks. It separately tracks source frontmatter hashes. For docs/en-US/setup.mdx, the registry is docs/en-US/setup.langnostic.json.

Commit this registry with source and translated documents. The ignored .langnostic/ directory is only for debug output and is not the registry store.

Source hashes identify which blocks have been translated for each target locale. New or modified source blocks and missing or changed translatable frontmatter are queued. Removal-only or reordering-only changes can be applied without translation requests.

Existing target blocks are associated with source hashes by position. Manual text edits can be reused while that association remains intact, but changing the number or order of target blocks can invalidate it or associate text with the wrong source block. If the target block count differs from the registry, every source block is queued again. A missing registry also causes retranslation.

Review manual structural edits carefully and keep a version-control copy before rebuilding translations. Restoring matching source, target, and registry files together preserves the tracking context.

Syntax and code examples

The plugin sends Markdown blocks, including code fences and JSX, to the model. Its instructions ask the model to retain inline code and handle Markdown/JSX, but code blocks are not excluded or validated as unchanged. Review syntax, placeholders, links, and executable examples after translation.

Markdown and YAML frontmatter are reserialized. Expect formatting changes even when the resulting document has equivalent structure.

Was this page helpful?