Skip to content

Conversation

@kennethkalmer
Copy link
Member

@kennethkalmer kennethkalmer commented Dec 3, 2025

Summary

Implements automatic MDX-to-Markdown transpilation during the Gatsby build process and adds nginx content negotiation to serve markdown documentation to LLMs and text-based tools while maintaining HTML for browsers.

Related to ticket: WEB-4447

What's Changed

1. MDX to Markdown Transpilation

  • Transpiles all MDX files under src/pages/docs/ to .md format during build
  • Runs in onPostBuild hook
  • Removes frontmatter except title (converted to # Title heading)
  • Removes import/export statements and script tags
  • Replaces template variables ({{API_KEY}}your-api-key, {{RANDOM_CHANNEL_NAME}}your-channel-name)
  • Preserves JSX components and code blocks as-is
  • Smart path mapping: channels/index.mdxpublic/docs/channels.md

2. Nginx Content Negotiation

  • Added text/markdown MIME type to config/mime.types
  • Implemented Accept header-based content negotiation using nginx map blocks
  • Serves markdown for: Accept: text/markdown, application/markdown, or text/plain
  • Maintains backward compatibility (HTML is default for browsers)
  • Works with existing authentication system
  • Zero performance impact (native nginx features)

3. Comprehensive Test Suite

  • Created bin/assert-content-negotiation.sh with 16 test cases
  • Tests all Accept header combinations and edge cases
  • Integrated into CircleCI test-nginx job
  • All tests passing locally and ready for CI

Content Negotiation Behavior

Request Response
/docs/channels (default) HTML
/docs/channels + Accept: text/markdown Markdown
/docs/channels + Accept: application/markdown Markdown
/docs/channels + Accept: text/plain Markdown
/docs/channels + browser Accept header HTML
/docs/channels.md (direct) Markdown

Files Changed

Created:

  • data/onPostBuild/transpileMdxToMarkdown.ts (246 lines) - Transpilation logic
  • bin/assert-content-negotiation.sh (138 lines) - Test suite

Modified:

  • data/onPostBuild/index.ts - Add transpilation to build pipeline
  • config/mime.types - Add text/markdown MIME type
  • config/nginx.conf.erb - Content negotiation maps and location blocks
  • .circleci/config.yml - Add test to CI pipeline

Test Plan

  • All MDX files transpile successfully
  • Markdown files appear in public/docs/ with correct paths
  • Content transformations work (frontmatter, imports, scripts, templates)
  • Content negotiation serves correct format based on Accept header
  • Browser requests get HTML (backward compatible)
  • Direct .md access works
  • Automated tests pass locally
  • CI tests pass
  • Review app deployment successful
  • Manual testing in review app

🤖 Generated with Claude Code

@kennethkalmer kennethkalmer added the review-app Create a Heroku review app label Dec 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch WEB-4447-transpile-mdx-to-md

Comment @coderabbitai help to get the list of available commands and usage tips.

@ably-ci ably-ci had a problem deploying to ably-docs-web-4447-tran-bjkybb December 3, 2025 14:42 Failure
@kennethkalmer kennethkalmer temporarily deployed to ably-docs-web-4447-tran-bjkybb December 3, 2025 14:54 Inactive
@ably-ci ably-ci temporarily deployed to ably-docs-web-4447-tran-mqes5f December 3, 2025 16:52 Inactive
@kennethkalmer kennethkalmer had a problem deploying to ably-docs-web-4447-tran-mqes5f December 3, 2025 22:34 Failure
@kennethkalmer kennethkalmer temporarily deployed to ably-docs-web-4447-tran-mqes5f December 4, 2025 09:06 Inactive
@kennethkalmer kennethkalmer self-assigned this Dec 4, 2025
@kennethkalmer kennethkalmer temporarily deployed to ably-docs-web-4447-tran-mqes5f December 4, 2025 10:28 Inactive
kennethkalmer and others added 3 commits December 4, 2025 10:53
Implements automatic transpilation of MDX documentation files to Markdown format during the Gatsby build process. The transpiled Markdown files are generated in the public/docs/ directory alongside HTML output, making documentation accessible to LLMs and other text-based tools.

Key features:
- Transpiles all MDX files under src/pages/docs/ to .md format
- Removes frontmatter except title (converted to # heading)
- Removes import/export statements and script tags
- Replaces template variables ({{API_KEY}}, {{RANDOM_CHANNEL_NAME}})
- Preserves JSX components and code blocks as-is
- Smart path mapping: index.mdx → parent.md, file.mdx → file.md

Successfully transpiles 211 documentation pages in ~5 seconds during onPostBuild hook.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Implements HTTP content negotiation in nginx to serve markdown versions of documentation pages based on the Accept header. This allows clients (like LLMs and text-based tools) to request markdown format while browsers continue to receive HTML by default.

Key features:
- Serves markdown for Accept: text/markdown, application/markdown, or text/plain
- Maintains backward compatibility (HTML is default)
- Works with existing authentication system
- Supports both index and non-index file paths
- No performance impact (uses nginx map blocks)

Content negotiation behavior:
- /docs/channels with Accept: text/markdown → serves docs/channels.md
- /docs/channels with Accept: text/html → serves docs/channels/index.html
- /docs/channels (browser default) → serves docs/channels/index.html
- /docs/channels.md (direct access) → serves docs/channels.md

Implementation:
- Added text/markdown MIME type to config/mime.types
- Added text/markdown to gzip_types for compression
- Created map blocks to detect Accept header preferences
- Updated location blocks to use content-negotiated file paths
- Fallback to HTML when markdown doesn't exist

All 211 markdown documentation files are now accessible via content negotiation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Adds comprehensive CI test suite to verify content negotiation works correctly for all Accept header scenarios. The test suite validates that nginx serves markdown or HTML based on the Accept header, with proper fallback behavior.

Test coverage (16 test cases):
- Basic content negotiation (6 tests): text/markdown, application/markdown, text/plain, text/html, */*
- Browser behavior (2 tests): Complex Accept headers, HTML priority when listed first
- Direct access (2 tests): .md and .html file access
- Path variations (3 tests): Index paths, non-index paths, nested paths
- Edge cases (3 tests): 404 handling, fallback behavior, non-docs paths

Also fixes nginx map priority order to ensure anchored patterns (^text/html, ^text/plain) are evaluated before wildcard patterns. This ensures "text/html, text/markdown" correctly serves HTML instead of markdown.

Changes:
- Created bin/assert-content-negotiation.sh with run_test() helper function
- Integrated test into CircleCI test-nginx job
- Reordered nginx map patterns for correct priority matching
- All 16 tests passing locally

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@m-hulbert m-hulbert left a comment

Choose a reason for hiding this comment

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

This LGTM (under the assumption that links contain ably-dev because it's a review app. There's a few really minor changes we could address, but I think that's more source-based than the .md generation. 🚀

@kennethkalmer
Copy link
Member Author

@m-hulbert thanks! let me get the code ready for team review then :)

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

Labels

review-app Create a Heroku review app

Development

Successfully merging this pull request may close these issues.

4 participants