Skip to content

[CMSDS-3954] Add hosted Markdown equivalents for documentation pages#3985

Merged
tamara-corbalt merged 23 commits intomainfrom
tdement/CMSDS-3954/add-markdown-only-pages
Apr 1, 2026
Merged

[CMSDS-3954] Add hosted Markdown equivalents for documentation pages#3985
tamara-corbalt merged 23 commits intomainfrom
tdement/CMSDS-3954/add-markdown-only-pages

Conversation

@tamara-corbalt
Copy link
Copy Markdown
Collaborator

@tamara-corbalt tamara-corbalt commented Mar 25, 2026

Summary

  • Adds hosted Markdown equivalents for each documentation page.
  • Converts .mdx content into pure Markdown output during build.

Jira ticket

How to test

Run docs tests

npm run test:unit:docs

Generate Hosted Markdown

  1. cd packages/docs
  2. npm run build
  3. Inspect the public directory:
    • Each page directory should now include a llms.txt file alongside index.html.
  4. Run npm run start (from within packages/docs):
    • Note: running npm run start from the repo root will run gatsby clean && gatsby develop, which clears the public directory and removes generated files.
  5. Visit a page and its Markdown equivalent:

Checklist

  • Prefixed the PR title with the Jira ticket number as [CMSDS-####] Title or [NO-TICKET] if this is unticketed work.
  • Selected appropriate Type (only one) label for this PR, if it is a breaking change, label should only be Type: Breaking
  • Selected appropriate Impacts, multiple can be selected.
  • Selected appropriate release milestone

@tamara-corbalt tamara-corbalt changed the title [CMSDS-3954] Add hosted Markdown only pages [CMSDS-3954] Add hosted Markdown equivalents for documentation pages Mar 25, 2026
@tamara-corbalt tamara-corbalt marked this pull request as ready for review March 25, 2026 21:03
@tamara-corbalt tamara-corbalt self-assigned this Mar 25, 2026
@tamara-corbalt tamara-corbalt added Impacts: Documentation Indicates that this item relates to documentation Type: Added Indicates a new feature. labels Mar 25, 2026
Copy link
Copy Markdown
Collaborator

@jack-ryan-nava-pbc jack-ryan-nava-pbc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly minor stuff. I would like to see some specs added, and I'm not sure if we need error handling in place given that most of these functions are find and replace operations, but maybe worth thinking about...

Comment thread packages/docs/scripts/llms-txt/index.mjs
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/index.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/index.mjs Outdated
Copy link
Copy Markdown
Collaborator

@derek-cmsds derek-cmsds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some questions about some of the Markdown generation. I have one other more general question though: Is there anything in the root LLMs.txt that references these other Markdown files? How do we prompt the chatbot to visit these other paths?

Comment thread packages/docs/scripts/llms-txt/index.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs Outdated
Comment thread packages/docs/scripts/llms-txt/mdxToMarkdown.mjs
Comment thread packages/docs/scripts/llms-txt/renderMarkdown.mjs
@tamara-corbalt
Copy link
Copy Markdown
Collaborator Author

I left some questions about some of the Markdown generation. I have one other more general question though: Is there anything in the root LLMs.txt that references these other Markdown files? How do we prompt the chatbot to visit these other paths?

Yes, good question. The change is a bit buried in this PR, but I updated the listed Urls in the root llms.txt to point to these hosted Markdown files instead of their HTML equivalents like so:

## Components

- [Accordion](https://design.cms.gov/components/accordion/llms.txt): An accordion is a list of headers that hide or reveal additional content when selected.
- [Alert](https://design.cms.gov/components/alert/llms.txt): Alerts give feedback to users, provide critical information, and/or offer key supplementary details about a task.


// Run this first on the whole document, since ThemeContent
// may wrap across fenced code blocks.
result = normalizeThemeContent(result);
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new code-snippet-aware processing (above in processMdxOutsideCodeFences), the MDX body is split into fenced and non-fenced chunks so cleanup transforms only run on the non-fenced chunks.

Because ThemeContent can wrap both text and fenced code blocks, it must be normalized before this split. Otherwise the opening and closing tags would end up in separate chunks.

.join('\n\n');
};

export function processMdxOutsideCodeFences(input, transform) {
Copy link
Copy Markdown
Collaborator Author

@tamara-corbalt tamara-corbalt Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to preserve non-interactive code snippets in the hosted markdown output. Otherwise, large portions of code-heavy pages like for-developers become almost meaningless.

The limitation here is that we don't yet have a reliable way to preserve interactive code examples such as <ThemeCodeBlock/>, whose rendered output changes based on the theme switcher, like this one.

Copy link
Copy Markdown
Collaborator

@derek-cmsds derek-cmsds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers, but I do have some questions about comments and the new doc site tests you added. Well done.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love all of this.

Comment on lines +50 to +52
// Unwraps simple components (e.g., Alerts, Badges) but keeps their text
chunk = unwrapSimpleComponents(chunk);
// Final cleanup: removes any remaining JSX.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad these comments are here. Would it make sense to document the functions in mdxToMArkdown.mjs with JSDoc comments so that devs can mouse-over them for more details?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate these tests.

Comment thread package.json
"test:unit:coverage:wc": "npm run test:unit:wc -- --collectCoverage --coverageReporters='json-summary'",
"test:unit:coverage:all": "npm run test:unit:coverage:react && npm run test:unit:coverage:wc && tsx ./tests/unit/combineTestCoverage.ts",
"test:unit": "jest --config=tests/unit/jest.config.js",
"test:unit:docs": "npm --prefix ./packages/docs run test",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the docs tests be run when running a broader test command like npm run test or npm run test:unit? Are we adding these tests to our CI pipeline?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I think that's a good idea to fold the new tests into the npm run test:unit script

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may need to back out folding the docs tests into npm run test:unit and move that to a follow-up ticket. I forgot there are some downstream side effects: test:unit:coverage calls test:unit, and combineTestCoverage.ts expects a dedicated coverage artifact that no longer appears to be generated in CI.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this follow up ticket: https://jira.cms.gov/browse/CMSDS-3973

Copy link
Copy Markdown
Collaborator

@jack-ryan-nava-pbc jack-ryan-nava-pbc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions and observations, but over all this looks awesome! Well done and thank you!

Comment thread packages/docs/scripts/llms-txt/index.mjs Outdated

result = processMdxOutsideCodeFences(result, (input) => {
let chunk = input;
// ⚠️ NOTE: Order matters — do not rearrange these steps.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very helpful comment!


const __dirname = path.dirname(fileURLToPath(import.meta.url))
const require = createRequire(import.meta.url)
const normalizePagePath = (slug) => slug.replace(/\d+_/g, '');
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is actually duplicative of removePositioning, which is in the packages/docs/src/helpers/casingUtils.ts file. You should probably import and use that function instead of duplicating.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree this is duplicative but Node doesn’t love that removePositioning is being imported from a .ts file inside gatsby-node.mjs.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it throw an error or a type warning? I can live with a type warning (or even silence it).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this looks like a hard runtime failure; the build fails because node can't resolve the .ts file extension

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alrighty, let's duplicate the function for now. Thanks for checking! Can you add a brief TODO comment pointing to the other function?

@tamara-corbalt tamara-corbalt merged commit c88e45b into main Apr 1, 2026
1 check passed
@tamara-corbalt tamara-corbalt deleted the tdement/CMSDS-3954/add-markdown-only-pages branch April 1, 2026 15:34
tamara-corbalt added a commit that referenced this pull request Apr 1, 2026
…3985)

* Write md files into public folder

* Add logic to strip out interative content and import lines.

* Readability adjustment

* Move buildMarkdownPage utility into llms-txt scripts

* Refactor for readability

* Small refinements to gatsby-node.mjs

* Strip out Code, Examples & Maturity content sections. For convertTHemeContentToAnnoations, fix casing logic and retain child text

* Rename function handling the ThemeContent logic

* Fixes regex for stripMarkdoSections

* Revert change to accordion.mdx

* Add warning about order of operations

* - Adds tests for:
  - removeImportStatements,
  - stripMarkdownSections,
  - normalizeThemeContent,
  - normalizeMarkdownOutput
- Adds logic to preserve code snippets

* Adds tests for unwrapSimpleComponents, normalizeMarkdownOutput, and processMdxForHostedMarkdown

* Move all fixtures into dedicated fixture file

* Standardize fixture variable names

* Adds commands to run unit tests in docs package

* Ensure html and css blocks are preserved as well

* Remove extra semicolon

* Adds jsdocs for mdxToMarkdown utilities

* Fold docs tests into broader test command

* Revert wrapping docs tests into broader test command

* Adds todo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Impacts: Documentation Indicates that this item relates to documentation Type: Added Indicates a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants