How to Debug CSS or JS Minification Issues in OpenMage: A Step-by-Step Guide

When CSS or JS minification fails in OpenMage, systematically verify module activation, observer registration, file permissions in media/fbminify, and the presence of the matthiasmullie/minify composer dependency, then check var/log/system.log for specific CssjsMinify: error messages.

The fballiano/openmage-cssjs-minify module optimizes frontend performance by intercepting the HTTP response via the http_response_send_before event, scanning for <script> and <link> tags, and rewriting URLs to point to minified copies stored in media/fbminify. When assets fail to minify or return 404 errors, use this structured debugging checklist to isolate configuration, permission, or code logic failures.

Understanding the Minification Flow

Before debugging, understand the execution path in app/code/community/Fballiano/CssjsMinify/Model/Observer.php. The httpResponseSendBefore method:

  1. Resolves the base directory using MAHO_PUBLIC_DIR or Mage::getBaseDir().
  2. Creates media/fbminify if it does not exist.
  3. Uses regex patterns to extract JS and CSS references from the HTML body.
  4. Generates a hash based on the file path and modification time (filemtime).
  5. Copies or minifies the file using the matthiasmullie/minify library.
  6. Replaces the original URL with the minified path.

10-Step Debugging Checklist

1. Verify Module Activation

Confirm the module is declared active in app/etc/modules/Fballiano_CssjsMinify.xml:

<config>
    <modules>
        <Fballiano_CssjsMinify>
            <active>true</active>
            <codePool>community</codePool>
        </Fballiano_CssjsMinify>
    </modules>
</config>

If <active> is false, the observer never registers.

2. Confirm Event Observer Registration

Check app/code/community/Fballiano/CssjsMinify/etc/config.xml for the http_response_send_before event binding:

<events>
    <http_response_send_before>
        <observers>
            <cssjsminify>
                <class>cssjsminify/observer</class>
                <method>httpResponseSendBefore</method>
            </cssjsminify>
        </observers>
    </http_response_send_before>
</events>

If this XML is malformed or cached, the minification logic never executes.

3. Validate Composer Dependencies

The module requires matthiasmullie/minify. Verify installation:

composer show matthiasmullie/minify

If the package is missing, minification fails silently or throws a class-not-found error in var/log/system.log.

4. Check Media Directory Permissions

The observer attempts to create media/fbminify in httpResponseSendBefore (lines 31-36 of Observer.php). If the web server user lacks write permissions to media/, minification fails.

Verify and fix:

ls -ld media/fbminify
chmod 775 media/fbminify
chown www-data:www-data media/fbminify

5. Verify Base Directory Resolution

The code determines the base path using MAHO_PUBLIC_DIR or falling back to Mage::getBaseDir() (lines 21-25 of Observer.php). If this resolves incorrectly (e.g., in a chrooted environment), file existence checks fail and assets are not processed.

Add temporary logging to Observer.php to verify:

Mage::log('BaseDir: ' . $baseDir, Zend_Log::DEBUG, 'minify_debug.log');

6. Inspect Regex Pattern Matching

