Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
fc693e5
feat: replace GitHub link with user profile button in navbar
MarketDataApp Mar 3, 2026
3c0edad
fix: cache user API response to eliminate navbar CLS on page navigation
MarketDataApp Mar 3, 2026
5c32475
fix: render user profile item correctly in mobile hamburger menu
MarketDataApp Mar 3, 2026
0f0420b
fix: show 'Customer Dashboard' with external link icon in mobile menu
MarketDataApp Mar 3, 2026
706b0d9
fix: show 'Log in' immediately instead of blank gap while API loads
MarketDataApp Mar 3, 2026
cbcdc83
feat: use btn-hover-orange from @marketdataapp/ui for the Log in button
MarketDataApp Mar 3, 2026
9a3c615
fix: mobile menu shows 'Log in' when logged out, 'Customer Dashboard'…
MarketDataApp Mar 3, 2026
e01191c
feat: add Log out button on desktop for logged-in users
MarketDataApp Mar 3, 2026
281e0b2
style: update comment for navbar user profile to reflect logged-in state
MarketDataApp Mar 3, 2026
6e3d99b
chore: upgrade @marketdataapp/ui to 1.2.0
MarketDataApp Mar 3, 2026
0d6857d
chore: upgrade @marketdataapp/ui to v2.0.0 (Tailwind v4)
MarketDataApp Mar 3, 2026
0caef70
fix: skip Cloudflare Zaraz script in development
MarketDataApp Mar 3, 2026
969c839
fix: restore btn-hover-orange text color overridden by Docusaurus
MarketDataApp Mar 3, 2026
cf960b3
chore: upgrade @marketdataapp/ui to v2.0.1
MarketDataApp Mar 3, 2026
263c384
chore: upgrade @marketdataapp/ui to v2.0.2
MarketDataApp Mar 3, 2026
49b34ab
feat: add customer support agent CLI tool
MarketDataApp Mar 4, 2026
131973f
feat: enhance support prompt with lookup tool documentation
MarketDataApp Mar 4, 2026
ebeca6b
chore: remove support agent (moved to MarketDataApp/support-agent)
MarketDataApp Mar 4, 2026
f1358b0
feat(worker): add canonical URL header and llms.txt spec support for …
MarketDataApp Mar 5, 2026
c538d30
fix: switch to no-reset UI CSS to prevent Docusaurus style conflicts
MarketDataApp Mar 5, 2026
d33dcd1
fix: load UI CSS as static file to bypass webpack nesting issues
MarketDataApp Mar 5, 2026
100b020
fix: add 12px spacing between login button and dark mode toggle
MarketDataApp Mar 5, 2026
f129356
fix: update staging title in docusaurus config for development enviro…
MarketDataApp Mar 5, 2026
a17e1da
chore: disable docs and blog in Docusaurus config and remove index.md…
MarketDataApp Mar 5, 2026
3fa5999
chore: rename GitHub Actions workflows for clarity
MarketDataApp Mar 5, 2026
e90dbd0
fix: keep navbar button compact at 1024-1079px to prevent link wrapping
MarketDataApp Mar 5, 2026
da3feaa
fix: show external link icon on login button in mobile menu
MarketDataApp Mar 5, 2026
03b77d1
fix: use stale-while-revalidate for navbar login state
MarketDataApp Mar 5, 2026
71b0408
feat: add priority-based navbar overflow auto-hide
MarketDataApp Mar 5, 2026
d52e169
fix: bump @marketdataapp/ui to v2.3.1 for flex-nowrap overflow detection
MarketDataApp Mar 5, 2026
2a4c3cd
fix: bump @marketdataapp/ui to v2.3.2 for grandchild compression dete…
MarketDataApp Mar 5, 2026
74f9bd9
fix: prevent navbar link text from wrapping at 1024-1027px
MarketDataApp Mar 5, 2026
8176f2b
docs: add explanatory comments to navbar overflow CSS rules
MarketDataApp Mar 5, 2026
d9f2bf1
fix: compact login button padding on mobile to prevent search overlap
MarketDataApp Mar 5, 2026
39979f4
fix: add right margin to login button on mobile for search icon clear…
MarketDataApp Mar 5, 2026
c00b248
chore: bump @marketdataapp/ui to v2.3.3
MarketDataApp Mar 5, 2026
dc57e43
chore: bump @marketdataapp/ui to v2.3.4
MarketDataApp Mar 5, 2026
33c488f
fix: scale login button margin-right to match search bar width
MarketDataApp Mar 5, 2026
723a00c
feat: migrate user profile to @marketdataapp/ui/user-profile v2.4.2
MarketDataApp Mar 6, 2026
c141339
fix: add margin rules for user-profile avatar at all breakpoints
MarketDataApp Mar 6, 2026
a5bdabc
fix: bump @marketdataapp/ui to v2.5.0 for scoped dropdown CSS specifi…
MarketDataApp Mar 6, 2026
81edf31
fix: apply margin to the flex-child container, not the inner wrapper
MarketDataApp Mar 6, 2026
918624c
refactor: simplify navbar CSS with UI library v2.6.0 consistent wrapper
MarketDataApp Mar 6, 2026
6d6ecde
fix: consistent 12px gap between search and avatar, center avatar ver…
MarketDataApp Mar 6, 2026
88ea6b8
feat: add user-profile integration tests
MarketDataApp Mar 6, 2026
afd2383
fix: bump UI to v2.7.0, use consistent .user-profile-avatar selector …
MarketDataApp Mar 6, 2026
9a387ce
refactor: move user-profile integration tests to UI repo, fix CLS
MarketDataApp Mar 6, 2026
f0775b8
feat: add Slack failure alerts to all workflows
MarketDataApp Mar 6, 2026
781f0c1
feat: bump UI to v2.8.0, adds guest sign-in dropdown for non-logged-i…
MarketDataApp Mar 6, 2026
cc361fa
fix: bump UI to v2.8.1
MarketDataApp Mar 6, 2026
6e40860
feat: bump UI to v2.9.0
MarketDataApp Mar 6, 2026
5ac90a9
fix: add run-name to post-deploy workflow so Actions list shows prefi…
MarketDataApp Mar 6, 2026
fd1e7e9
fix: keep user profile dropdown on right side of navbar at all widths
MarketDataApp Mar 6, 2026
c14401c
feat: bump UI to v2.9.1, update CSS copy path for new dist layout
MarketDataApp Mar 6, 2026
dcb697b
fix: vertically center avatar in navbar by removing baseline gap
MarketDataApp Mar 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Deploy Docs
name: "Docs: Build & Upload to R2"

