- Docs site is hosted on Cloudflare Pages with a Cloudflare Worker reverse proxy
- Both environments use the same
/docs/base path — routing is by hostname, not path prefix
| Environment | URL | Pages Project | Branch |
|---|---|---|---|
| Production | www.marketdata.app/docs/ |
www-marketdata-app |
main |
| Staging | www-staging.marketdata.app/docs/ |
www-staging-marketdata-app |
staging |
- DNS resolves the hostname (both are proxied CNAMEs in Cloudflare)
- Cloudflare routes
/docsand/docs/*to the Worker (viawrangler.tomlroute patterns) - Worker (
worker/handler.js) looks up the hostname in theTARGETSmap to find the Pages target - Worker rewrites the hostname and fetches from the Pages project (e.g.
www-marketdata-app.pages.dev/docs/api/stocks) - Pages serves the file from its
docs/directory (built and nested there by CI) - Worker returns the response to the client — path stays the same throughout
- Hostname-based routing:
TARGETSmap inhandler.jsmaps each hostname to its Cloudflare Pages deployment - Markdown serving: Requests with
.mdextension orAccept: text/markdownheader fetch raw source from GitHub and return cleaned markdown (frontmatter stripped, JSX components converted) - SDK PHP redirect:
/docs/sdk-php/*→marketdataapp.github.io/sdk-php/*(301) - robots.txt blocking: Returns 404 for
/docs/robots.txtto prevent stale cached copies - Edge caching: Passes
cf.cacheEverythingon subrequests - 404 logging: Logs pathname and referer for 404 responses
- Non-docs paths pass through to the origin (WordPress)
Docs repo (.github/workflows/deploy-docs.yml):
- Builds Docusaurus (
yarn build) - Restructures build output to nest under
build/docs/ - Generates
_headersfile for asset cache control - Uploads build to R2 (
www-marketdata-app-buildsbucket) at{env}/sources/docs/ - Triggers orchestrator via
repository_dispatch - If
worker/files changed: runs worker tests, then deploys the worker
Orchestrator (MarketDataApp/www-marketdata-app, .github/workflows/deploy-site.yml):
- Downloads all sources from R2 (
{env}/sources/) - Merges into unified
build/directory - Deploys to Cloudflare Pages (
www-marketdata-apporwww-staging-marketdata-app) - Notifies source repo via
deploy-completedispatch
Post-deploy tests (.github/workflows/post-deploy-tests.yml):
- Triggered by
deploy-completefrom the orchestrator - Checks out the docs repo at the deployed commit SHA
- Runs integration tests and e2e tests against the deployed environment
www-staging.marketdata.app→ CNAME towww-staging-marketdata-app.pages.dev(proxied)www.marketdata.app→ existing DNS (proxied)
- Work on the staging branch, verify changes at
www-staging.marketdata.app/docs/ - Once verified, open a PR from
staging→mainand merge to deploy to production
- Use yarn, not npm (project uses
yarn.lock)
- Algolia DocSearch (App ID: IUHZFO750H, Index: "Market Data Documentation")
- Crawler config is managed in the Algolia dashboard, not in the codebase
hierarchy.lvl1is ranked abovehierarchy.lvl0in searchable attributes (custom tweak from Docusaurus default)
- Badges (New, Premium, Beta, High Usage) are configured via
sidebar_custom_props: { badge: n/p/b/h }in page frontmatter - Rendered by
src/theme/RenderTag.js, styled insrc/css/custom.css - Supported in sidebar links, sidebar categories, and page titles via swizzled theme components
- Unit tests:
cd worker && yarn test— tests worker routing, markdown serving, robots.txt, 404 logging - Integration tests:
cd worker && TEST_ENV=staging yarn test:integration— fetches live sitemap and verifies markdown serving for every doc URL - Redirect tests:
cd worker && TEST_ENV=staging yarn test:integration— verifies client-side redirects fromdocusaurus.config.js - E2E tests:
TEST_ENV=staging yarn test:e2e— Playwright tests for Context7 widget rendering