JavaScript
Rules marked [enforced] are caught automatically by ESLint (ddev npm run lint:js).
Naming conventions
Section titled “Naming conventions”| What | Convention | Example |
|---|---|---|
| Variable / function | camelCase | getPostData, postCount |
| Class | PascalCase | AjaxClient |
| Constant (module-level) | UPPER_SNAKE_CASE | MAX_RETRIES |
| File | kebab-case | ajax-client.js |
const over let [enforced]
Section titled “const over let [enforced]”Default to const. Only use let when the variable is reassigned. Never use var.
// Goodconst button = document.querySelector('.btn');let count = 0;count++;
// Badvar button = document.querySelector('.btn');let label = 'Submit'; // never reassigned — use constSemicolons
Section titled “Semicolons”End every statement with a semicolon.
// Goodconst greeting = 'hello';
// Badconst greeting = 'hello'Modules
Section titled “Modules”Use ES6 import/export instead of CommonJS. Each module lives in assets/src/js/modules/ and is loaded conditionally from site.js using loadIf.
Conditional loading
Section titled “Conditional loading”loadIf checks for a selector before importing the module. If the element isn’t on the page, the JS chunk is never fetched.
import { loadIf } from '@/lib/loadIf';
loadIf('.slider-example', () => import('@/modules/slider-example'));Module structure
Section titled “Module structure”Each module wraps its logic in an init function and calls it immediately. This allows early returns when required DOM elements are missing — top-level return is not valid in ES modules.
import 'swiper/css';import Swiper from 'swiper';
function init() { const el = document.querySelector('.slider-example'); if (!el) return;
new Swiper(el);}
init();Async / await
Section titled “Async / await”Use async/await instead of .then() chains.
// Goodasync function fetchPosts() { const response = await fetch(window.LUMBERMILL_GLOBAL.rest_routes.lumbermill_v1_posts); return response.json();}
// Avoidfetch(url) .then((res) => res.json()) .then((data) => console.log(data));jQuery or Vanilla JS
Section titled “jQuery or Vanilla JS”Per file, use either jQuery or Vanilla JS — avoid mixing the two in the same file.
ESLint
Section titled “ESLint”Config: eslint.config.js in the theme root. Run before committing:
ddev npm run lint:js
