Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Understanding Content Security Policy (CSP): registerInlineScript() in Detail

Understanding Content Security Policy (CSP): registerInlineScript() in Detail

~8 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026

The CSP variant of the Hyvä parent theme (chapter 3) ships with a strict Content Security Policy. This is an HTTP header mechanism that tells the browser exactly which script, style, and resource sources are even allowed to execute. For us as developers, that mainly means: inline <script> blocks don't work automatically.

Why inline JS is blocked by default

A strict CSP typically forbids arbitrary inline JavaScript, because it's one of the most common attack surfaces for cross-site scripting: if an attacker somehow manages to inject their own HTML into a page, an injected <script> tag must not simply be allowed to execute. Without CSP, that's exactly what would happen. With CSP, every allowed script must either come from a registered external file or be explicitly marked as trusted.

$hyvaCsp->registerInlineScript() in detail

Hyvä solves this with its own service, available in every template as $hyvaCsp. After every inline <script> block, $hyvaCsp->registerInlineScript() must be called - it generates a cryptographic hash of the exact script content and adds it to the CSP directive, so the browser is allowed to execute exactly this (and only this) script.

Correct pattern: inline script + registration
<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('teamFilter', () => ({
            activeCategory: 'alle',
        }));
    });
</script>
<?php $hyvaCsp->registerInlineScript(); ?>

Achtung: If the call to registerInlineScript() is missing, the browser blocks the script completely and silently on the frontend - all you'll see is a CSP violation message in the browser console, no PHP error. This is by far the most common beginner mistake in Hyvä projects with CSP (chapter 28 shows how to debug this specifically).

Why right after, not at the end of the file

The call deliberately sits directly after its matching <script> block, not collected at the end of the file: with several inline scripts in the same template, it's otherwise easy to lose track of which registerInlineScript() belongs to which script - and depending on the internal hash calculation, a wrong pairing can leave a script blocked even though it was "registered".

External script sources

For scripts from external sources (a CDN, third parties), a hash isn't enough - those need to be added as an allowed host source via etc/csp_whitelist.xml instead. In this project, though, the rule is: don't load extra external JavaScript, just use the Alpine.js already included with Hyvä - so this case rarely comes up in practice.

Inline style attributes and CSP

A strict CSP can also affect style="..." attributes. In this project, styling is consistently done through Tailwind classes instead of inline styles - that sidesteps the problem entirely, and it's the better practice with a utility-CSS framework anyway.