on:
push:
Expand Down Expand Up @@ -115,3 +115,19 @@ jobs:
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy
workingDirectory: worker

- name: Notify Slack on failure
if: failure()
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_ALERTS_WEBHOOK_URL }}
REPO: ${{ github.repository }}
WORKFLOW: ${{ github.workflow }}
BRANCH: ${{ github.ref_name }}
SHA: ${{ github.sha }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
SHORT_SHA="${SHA:0:7}"
printf '🔴 WORKFLOW FAILED — %s\nRepo: %s\nBranch: %s @ %s\n%s' \
"$WORKFLOW" "$REPO" "$BRANCH" "$SHORT_SHA" "$RUN_URL" \
| jq -Rs '{text: .}' \
| curl -s -X POST "$SLACK_WEBHOOK" -H 'Content-Type: application/json' -d @-
19 changes: 18 additions & 1 deletion .github/workflows/post-deploy-tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: Post-Deploy Tests
name: "Docs: Post-Deploy Integration & E2E Tests"
run-name: "Docs: Post-Deploy Tests (${{ github.event.client_payload.environment || 'unknown' }})"

on:
repository_dispatch:
Expand Down Expand Up @@ -35,3 +36,19 @@ jobs:
env:
TEST_ENV: ${{ github.event.client_payload.environment }}
run: yarn test:e2e

- name: Notify Slack on failure
if: failure()
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_ALERTS_WEBHOOK_URL }}
REPO: ${{ github.repository }}
WORKFLOW: ${{ github.workflow }}
BRANCH: ${{ github.ref_name }}
SHA: ${{ github.sha }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
SHORT_SHA="${SHA:0:7}"
printf '🔴 WORKFLOW FAILED — %s\nRepo: %s\nBranch: %s @ %s\n%s' \
"$WORKFLOW" "$REPO" "$BRANCH" "$SHORT_SHA" "$RUN_URL" \
| jq -Rs '{text: .}' \
| curl -s -X POST "$SLACK_WEBHOOK" -H 'Content-Type: application/json' -d @-
34 changes: 33 additions & 1 deletion .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: PR Checks (Staging Integration Tests)
name: "Docs: PR Checks"

on:
pull_request:
Expand Down Expand Up @@ -54,6 +54,22 @@ jobs:
TEST_ENV: staging
run: yarn test:integration

- name: Notify Slack on failure
if: failure()
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_ALERTS_WEBHOOK_URL }}
REPO: ${{ github.repository }}
WORKFLOW: ${{ github.workflow }}
BRANCH: ${{ github.ref_name }}
SHA: ${{ github.sha }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
SHORT_SHA="${SHA:0:7}"
printf '🔴 WORKFLOW FAILED — %s\nRepo: %s\nBranch: %s @ %s\n%s' \
"$WORKFLOW" "$REPO" "$BRANCH" "$SHORT_SHA" "$RUN_URL" \
| jq -Rs '{text: .}' \
| curl -s -X POST "$SLACK_WEBHOOK" -H 'Content-Type: application/json' -d @-

staging-e2e-tests:
runs-on: ubuntu-latest
steps:
Expand All @@ -72,3 +88,19 @@ jobs:
env:
TEST_ENV: staging
run: yarn test:e2e

- name: Notify Slack on failure
if: failure()
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_ALERTS_WEBHOOK_URL }}
REPO: ${{ github.repository }}
WORKFLOW: ${{ github.workflow }}
BRANCH: ${{ github.ref_name }}
SHA: ${{ github.sha }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
SHORT_SHA="${SHA:0:7}"
printf '🔴 WORKFLOW FAILED — %s\nRepo: %s\nBranch: %s @ %s\n%s' \
"$WORKFLOW" "$REPO" "$BRANCH" "$SHORT_SHA" "$RUN_URL" \
| jq -Rs '{text: .}' \
| curl -s -X POST "$SLACK_WEBHOOK" -H 'Content-Type: application/json' -d @-
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ llm-docs/
*.draft
.cursorignore
.playwright-mcp/
e2e/.auth/
test-results/

npm-debug.log*
Expand All @@ -27,5 +28,6 @@ yarn-error.log*
.env

static/robots.txt
static/css/
worker/node_modules

5 changes: 0 additions & 5 deletions docs/index.md

This file was deleted.

20 changes: 15 additions & 5 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require("dotenv").config();
/** @type {import('@docusaurus/types').Config} */
const config = {
title:
process.env.PROD == "true" ? "Market Data" : "Market Data Docs (dev)",
process.env.PROD == "true" ? "Market Data" : "Market Data Docs (staging)",
tagline: "Complete Documentation For All Market Data Products & Services",

url:
Expand All @@ -35,6 +35,13 @@ const config = {
content: "BAA3BC0EFD344D0C",
},
},
{
tagName: "link",
attributes: {
rel: "stylesheet",
href: "/docs/css/components.no-reset.css",
},
},
],

i18n: {
Expand All @@ -47,9 +54,10 @@ const config = {
"classic",
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: false,
blog: false,
theme: {
customCss: require.resolve("./src/css/custom.css"),
customCss: [require.resolve("./src/css/custom.css")],
},
sitemap:
process.env.PROD == "true"
Expand All @@ -64,7 +72,10 @@ const config = {
],
],

clientModules: ['./src/clientModules/themeCookieSync.js'],
clientModules: [
'./src/clientModules/themeCookieSync.js',
'./src/clientModules/navbarOverflow.js',
],

plugins: [
'./plugins/theme-cookie-sync',
Expand Down Expand Up @@ -222,8 +233,7 @@ const config = {
position: "right",
},
{
href: "https://github.com/MarketDataApp/documentation",
label: "GitHub",
type: "custom-UserProfile",
position: "right",
},
],
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"copy:ui-css": "mkdir -p static/css && cp node_modules/@marketdataapp/ui/dist/css/components.no-reset.css static/css/",
"start": "yarn copy:ui-css && docusaurus start",
"build": "yarn copy:ui-css && docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
Expand All @@ -23,7 +24,7 @@
"@docusaurus/plugin-client-redirects": "3.0.1",
"@docusaurus/plugin-content-docs": "3.0.1",
"@docusaurus/preset-classic": "3.0.1",
"@marketdataapp/ui": "github:MarketDataApp/ui",
"@marketdataapp/ui": "github:MarketDataApp/ui#main",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"dotenv": "^16.0.2",
Expand Down
12 changes: 11 additions & 1 deletion playwright.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { defineConfig } from '@playwright/test';

try {
process.loadEnvFile();
} catch {}

export default defineConfig({
testDir: './e2e',
timeout: 30_000,
retries: 1,
use: {
headless: true,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{
name: 'smoke',
testMatch: ['context7-widget.spec.js'],
use: { browserName: 'chromium' },
},
],
});
17 changes: 17 additions & 0 deletions src/clientModules/navbarOverflow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { initNavbarOverflow } from '@marketdataapp/ui/navbar-overflow';

export function onRouteDidUpdate() {
const container = document.querySelector('.navbar__inner');
if (!container || container._overflowInit) return;

container._overflowInit = true;
initNavbarOverflow({
container,
items: [
// Priority order: lowest number = hidden first
{ selector: '.navbar__items--right [class*="colorModeToggle"]', priority: 1 },
{ selector: '.user-profile-wrapper', priority: 2 },
{ selector: '.navbar__items--right .DocSearch-Button', priority: 3 },
],
});
}
51 changes: 51 additions & 0 deletions src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,57 @@
background-color: #E65100; /* Beta: Orange */
}

/* ==========================================================================
Navbar overflow prevention
At desktop widths (≥997px) the right-side items (search, avatar, username,
logout button, dark-mode toggle) can overflow the navbar when a user is
logged in. These rules keep everything on one line:
- flex-wrap: nowrap on .navbar__inner stops the two halves from stacking.
- white-space: nowrap on nav links stops multi-word labels ("Sheets Add-On",
"Accounts & Billing") from wrapping inside their flex item at ~1024px.
- The JS utility (navbarOverflow.js) then hides lower-priority right-side
items one at a time until nothing is compressed.
========================================================================== */
@media (min-width: 997px) {
.navbar__inner {
flex-wrap: nowrap;
}
.navbar__items .navbar__link {
white-space: nowrap;
}
}

/* Navbar user-profile positioning
Desktop (≥997px): 12px gap before the dark-mode toggle.
Below desktop (<997px): Docusaurus absolutely-positions the search bar to
the right, which puts the profile to its left. Override search back to
normal flow so both items participate in flex layout and the profile
(later in DOM order) stays on the far right. */
.navbar__items--right .user-profile-wrapper {
align-self: center;
line-height: 0;
}
@media (min-width: 997px) {
.navbar__items--right .user-profile-wrapper {
margin-right: 12px;
}
}
@media (max-width: 996px) {
.navbar__items--right [class*="navbarSearchContainer"] {
position: relative;
right: auto;
}
.navbar__items--right .user-profile-wrapper {
margin-left: 12px;
}
}

/* Generic hidden utility — required by the UI library's dropdown toggle
(classList.add('hidden') / classList.remove('hidden')). */
.hidden {
display: none;
}

/* Clear floats so following content starts below (e.g. after float: right images) */
.clear-float {
clear: both;
Expand Down
7 changes: 7 additions & 0 deletions src/theme/NavbarItem/ComponentTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ComponentTypes from '@theme-original/NavbarItem/ComponentTypes';
import UserProfile from '@site/src/theme/NavbarItem/UserProfile';

export default {
...ComponentTypes,
'custom-UserProfile': UserProfile,
};
33 changes: 33 additions & 0 deletions src/theme/NavbarItem/UserProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, { useRef, useEffect } from 'react';
import { initUserProfile } from '@marketdataapp/ui/user-profile';

export default function UserProfile({ mobile }) {
const ref = useRef(null);

useEffect(() => {
if (mobile) return;
let cancelled = false;
let cleanup;
initUserProfile({
container: ref.current,
dropdown: true,
loginUrl: 'https://www.marketdata.app/dashboard/',
logoutUrl: 'https://dashboard.marketdata.app/marketdata/logout',
dashboardUrl: 'https://www.marketdata.app/dashboard/',
loginText: 'Log in',
}).then((fn) => {
if (cancelled) {
fn();
return;
}
cleanup = fn;
});
return () => {
cancelled = true;
if (cleanup) cleanup();
};
}, [mobile]);

if (mobile) return null;
return <div ref={ref} className="user-profile-container" />;
}
10 changes: 7 additions & 3 deletions src/theme/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import React from 'react';
import Head from '@docusaurus/Head';
import Context7Widget from '@site/src/components/Context7Widget';

const isProd = process.env.NODE_ENV === 'production';

export default function Root({children}) {
return (
<>
<Head>
<script data-cfasync="false" src="/cdn-cgi/zaraz/i.js" referrerPolicy="origin" />
</Head>
{isProd && (
<Head>
<script data-cfasync="false" src="/cdn-cgi/zaraz/i.js" referrerPolicy="origin" />
</Head>
)}
{children}
<Context7Widget />
</>
Expand Down
21 changes: 17 additions & 4 deletions worker/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,18 @@ async function handleRequest(request) {

if (wantsMd || acceptsMd) {
const docsPrefix = '/docs/';
const stem = wantsMd
? url.pathname.slice(docsPrefix.length, -3)
: url.pathname.replace(/\/$/, '').slice(docsPrefix.length);
let stem;
if (wantsMd) {
// Support llms.txt spec: /docs/options/index.html.md → stem "options"
const indexHtmlMd = '/index.html.md';
if (url.pathname.endsWith(indexHtmlMd)) {
stem = url.pathname.slice(docsPrefix.length, -indexHtmlMd.length);
} else {
stem = url.pathname.slice(docsPrefix.length, -3);
}
} else {
stem = url.pathname.replace(/\/$/, '').slice(docsPrefix.length);
}
const branch = url.hostname === 'www-staging.marketdata.app' ? 'staging' : 'main';
const base = `https://raw.githubusercontent.com/MarketDataApp/documentation/${branch}`;
const candidates = [
Expand All @@ -104,8 +113,12 @@ async function handleRequest(request) {
const res = await fetch(candidate);
if (res.ok) {
const text = cleanMarkdown(await res.text());
const canonicalUrl = `https://www.marketdata.app/docs/${stem}/`;
return new Response(text, {
headers: { 'content-type': 'text/markdown; charset=utf-8' },
headers: {
'content-type': 'text/markdown; charset=utf-8',
'link': `<${canonicalUrl}>; rel="canonical"`,
},
});
}
}
Expand Down
Loading