Skip to content

Add a way for consumers to pass custom components for MDX parsing #222

@wise-king-sullyman

Description

@wise-king-sullyman

Problem Summary

Consumers cannot use custom components directly within their MDX/markdown files. The MDX component mapping is hardcoded in the Astro page files ([...page].astro and [tab].astro), preventing users from injecting custom components like PatternFly's <Alert /> into their documentation content.

Current limitation: While the scope config option (in pf-docs.config.mjs) allows passing custom components for use within <LiveExample> blocks, there's no way to use custom components in the general MDX content outside of examples.

Use Case

When integrating docs-core v1.20.0, consumers need to:

  • Use PatternFly components (Alert, Banner, etc.) directly in markdown content for callouts and warnings
  • Import custom documentation components for specialized content rendering
  • Include organization-specific UI components in documentation pages
  • Render interactive widgets or diagrams inline with documentation

Example of desired usage:

# Component Documentation

<Alert variant="warning" title="Important Note">
  This component is deprecated. Use the new version instead.
</Alert>

Rest of documentation content...

Current Architecture

MDX components are provided via the components prop on the <Content /> component in Astro page files:

// src/pages/[section]/[...page].astro:84-106
<Content
  components={{
    SectionGallery,
    h1, h2, h3, h4, h5, h6,
    p, a, small, blockquote,
    pre, hr, ul, ol, dl, li, dt, dd,
    LiveExample,
  }}
/>

Why this is hardcoded:

  • The components object maps MDX elements to React/Astro components
  • Currently only includes HTML elements, LiveExample, and SectionGallery
  • No mechanism to merge in user-provided components from config

Related scope mechanism:

  • pf-docs.config.mjs has a scope property for LiveExample components
  • LiveExample.tsx:35-43 merges config.scope with built-in PatternFly components
  • This only applies to code inside <LiveExample> blocks, not general MDX content

MDX import stripping:
The convertToMDX process (cli/convertToMDX.ts:48-52) also removes absolute imports, which would prevent direct imports even if components were available:

function removeExistingImports(content: string): string {
  // Remove imports that are absolute and not CSS
  const importRegex = /^import {?[\w\s,\n]*}? from ['"](?!\.\.?\/)(?!.*\.css['"])[^'"]*['"];?\n/gm
  return content.replace(importRegex, '')
}

Potential Approaches

Two options have been identified:

  1. Configuration-based approach: Enable consumers to specify custom components through the pf-docs configuration file that become available globally in MDX files

  2. Import preservation approach: Modify the MDX conversion process to retain certain component imports in markdown files, while selectively removing only imports used exclusively in LiveExamples

Completion Criteria

The issue is resolved when:

  1. Custom components in MDX: Consumers can use custom components directly in MDX content outside of <LiveExample> blocks
  2. Configuration support: Clear mechanism (config or import-based) for registering custom components
  3. Component merging: User-provided components are merged with built-in components in the <Content /> components prop
  4. LiveExample compatibility: Custom components work in both general MDX content and within <LiveExample> scopes
  5. No conflicts: Custom components don't interfere with built-in component resolution or auto-generated imports
  6. Type safety: Proper TypeScript support for custom component registration
  7. Documentation: Clear examples showing how to register and use custom components

Technical Notes

  • File locations needing changes:
    • src/pages/[section]/[...page].astro:84-106 (components prop)
    • src/pages/[section]/[page]/[tab].astro:116-137 (components prop)
    • cli/convertToMDX.ts:48-52 (if using import preservation approach)
  • Existing scope config: pf-docs.config.mjs:44 has a scope property (currently only for LiveExample)
  • MDX components are provided via Astro's <Content components={{...}} /> pattern
  • Astro docs: https://docs.astro.build/en/guides/markdown-content/#custom-components-with-imported-mdx

Related Links


Jira Issue: PF-3654

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions