DfCustomCodeManager — Complete Guide
Install, configure and operate DfCustomCodeManager: built-in code editor, multi-channel containers, theme variables inheritance, 5-version history, safe mode and a library of 8 presets for Shopware 6.6 and 6.7.
DfCustomCodeManager brings a simple answer to a universal problem in Shopware shops: where to put, how to version and how to safely manage the custom CSS and JavaScript you always end up adding to a theme. The plugin offers a built-in code editor in the administration, a container system that groups SCSS or JavaScript snippets, and above all direct injection into the theme compilation via Shopware’s native events. The consequence: no extra file served, no additional HTTP request for the visitor, and your SCSS snippets automatically inherit the variables and mixins of the active theme. This guide covers installation, configuration, creating containers and snippets, theme compilation, version history, safe mode, the preset library, import/export and troubleshooting.
Installation
- Download the
DfCustomCodeManager-1.0.0.ziparchive from your DataFirefly account. - Install it via Administration → Extensions → My extensions → Upload extension, or unzip the
DfCustomCodeManagerfolder intocustom/plugins/. - Run installation and activation:
bin/console plugin:refresh bin/console plugin:install --activate DfCustomCodeManager bin/console cache:clear - On installation, the plugin creates its 4 tables (
df_ccm_container,df_ccm_container_sales_channel,df_ccm_snippet,df_ccm_snippet_version) and registers its subscribers on the theme compilation events. - Recompile the theme so it picks up the plugin:
bin/console theme:compile
Compatible with Shopware 6.6.x and 6.7.x on a single codebase (composer ^6.6.0 || ^6.7.0). The administration module is precompiled, no build is required. PHP 8.2+ required. SCSS compilation relies on scssphp/scssphp, already shipped by shopware/storefront. No additional Composer dependency.
Where to find the plugin in the administration
After activation, a Custom Code Manager entry appears in the Catalogues menu of the administration (orange icon, position 100). It’s the main screen: list of containers, search, filters, and the global actions Import, Export, Presets and Compile theme. All low-level configuration (safe mode, minify, banner) is done from Extensions → My extensions → DfCustomCodeManager → ⋯ → Configure.
If the entry does not appear after an update, run bin/console assets:install && bin/console cache:clear then reload the administration with a hard refresh (Ctrl+Shift+R).
Plugin configuration
The Shopware plugin configuration card exposes three simple but essential toggles:
- Safe mode (
DfCustomCodeManager.config.safeMode): disabled by default. When enabled, all containers are ignored at the next compilation, as if they were all inactive. It’s the safety net described below. - Minify JS (
DfCustomCodeManager.config.minifyJs): basic minification of the injected JavaScript. Useful in production, leave it disabled in development so you can read your snippets in the compiled bundle. - Add banner (
DfCustomCodeManager.config.addBanner): adds a/* DataFirefly Custom Code Manager */comment at the start of the injected code. Handy to quickly spot your snippets in the compiled bundle.
The mental model: containers and snippets
The plugin is organised in two levels:
- A container is a logical grouping: Summer 2026 promo, GTM analytics, Dark mode opt-in, CTA button A/B test… Each container has a name, a description, a priority, an active/inactive toggle and a sales-channel scope.
- A snippet is a unit of code inside a container. Type SCSS or JavaScript, name, code, priority, active/inactive toggle, Markdown notes, and a toggle to enable or not theme variables injection.
A container can hold several snippets of mixed types. It’s useful to group snippets that belong together: for example a Dark mode opt-in container with a SCSS snippet for the styles and a JavaScript snippet for the class toggle on html.
Creating your first container
- From Catalogues → Custom Code Manager, click New container in the top right.
- Give it an evocative name (e.g. Summer 2026 promo — sticky header & badge).
- Set the priority (leave it at 0 by default, increase it if you want this container injected later in the bundle and thus to override other styles).
- (Optional) Enable Limit to specific sales channels and pick one or more channels. If the option is disabled, the container applies to every channel.
- Fill in a description (internal notes, context, related ticket) — it will never be injected into the bundle.
- Save. You are now ready to add snippets.
Adding a SCSS or JavaScript snippet
In the Code snippets card of the container page, two buttons: Add SCSS and Add JavaScript. Each added snippet appears as a card with:
- A SCSS (info) or JS (warning) badge.
- A name field (only visible in edit mode).
- An active/inactive toggle.
- A Validate syntax button (✓).
- A History button (clock) — available as soon as the first save.
- A Duplicate button.
- A Remove button.
- A code editor with syntax highlighting adapted to the type.
- A Markdown Notes area to document what the snippet does.
The code editor natively uses the mt-code-editor component introduced in Shopware 6.7 (based on Meteor). On Shopware 6.6, the plugin automatically falls back to sw-code-editor (the older Ace-based component). As a last resort (if no component is available), a monospace textarea takes over — no syntax highlighting but perfectly functional.
Compile the theme
A saved snippet is not yet visible on the storefront until the theme has been recompiled. Two ways to do this:
- From the administration, the Compile theme button (top right of the list, or in the container page). A notification confirms the end of the operation.
- From the command line:
bin/console theme:compile
At compile time, the plugin listens to three Shopware events and injects your snippets there:
ThemeCompilerEnrichScssVariablesEvent— captures the SCSS variables map of the active theme. This is what allows your SCSS snippets to use$sw-color-brand-primary,$font-family-base, etc.ThemeCompilerConcatenatedStylesEvent— appends your compiled SCSS at the end of the main stylesheet.ThemeCompilerConcatenatedScriptsEvent— appends your JavaScript at the end of the main scripts bundle.
The result: zero additional HTTP request served to the visitor, your code goes through the whole Shopware optimisation chain (concatenation, minification, cache fingerprinting).
Theme variables and mixins inheritance
By default, every SCSS snippet benefits from an automatic preamble containing every variable and mixin exposed by the active theme and its theme plugins. So you can write in a snippet:
.header {
background: $sw-color-brand-primary;
font-family: $font-family-base;
transition: $transition-base;
}
…without importing anything manually, exactly as in a theme SCSS file. If for any specific reason (variable conflict, self-contained snippet) you want to disable this inheritance on a given snippet, uncheck the Theme variables available toggle in the snippet card footer.
Multi-channel scope
In the Scope & sales channels card of the container, enable Limit to specific sales channels and pick the relevant channels. The container will then only be injected in theme compilations for those channels. Very useful for:
- A promo banner reserved to a secondary brand store.
- A tracking script specific to one market.
- An A/B test on a single channel to measure impact.
Load priority
Priority is an integer (default 0) that controls the injection order in the compiled bundle: the higher the value, the later the code is injected, and therefore the more it can override what comes before. Priority exists at two levels:
- Container level: order between containers.
- Snippet level: order between snippets inside the same container.
The final order is: (container priority, snippet priority) ascending. Simple advice: leave everything at 0 by default, only use priority when you really need to override something.
Version history
On every snippet save, the plugin automatically creates a version in the df_ccm_snippet_version table. The last 5 versions per snippet are kept (the oldest is dropped when the threshold is reached). To browse and restore a version:
- On the snippet card, click the History icon (clock).
- A modal opens with the list of versions: date, author, comment and preview.
- Click Restore next to the desired version — the snippet code is immediately replaced by the one from the version. A new version is created to record the restoration.
- Save the container and recompile to see the effect.
For longer histories, the full journal stays in the df_ccm_snippet_version table (old versions are only hidden from the modal). A developer can very easily extend VersionTracker::MAX_VERSIONS_PER_SNIPPET if needed.
Safe mode: the emergency safety net
Safe mode is a global toggle in the plugin configuration. When enabled, every container is ignored at the next compilation, without changing any data. Typical use:
- A poorly tested snippet breaks something in production at 10pm.
- Go to Extensions → My extensions → DfCustomCodeManager → ⋯ → Configure.
- Turn on the Safe mode toggle and save.
- Recompile the theme:
bin/console theme:compile. - The storefront is back to its native state (no snippet injected). You can now identify and fix the offending snippet calmly.
- Once fixed, turn safe mode off and recompile again.
Safe mode is an emergency tool, not an operation mode. Once the incident is resolved, remember to disable it, otherwise none of your containers will be injected.
Preset library
The Presets button (from the container list) opens a library of 8 containers installable in one click:
- Sticky header — header that transforms on scroll (
is-stickyclass added above a threshold). - Back to top — back-to-top button, visible past a certain scroll point.
- Cookie banner skin — re-skinning of the native cookie banner to align with your branding.
- Product badge — New — “New” badge on recently created products.
- Free shipping bar — free shipping progress bar at the top of the page.
- Rounded buttons — rounded buttons across the whole shop.
- GTM DOM-ready event — fires a custom event once the DOM is ready, to prime your data layers.
- Fade-in on scroll — progressive fade-in of elements as you scroll.
Clicking Install creates the container and its snippets in the database. You just need to recompile the theme to see them go live. Preset-created containers are containers like any other: you can edit them, extend them, disable them, delete them.
JSON Import / Export
To migrate snippets between environments (dev, staging, production) or between stores:
- Export — select one or more containers in the list (checkboxes), then click Export. A JSON file is downloaded, containing all selected containers with their snippets, their priority, their notes — and the format version number (
EXPORT_VERSION = 1) for backward compatibility. - Import — on the destination environment, click Import and pick the JSON file. Containers and snippets are recreated identically.
Import does not touch existing containers (no merge by name): it always creates new entries. If you want to overwrite an existing container, delete it manually before importing.
Syntax validation
The ✓ Validate syntax button on each snippet card triggers a server-side validation without saving anything. Depending on the type:
- SCSS — the plugin runs a dry compilation via
scssphp/scssphpwith the theme variables preamble injected. If compilation passes, the snippet is valid. Otherwise, errors are reported in an error area on the card (line number, message). - JavaScript — the plugin strips strings and comments from the code, then checks the balance of braces
{}, parentheses()and brackets[]. This check does not replace a real ECMAScript parser, but it catches 90% of copy-paste errors (forgotten brace, unclosed string). To go further, validate your JavaScript in a dedicated tool before pasting.
Technical architecture
For developers who want to understand or extend the plugin:
- Root PHP namespace:
DataFirefly(sub-namespace:CustomCodeManager, classes undersrc/). - Plugin class:
DfCustomCodeManager(extendsShopwareCoreFrameworkPlugin). - SystemConfig prefix:
DfCustomCodeManager.config.*. - Tables:
df_ccm_container,df_ccm_container_sales_channel,df_ccm_snippet,df_ccm_snippet_version. - Migrations:
Migration1779580800CreateCcmContainerTable,Migration1779580801CreateCcmSnippetTable,Migration1779580802CreateCcmSnippetVersionTable. - Services:
CodeCompiler(orchestration + cache),SnippetExporter(JSON import/export),SnippetValidator(syntax validation),VersionTracker(snapshot + restore + trim). - Subscribers:
ThemeCompilerSubscriber(the 3 compilation events),SnippetWrittenSubscriber(auto snapshot on write). - Private API routes under
/api/_action/df-ccm/(scopeapi):validate,export,import,restore-version,recompile,presets.
All service declarations are explicit in services.xml (no autowiring) to stay aligned with DataFirefly conventions.
Extending the administration module
The administration module is compiled and placed under Resources/public/administration/js/df-custom-code-manager.js. It is precompiled in the ZIP and requires no local build. To extend it, find the components (df-ccm-list, df-ccm-detail, df-ccm-snippet-card, df-ccm-code-field, df-ccm-preset-modal, df-ccm-version-modal) and customise via Shopware’s standard override system (Component.override).
FAQ and troubleshooting
My snippets do not appear on the storefront. Did you recompile the theme? Until theme:compile has been run after a change, nothing changes. Also check that the container and the snippet are active, that the relevant sales channel is in scope (if scope is restricted), and that safe mode is not enabled.
SCSS compilation error in the console after theme:compile. Most often it’s a theme variable that doesn’t exist (typo) or a SCSS snippet that opens a block without closing it. Disable the offending snippet, recompile to confirm, then fix at your own pace. The syntax validation on the snippet card catches most of these cases before save.
The Custom Code Manager menu does not appear in the admin. Run bin/console assets:install && bin/console cache:clear then reload the administration with Ctrl+Shift+R. The module is under the Catalogues group.
The code editor shows a textarea without highlighting. This is the fallback when neither mt-code-editor (6.7) nor sw-code-editor (6.6) is available. Check your Shopware version and that the administration module is properly loaded.
I want to temporarily disable all snippets without deleting anything. That’s exactly safe mode. Toggle in the plugin configuration, recompile, done.
The “Compile theme” button spins forever. Check the Shopware logs. Compilation can take time on a large theme; in case of a real freeze, the usual cause is a SCSS snippet that loops or contains an unknown variable. Turn on safe mode, recompile, then re-enable the snippets one by one to identify the culprit.
My JavaScript snippet does not trigger. Remember that the injected code runs in the global bundle, so in a different context from regular Shopware JavaScript plugins. To interact with the storefront JavaScript plugins, listen instead to document.addEventListener('DOMContentLoaded', …) or the global events the storefront emits.
What happens on uninstall? During plugin:uninstall, Shopware displays the standard Keep user data checkbox. If it’s unchecked, the plugin drops its 4 tables and all related data (containers, snippets, versions, channel links). If it’s checked, the tables stay in place and you’ll find your snippets back if you reinstall the plugin later.