Who this is for. Everyone who writes or reviews a theme. Later guides assume these rules without restating them. Some are the platform's own requirements, marked as such; the rest are the house style that keeps one theme readable to the next developer.
The rules
| Rule | Why | In depth |
|---|---|---|
SCSS with BEM class names: .card, .card__title, .card__title--large | Class names that say what they belong to and cannot collide between components | Styling |
| A bundle per page type: shared code in the main bundle, code one kind of page needs in its own entry | Each page loads only what it uses | Builds, bundles and script tags |
A nonce on every script tag: nonce="{$_inlineScriptNonce}". A platform requirement | The site's Content Security Policy refuses an inline script without it | Assets, CSP and the build pipeline |
| A cache-buster on every asset URL, usually the deployed commit | Browsers keep built files for a year | The build output is committed and served |
| The production build, committed with its source. A platform requirement | The server builds nothing; it serves what is committed | The build output is committed and served |
| No secrets in tracked files | The repository is copied to every developer and every environment that follows it | Configuration and secrets per environment |
Escape what you print: |escape in Smarty, |e in Twig | Neither engine escapes output for you on Core dna | Smarty and Twig side by side |
Links built from route names with _url, not typed paths | A site can change a module's prefix; a built link follows it | Global template variables |
The nonce, in both engines
The policy is the site setting CSP policy (Globals.security.cspPolicy); by default it allows scripts from the site itself, from cdnjs.cloudflare.com, and inline scripts that carry the request's nonce. The nonce changes on every request, so it is printed from _inlineScriptNonce, never copied: