Skip to main content

MDX Preview Setup Guide

This guide will help you set up a complete MDX editing workflow with syntax highlighting, live preview, and hot reload for Docusaurus running in Docker with Cloudflare Tunnel.

What You'll Learn
  • How to enable MDX syntax highlighting in VS Code
  • Setting up live preview without constant Docker restarts
  • Configuring hot reload for instant changes
  • Secure preview access via Cloudflare Tunnel

Understanding the Problem

When working with .mdx files in VS Code, you may encounter:

  • ❌ No syntax highlighting (plain text appearance)
  • ❌ No "Open Preview" option like .md files have
  • ❌ Manual Docker restarts needed to see changes
  • ❌ No live reload during development

This guide solves all these issues.


Part 1: VS Code MDX Syntax Highlighting

Step 1: Install MDX Extension

  1. Open VS Code Extensions (Ctrl+Shift+X)
  2. Search for "MDX" (by unifiedjs is recommended)
  3. Click Install on SSH: [your-server] (if using Remote SSH)
  4. Reload VS Code: Ctrl+Shift+PDeveloper: Reload Window

Step 2: Configure File Association

Open Settings (JSON) and add:

"files.associations": {
"*.mdx": "mdx"
}

Step 3: Verify Language Mode

  1. Open any .mdx file
  2. Check bottom-right of VS Code status bar
  3. It should show MDX (not "Plain Text")
  4. If not, click it and select MDX
Quick Test

After setup, you should see colorful syntax highlighting for:

  • Markdown headers, bold, italic
  • JSX components like <Tabs>, <Details>
  • Import statements
  • Code blocks

Part 2: Live Preview Setup (No Restarts Needed)

Why Can't We Use "Open Preview"?

Unlike .md files, MDX contains React components that need a renderer. The best preview is the Docusaurus dev server itself.

Solution Architecture


Part 3: Docker Configuration for Hot Reload

Option A: Complete docker-compose.yml Setup

Create or update your docker-compose.yml:

services:
docusaurus:
image: node:20-alpine
container_name: docusaurus
working_dir: /site
restart: unless-stopped

volumes:
- /opt/docker-data/apps/docusaurus/site:/site
- docusaurus_node_modules:/site/node_modules

command: sh -c "npm run start -- --host 0.0.0.0 --port 3000"

environment:
# Enable file watching in Docker (critical for hot reload)
- CHOKIDAR_USEPOLLING=true
- WATCHPACK_POLLING=true
- CHOKIDAR_INTERVAL=1000

ports:
# Expose ONLY to localhost (safe for Cloudflare Tunnel)
- "127.0.0.1:3000:3000"

volumes:
docusaurus_node_modules:

Why This Configuration?

SettingPurpose
--host 0.0.0.0Container listens on all interfaces (required in Docker)
127.0.0.1:3000:3000Exposes port only to localhost (not public)
CHOKIDAR_USEPOLLINGEnables file watching in Docker environment
docusaurus_node_modules volumePersists dependencies, avoids reinstalling on restart

Part 4: Initial Setup & Testing

Step 1: Install Dependencies (One-Time)

# Start the container
docker compose up -d

# Install dependencies
docker compose exec docusaurus npm install

# Check logs
docker logs -f docusaurus

Step 2: Verify Dev Server

On your server, test that Docusaurus is running:

curl -I http://127.0.0.1:3000

Expected output:

HTTP/1.1 200 OK
Content-Type: text/html
Container Stays Running

You only need to do this ONCE. The container will keep running and auto-reload on file changes.


Part 5: Cloudflare Tunnel Configuration

Step 1: Configure Tunnel Ingress

Edit your Cloudflare Tunnel configuration:

ingress:
# Dev preview subdomain
- hostname: docs-dev.yourdomain.com
service: http://localhost:3000

# Other services...

# Catch-all
- service: http_status:404

Step 2: Restart Tunnel

cloudflared tunnel run <tunnel-name>

Step 3: Secure Your Preview (Important!)

Public Access Risk

Without protection, anyone can access your dev preview!

  1. Go to Cloudflare Zero Trust dashboard
  2. AccessApplicationsAdd application
  3. Choose Self-hosted
  4. Domain: docs-dev.yourdomain.com
  5. Policy: Allow only your email
  6. Save and deploy

Option B: Alternative Authentication

If you don't use Cloudflare Access, consider:

  • HTTP basic auth in Docusaurus config
  • VPN-only access
  • IP whitelist

Part 6: Your New Workflow (No Restarts!)

Daily Development Process

Step-by-Step

  1. Open https://docs-dev.yourdomain.com in browser
  2. Edit any .mdx file in VS Code
  3. Save the file (Ctrl+S)
  4. Watch browser auto-refresh (2-5 seconds)
  5. No Docker restart needed!

Part 7: Troubleshooting

Issue 1: No Syntax Highlighting

Symptom: MDX files appear as plain text

Solutions:

# Check language mode (bottom-right of VS Code)
# Should show "MDX", not "Plain Text"

# If wrong, manually select MDX:
# Click language mode → Search "MDX" → Select

Issue 2: Hot Reload Not Working

Symptom: Changes don't appear after saving

Solutions:

Check container is running dev server:

docker logs docusaurus | grep "webpack compiled"

Verify environment variables:

docker compose exec docusaurus env | grep CHOKIDAR

Increase polling interval:

environment:
- CHOKIDAR_INTERVAL=2000 # Slower system? Use 2-3 seconds

Force restart (if needed):

docker compose restart docusaurus

Issue 3: Tunnel Can't Reach Dev Server

Symptom: docs-dev.yourdomain.com shows error

Solutions:

Check port binding:

docker port docusaurus
# Should show: 3000/tcp -> 127.0.0.1:3000

Test from server:

curl http://localhost:3000
# Should return HTML

Verify tunnel configuration:

cloudflared tunnel info <tunnel-name>

Issue 4: "Open Preview" Still Missing

Workaround (if you want simple markdown preview):

// settings.json
"files.associations": {
"*.mdx": "markdown"
}

⚠️ Limitation: JSX components won't render, but basic Markdown structure will preview.


Part 8: Advanced Tips

Tip 1: Multiple Preview URLs

You can have both dev and production:

ingress:
# Dev preview (live reload)
- hostname: docs-dev.yourdomain.com
service: http://localhost:3000

# Production build
- hostname: docs.yourdomain.com
service: http://localhost:3001

Tip 2: VS Code Port Forwarding Alternative

If you don't want Cloudflare Tunnel for dev:

  1. In VS Code (Remote SSH)
  2. Open Ports tab
  3. Click Forward a Port
  4. Enter 3000
  5. Click Open in Browser

✅ Stays private, no tunnel configuration needed!

Tip 3: Build Production to Test

Before deploying:

# Build production version
docker compose exec docusaurus npm run build

# Test production locally
docker compose exec docusaurus npm run serve -- --port 3001

Tip 4: Clear Cache on Weird Issues

# Clear Docusaurus cache
docker compose exec docusaurus npm run clear

# Or full restart
docker compose down
docker compose up -d

Part 9: Quick Reference

Common Commands

# Start Docusaurus dev server
docker compose up -d

# View live logs
docker logs -f docusaurus

# Install new package
docker compose exec docusaurus npm install <package-name>

# Restart container
docker compose restart docusaurus

# Stop container
docker compose down

# Full cleanup (removes node_modules volume)
docker compose down -v

File Locations

PathDescription
/opt/docker-data/apps/docusaurus/site/Your Docusaurus project
/opt/docker-data/apps/docusaurus/site/docs/MDX documentation files
/opt/docker-data/apps/docusaurus/site/docusaurus.config.jsMain config
docker-compose.ymlContainer configuration

Port Reference

PortPurpose
3000Dev server (hot reload)
3001Production build (optional)

Summary Checklist

Use this checklist to verify your setup:

  • MDX extension installed in VS Code
  • Syntax highlighting works (colors visible)
  • docker-compose.yml configured with polling environment variables
  • Container running and accessible on localhost:3000
  • Cloudflare Tunnel pointing to localhost:3000
  • Cloudflare Access protecting dev preview
  • File changes trigger hot reload (test by editing a file)
  • Browser auto-refreshes on save

What You've Achieved

Syntax Highlighting: MDX files are colorful and readable
Live Preview: True Docusaurus rendering with all components
Hot Reload: Changes appear automatically, no restarts
Secure Access: Cloudflare Tunnel with authentication
Developer Experience: Edit → Save → See results instantly

Next Steps

Now you can focus on writing great documentation without fighting your tools!


Additional Resources


Last Updated: February 2, 2026
Tested With: Docusaurus 3.x, Node 20, Docker Compose, Cloudflare Tunnel