Customizing & Extending
Re-theme via LESS tokens, customize dark mode, add pages and locales, swap the API base, and consume the design-system in React/Vue.
You customize Taxi CRM 2026 at its source: the LESS tokens drive every edition's look, the PUG templates drive the HTML pages, and the shared design-system carries it all to React and Vue. This guide covers theming, dark mode, adding pages and locales, swapping the API base, and consuming the design-system in the Vite editions.
Theming via LESS tokens
The design tokens live in apps/html/assets/css/01-variable.less as flat LESS variables
(@name: value;). Editing them is the single highest-leverage way to re-theme: style.less
imports 01-variable.less along with ~70 other partials, and the design-system build extracts
those same variables into tokens.json / tokens.css for the React and Vue editions.
// apps/html/assets/css/01-variable.less
@primary: #4f46e5; // brand / accent colour
@app-width-lhs: 16rem; // sidebar width
@card-bg: #ffffff;
// …After editing tokens, rebuild so the change propagates:
npm run ds:build # extract tokens + compile style.css for React/Vue
npm run ship:html # recompile the static HTML edition's CSSbuild.mjs pulls the flat @name: value; variables (skipping mixins and interpolated maps)
into dist/tokens.json, and emits the same set as :root { --name: value; } in
dist/tokens.css. So a token edited once in 01-variable.less re-themes all three editions.
The full stylesheet structure, layout variables and palette classes are documented in
CSS System.
Don't hand-edit the compiled
dist/style.cssorapps/html/assets/css/style.css— they are regenerated from LESS on every build and your edits would be lost. Change the LESS source.
Dark mode
Dark mode is driven by a data-theme attribute on the <html> element — not a body class.
app.js reads the saved preference from localStorage and the header's #themeToggle button
flips it:
// what app.js does — you don't write this
document.documentElement.setAttribute('data-theme', 'dark'); // or 'light'
localStorage.setItem('theme', 'dark');To tweak dark-mode colours, scope your rules to the [data-theme="dark"] selector and
reuse the kit's theme variables rather than introducing new hex colours:
[data-theme="dark"] .panel-card { background: var(--card-bg); }
[data-theme="dark"] .my-custom-block { color: var(--text-primary); }For any new markup, prefer the theme CSS variables (--card-bg, --panel-bg, --input-bg,
--text-primary, --border-primary, …) over fixed colours so your additions follow the theme
automatically. See CSS System for the variable names.
Adding a page (HTML edition)
The HTML edition is compiled from PUG templates in apps/html/pug/. The fastest approach is to
copy the page closest to what you need:
- Copy a PUG template — e.g.
pug/roleMaster.pug→pug/myMaster.pug. Top-levelpug/*.pugfiles compile to.html; partials inpug/common_pagesare shared. - Edit the content block only; leave the shared header, sidebar and footer partials intact.
- Update the page header: the title and breadcrumb in
.page-header. - Link it from the sidebar:
app.jsactivates the sidebar entry whose link matches the current file, so add a menu entry pointing atmyMaster.html. - Wire
data-i18nkeys and add the matching locale file (next section). - Add a page script: create
assets/js/pages/<feature>/myMaster.jsand include it at the bottom of the page. Build the DataTable the way the existing scripts do — see Tables and JavaScript Helpers. - Add an endpoint: add the path to
API_CONFIG.endpointsinapp.js(and, to share it with React/Vue, toendpointsinapi-contract.mjs). See Data & API Integration. - Recompile:
npm run ship:htmlrenders the new PUG todist/public/.../myMaster.html.
Adding a locale or translations
The kit ships 8 languages (en, fr, de, es, pt, zh, ja, nl). Translations live in
apps/html/assets/locales/<lang>/ as JSON, auto-discovered at runtime via the locale manifest;
the design-system build copies the whole locales/ tree into dist/ so React and Vue get the
same files.
- New keys: add
data-i18n="myMaster.someKey"to your markup, then add the key toassets/locales/en/myMaster.json(and the other languages) and listmyMasterin that locale's manifest. Full rules in Internationalization. - New language: add its code to the
availableLocaleslist in the i18n module ofapp.jsand create a matchingassets/locales/<lang>/folder, then re-runnpm run ds:build.
Swapping the API base
You point any edition at your own backend in one place — see Data & API Integration for the full contract.
- React / Vue: pass a base to the shared helper —
createApi('https://api.yourcompany.com')— or keep the same-origin/apiand repoint the hosting rewrite. The default base is/apiin the browser andhttp://localhost:8080/apion localhost. - HTML: change
API_CONFIG.baseUrlinassets/js/core/app.js. - Auth header: replace
headers.x_pvr_tech_studio_access(api-contract.mjs) /API_CONFIG.headers(app.js) with your real header. It is sent on every call.
Consuming the design-system in React / Vue
The React and Vue editions don't re-implement styling — they import the compiled
@taxi-crm/design-system outputs. In the entry file:
// apps/react/src/main.jsx (Vue: apps/vue/src/main.js)
import '@taxi-crm/design-system/style.css'; // compiled LESS bundle
import '@taxi-crm/design-system/tokens.css'; // :root custom propertiesThen use the shared API contract and the kit's Bootstrap-5 classes in your components:
import { createApi, endpoints } from '@taxi-crm/design-system/api-contract';
const api = createApi();
export default function Drivers() {
const [drivers, setDrivers] = useState([]);
useEffect(() => {
api.get(endpoints.Driver.getDriver).then((res) => setDrivers(res.data || []));
}, []);
return (
<div className="card">
<div className="card-header"><h5 className="card-title mb-0">Drivers</h5></div>
<table className="table table-hover">{/* render res.data rows */}</table>
</div>
);
}Because both style.css and tokens.css originate from 01-variable.less, re-theming the
LESS tokens and re-running npm run ds:build restyles the React/Vue editions too — no
component changes needed. Components and widgets are plain Bootstrap 5 plus the kit's classes;
see Components and Widgets.
Where to go next
- The monorepo, build pipeline and deployment: Architecture & File Structure
- The data contract and mock API: Data & API Integration
- The stylesheet and theme variables: CSS System
- Shared helpers (HTML edition): JavaScript Helpers
Was this page helpful?
