This is the Broxy website - a static landing page for Broxy, a tool that turns any webpage into an MCP server. The project uses pure vanilla HTML, CSS, and JavaScript without any build system or framework.
This is a static website with no build system. To preview locally:
# Using Python (if available)
python3 -m http.server 8000
# Using Node.js npx (if Node.js is available)
npx serve .
# Using PHP (if available)
php -S localhost:8000Then open http://localhost:8000 in your browser.
No automated tests or lint commands are configured. Manual testing by opening the site in a browser is the primary verification method.
www/
├── index.html # Main landing page
├── script.js # Core functionality (theme, language, UI interactions)
├── i18n.js # Internationalization (zh/en translations)
├── styles.css # Styling with light/dark theme support
└── assets/
├── broxy-v1.user.js # Tampermonkey userscript
├── data.js # Broxy configuration data (routes/tools)
└── logo.png # Logo image
- Variable declarations: Use
constfor constants,letfor variables that will be reassigned. Avoidvar. - Functions: Use function declarations for hoisted functions, arrow functions for callbacks and short utilities.
- Naming conventions:
camelCasefor functions and variablesPascalCasefor constructor functions (not used in this project)UPPER_SNAKE_CASEfor constants (not used in this project)
- DOM elements: Prefix with descriptive names, use
elor element type (e.g.,btn,copyBtn) - Event handlers: Prefix with
initfor setup functions (e.g.,initCopyButton,initTryButton)
// Good
const copyBtn = document.querySelector('.copy-btn');
function getTheme() { ... }
const toggleTheme = () => { ... };
// Avoid
var x = document.querySelector('.copy-btn');- Comments are sparse in this codebase
- When used, comments may be in Chinese or English
- JSDoc-style comments are used for documenting public APIs (see
script.jsheader)
- Naming: Use lowercase with hyphens (e.g.,
.flow-box,.install-tab) - CSS Variables: Define theme colors in
:rootand override in[data-theme="dark"] - Selectors: Prefer class selectors over tag selectors
- Organization: Group related styles with comment headers (e.g.,
/* Hero */,/* Controls */) - Responsive: Use
@media (max-width: 768px)for mobile styles
:root {
--bg: #ffffff;
--text: #000000;
}
[data-theme="dark"] {
--bg: #000000;
--text: #ffffff;
}- Indentation: 2 spaces
- Data attributes: Use
data-*attributes for JavaScript hooks and i18n - Semantic elements: Use appropriate semantic elements (
<main>,<section>,<footer>) - Meta tags: Include Open Graph and Twitter Card meta tags for social sharing
<button id="lang-toggle" class="ctrl-btn" title="Language">EN</button>
<p data-i18n="tagline">Turn any webpage into an MCP server</p>- Translation keys use dot notation (e.g.,
features.api.title) - Keys are defined in
i18n.jsas nested objects - Elements with
data-i18nattribute are auto-translated on language change
const i18n = {
zh: {
features: {
api: { title: '对外接口', desc: '...' }
}
},
en: {
features: {
api: { title: 'API Endpoint', desc: '...' }
}
}
};- Use try/catch for async operations that may fail
- Log errors to console with descriptive messages
- Provide user feedback for failed operations (e.g., copy failed)
try {
await navigator.clipboard.writeText(code);
} catch (err) {
console.error('Copy failed:', err);
}- Use
querySelectorandquerySelectorAllfor element selection - Use optional chaining (
?.) when accessing potentially null elements - Use
classList.add/remove/togglefor class manipulation
document.getElementById('theme-toggle')?.addEventListener('click', toggleTheme);
btn.classList.add('hidden');- Use prefixed keys to avoid collisions (e.g.,
broxy_theme,broxy_lang) - Check for null/undefined before using stored values
const stored = localStorage.getItem('broxy_theme');
if (stored) return stored;- Theme is stored in localStorage as
broxy_theme - Falls back to system preference via
prefers-color-scheme - Applied via
data-themeattribute on<html>element - CSS variables change based on theme
- Language stored in localStorage as
broxy_lang - Falls back to browser language (
navigator.language) - Applied by iterating
[data-i18n]elements and settingtextContent
The window.BroxyDev object exposes:
getTheme(),setTheme(theme),toggleTheme()getLang(),setLang(lang),toggleLang()getSettings()- returns{ theme, lang }getBrowserInfo()- returns browser/page metadata
- Modern browsers (ES6+ support required)
- No transpilation or polyfills
- Uses modern APIs:
localStorage,clipboard.writeText(),matchMedia()