Problem/Motivation
Follow-up to #3381293: Aggregation not working css and js cache directories not being created. When a web server (e.g. nginx) is not configured to pass requests for aggregated asset files to Drupal's PHP controllers, CSS/JS aggregation silently fails. The aggregated files are never generated because the asset delivery controllers (CssAssetController, JsAssetController) are never invoked, and the page renders without optimized assets. There is currently no feedback to the site administrator that their server configuration is incompatible with asset aggregation.
Steps to reproduce
- Use a web server configuration that serves the
assets://directory (typicallysites/default/files/assets/) directly from the filesystem without falling back to Drupal's front controller for missing files (e.g. an outdated nginx template missing thetry_filesdirective for the assets path). - Enable CSS and/or JS aggregation at
/admin/config/development/performance. - Observe that pages render without aggregated CSS/JS — the assets are never generated.
Proposed resolution
Add client-side validation on the Performance settings page that probes the server configuration when aggregation checkboxes are enabled. The validation issues a lightweight HEAD request to a URL under the asset controller routes:
- The existing
AssetControllerBase::deliver()is extended to detectHEADrequests and return an immediate200 OK— confirming that the web server correctly forwarded the request to PHP. - If the web server is misconfigured (serving the assets directory directly from the filesystem), the non-existent file produces a
404, which the client-side script detects.
This approach reuses the existing asset routes without introducing new endpoints. The HEAD method is ideal because:
- It tests the exact same
try_files/rewritepath that real asset GET requests use. - It avoids the overhead of theme initialization, library resolution, and hash computation.
- It provides an unambiguous
200 OKsuccess signal instead of relying on400 Bad Requestas a proxy for "reachable".
Remaining tasks
TBD;
User interface changes
When a user checks the "Aggregate CSS files" or "Aggregate JavaScript files" checkbox on the Performance page, a status message appears inline indicating whether the server configuration supports asset aggregation.
API changes
-
Data model changes
-
Release notes snippet
-
| Comment | File | Size | Author |
|---|
Issue fork drupal-3384272
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
volegerThe idea is to check the response status.
If the server is configured to return the file's content directly without passing a request through the PHP application on an empty file, the status code 404 will be returned.
In other cases, the controller will generate the aggregated file if files exist to aggregate or status code 400 if the aggregation file fails to be generated. In short, a response status code is different from 404.
I provided initial implementation. Feedback is welcome.
Comment #4
catchCould we also do this for image styles?
Comment #5
smustgrave commentedImage styles would be amazing as that's bit me before.
Moving to NW for a change record though for the new setting.
Comment #6
orkutmuratyilmazbrilliant feature! thanks for the development:)
Comment #7
zcht commentedThe feature is really great, at this point a note that the patch is not compatible with Drupal 10.2. see details here in the issue: #3409219: system.performance.yml no longer considered after update
Comment #8
socialnicheguru commentedI received two errors:
admin/config/development/performance|Warning: Undefined variable $config in Drupal\system\Form\PerformanceForm->buildForm() (line 170 of d10.2.x/html/core/modules/system/src/Form/PerformanceForm.php
admin/reports/status|1||Error: Call to a member function get() on null in Drupal\system\Form\PerformanceForm->buildForm() (line 170 of d10.2.x/html/core/modules/system/src/Form/PerformanceForm.php)
Comment #9
volegerThanks for the feedback. Adding new form elements to the config form was not the best idea.
So, I removed the validation button and performed validation on the appropriate checkbox checked change state.
Please review.
Comment #10
volegerRegarding #5: I filled the follow-up issue #3418840: Allow to validate Apache/Nginx configuration for image style files access for image style validation as it requires a different approach and different change scope to implement the new validation feature.
Comment #11
volegertest cases using different
NGINX_VHOST_PRESETenv var inDocker4Drupaldevelopment stack:-
drupal9ordrupal8validation will show the warning regarding server requirement;-
drupal10validation will show that server configured properlyComment #12
yannickooIn case you need to apply the patch for a
10.1.xDrupal you can find the patch attached 😇Comment #13
smustgrave commentedBelieve next step would be to get test coverage added.
Comment #14
socialnicheguru commentedit would be nice to know which tests are failing
Comment #15
socialnicheguru commentedI get a js error in the console and this error in my logs:
https://mysite/css/_validate.css|https://mysite/admin/config/development/performance|1||Symfony\Component\HttpKernel\Exception\BadRequestHttpException: The theme must be passed as a query argument in Drupal\system\Controller\AssetControllerBase->deliver() (line 132 of d10.2.x/html/core/modules/system/src/Controller/AssetControllerBase.php).Comment #16
d.stoyanov commentedAdding the current state of the MR so that I can use it from composer patches securely.
Comment #17
volegerUpdated IS
Comment #18
volegerFixed base assets controller check issues. Maybe it's worth updating to use the existing system library files for testing.
Current behavior looks like this (GIF).
Attaching the patch from the latest MR version.
Comment #19
volegerComment #20
dcam commentedThis was tagged for needing tests. I'm setting the status back to Needs Work for those to be added.
Comment #23
majid.ali commentedI have added test as mentioned in #20. 1 PHPUnit Functional Javascript 2/3 test failing but its irrelevant to the changes done here. Changing status to needs review.
Comment #24
smustgrave commentedSorry can the summary be updated, not super clear based on the description vs MR. Example I see a new system.library entry but nothing is calling it.
Comment #25
volegerComment #26
smustgrave commentedThis one seems close but not super clear. CR mentions it could be validated but how? There are no screenshots or steps that mention that. Same for summary here, so tagging for such
But rest appears addressed and seems close!