Inject custom HTML, JavaScript, or CSS into any public page from the admin - no theme edits needed.
Three injection slots:
| Slot | Location | Typical uses |
|---|---|---|
| Head | Inside <head>, before </head> |
Google Analytics, custom fonts, meta tags, CSS overrides |
| Body start | First element inside <body> |
Google Tag Manager <noscript> snippet |
| Body end | Just before </body> |
Chat widgets (Intercom, Crisp), deferred scripts, tracking pixels |
- Contensio 2.0 or later
composer require contensio/plugin-code-injectionNo migrations required.
The service provider registers one callback on each of the three core frontend render hooks:
Hook::add('contensio/frontend/head', fn() => InjectionConfig::get('head'));
Hook::add('contensio/frontend/body-start', fn() => InjectionConfig::get('body_start'));
Hook::add('contensio/frontend/body-end', fn() => InjectionConfig::get('body_end'));Each callback is lazy - the database is only queried when the hook point is actually rendered. Empty slots return '' so no whitespace is emitted.
Code is stored in the core settings table (module = plugin_code_injection, setting_key = config) as a JSON blob.
Settings > Code Injection - three monospace textareas, one per slot. Saved with a single POST.
Code entered here is output unescaped directly into the page HTML - that is the entire point of this plugin. Only paste code from sources you trust. Access to this settings page requires admin privileges.
| Hook | Description |
|---|---|
contensio/frontend/head |
Inside <head> |
contensio/frontend/body-start |
After <body> opening tag |
contensio/frontend/body-end |
Before </body> closing tag |