The module uses regex to find assets:

  • JS: /<script[^>]+src=["\']([^"\']+\.js)[^>]*>/i (lines 38-44)
  • CSS: /<link[^>]+href=["\']([^"\']+\.css)[^>]*>/i (lines 68-74)

If your HTML uses non-standard attributes like type="module", rel="preload", or async/defer placed differently, the regex may fail to match.

Test your specific markup:

$html = '<script type="module" src="/js/app.js"></script>';
preg_match('/<script[^>]+src=["\']([^"\']+\.js)[^>]*>/i', $html, $matches);
var_dump($matches);

7. Review "Already Minified" Logic

Files containing .min. or .pack. in their names are copied directly rather than re-minified (method isAlreadyMinified, lines 12-15). If a file is named script.minified.js (not .min.), it will be processed through the minifier, potentially causing issues if the library expects pure JS.

Verify naming conventions:

find . -name "*.min.js" -o -name "*.pack.js"

8. Monitor Error Logs

All failures write to Magento logs with the prefix CssjsMinify:. Check:

grep "CssjsMinify" var/log/system.log
grep "CssjsMinify" var/log/exception.log

Common messages include:

  • Failed to create minified directory
  • Failed to minify JS
  • Failed to copy file

9. Verify File Timestamps

The generated hash includes filemtime() (lines 46-48 for JS, 75-77 for CSS). If your deployment process preserves old timestamps or uses a CDN that caches based on mtime, the module may serve stale minified copies.

Force regeneration by touching the source file:

touch js/sample.js

10. Check Cron Cleanup

The dailyCron job (defined in config.xml lines 27-36, implemented in Observer.php lines 101-135) removes old minified files. If the cron is not running or the schedule is wrong, stale files accumulate; if it runs too aggressively, it may delete files still referenced in cached HTML.

Verify cron status:

crontab -l | grep openmage

Practical Debugging Examples

Testing Regex Patterns Locally

If assets are not being detected, extract the exact HTML from your page and test against the module's regex:

<?php
// Test script for debugging asset detection
$html = file_get_contents('http://your-site.local/');
$jsPattern = '/<script[^>]+src=["\']([^"\']+\.js)[^>]*>/i';

if (preg_match_all($jsPattern, $html, $matches)) {
    echo "Found JS files:\n";
    print_r($matches[1]);
} else {
    echo "No JS files matched. Check your markup format.\n";
}
?>

Verifying Minifier Library Function

Test if the underlying minifier works independently:

<?php
require 'vendor/autoload.php';

use MatthiasMullie\Minify\JS;

$minifier = new JS('/path/to/your/test.js');
try {
    $minifier->minify('/path/to/output.min.js');
    echo "Minification successful\n";
} catch (Exception $e) {
    echo "Minification failed: " . $e->getMessage() . "\n";
}
?>

If this fails, the issue is with the library or PHP environment, not the OpenMage module.

Summary

  • Verify activation: Ensure Fballiano_CssjsMinify.xml has <active>true</active> and the observer is wired to http_response_send_before in config.xml.
  • Check dependencies: Confirm matthiasmullie/minify is installed via Composer.
  • Inspect permissions: The web server must write to media/fbminify, created dynamically in Observer.php lines 31-36.
  • Review regex matching: Standard JS/CSS detection patterns may miss type="module" or rel="preload" attributes.
  • Monitor logs: Search var/log/system.log for CssjsMinify: error messages indicating directory creation or minification failures.
  • Verify timestamps: The hash includes filemtime(); stale timestamps cause cached minified files to persist.
  • Test independently: Run the minifier library standalone to isolate environment issues from module logic.

Frequently Asked Questions

Why are my CSS and JS files not being rewritten to the media/fbminify path?

If URLs remain unchanged in the HTML source, the httpResponseSendBefore observer is likely not firing. Verify the module is active in app/etc/modules/Fballiano_CssjsMinify.xml and that the http_response_send_before event is correctly mapped to cssjsminify/observer::httpResponseSendBefore in app/code/community/Fballiano/CssjsMinify/etc/config.xml. Also clear the Magento configuration cache to ensure the XML changes are loaded.

How do I fix permission errors when the module tries to create the minified directory?

The observer attempts to create media/fbminify dynamically in Observer.php lines 31-36. If the web server user (e.g., www-data, nginx, or apache) lacks write permissions to the media/ directory, minification fails silently and logs an error. Run chmod 775 media/ and chown -R www-data:www-data media/ (adjusting the user for your environment), then verify the fbminify folder appears after reloading a page.

Why does the minifier work for some files but skip others?

The module uses regex patterns in Observer.php (lines 38-44 for JS, 68-74 for CSS) that may not match non-standard markup. Attributes like type="module", rel="preload", or async/defer placed before the src attribute can break the match. Additionally, files containing .min. or .pack. in their names are copied rather than re-minified via the isAlreadyMinified method (lines 12-15). Test your specific HTML markup against the regex patterns to confirm compatibility.

Where can I find error messages when minification fails?

All failure points in Observer.php write descriptive errors to the Magento log using Mage::log() with the prefix CssjsMinify:. Check var/log/system.log and var/log/exception.log for messages such as "Failed to create minified directory," "Failed to minify JS," or "Failed to copy file." Enable developer mode or temporarily add Mage::log() calls in httpResponseSendBefore to trace base directory resolution and regex match results if the standard logs do not provide enough detail.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →