0

I'm working with Craft CMS 5 using a local environment configured through DDEV, which defaults to NGINX. I typically work with Apache, so I've been adjusting my caching rules for NGINX to ensure static resources like images, CSS, and JavaScript files are properly cached. Here is the configuration I’ve implemented:

# Enable gzip compression for common text-based content
gzip on;
gzip_types text/html text/plain text/css text/javascript application/javascript application/json application/xml font/woff font/woff2;
gzip_min_length 1024;
gzip_comp_level 5;
gzip_vary on;

# Set cache control headers for all static assets (images, CSS, JavaScript, fonts)
location ~* \.(jpg|jpeg|png|gif|svg|css|js|woff|woff2|json)$ {
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

# Serve /templates/assets/js/ with cache headers via proxy
location ~* ^/templates/assets/js/(.*\.js)$ {
    proxy_pass http://127.0.0.1:8080/index.php?p=assets/js/$1;
    expires 1y;
    add_header Cache-Control "public, max-age=31536000, immutable";
    gzip on;
    gzip_types application/javascript;
    gzip_min_length 1024;
    gzip_comp_level 5;
    gzip_vary on;
}

Problem

This configuration works well for standard static assets. However, I have some JavaScript files generated dynamically through Craft CMS templates, which are served under /templates/assets/js/. For example, a file like /templates/assets/js/search.js relies on Twig templating within Craft.

Prior to adding this NGINX configuration, these files loaded correctly. Now, any attempt to access these JavaScript files results in 404 errors, as NGINX is looking for the actual files in /templates/assets/js/ rather than routing the requests to Craft's templating engine.

Attempts to Solve

  1. Adding specific routes in config/routes.php for these JavaScript files did not resolve the issue.
  2. Removing or adjusting the NGINX caching rules partially fixes the problem, but I lose caching for the rest of my static resources.

Question

What would be the best approach to configure NGINX to route these dynamic JavaScript files through Craft CMS without causing 404 errors, while still caching true static assets effectively?

Any guidance on modifying the NGINX configuration to handle these dynamic assets would be greatly appreciated. Thank you!

2
  • Worth noting that you aren't required to use the "correct" file extensions to request or send a given content type. Craft does make use of extensions when rendering templates to automatically send the correct headers… but you can do that yourself using the {% header ... %} tag: create /templates/assets/js/search.twig and place {% header 'Content-Type: text/javascript' %} at the top! Commented Nov 6, 2024 at 0:48
  • Additionally, this sounds a lot like what the try_files directive is for… When using regular expressions in location rules, the order of the rules also matters! Commented Nov 6, 2024 at 0:49

2 Answers 2

0

You don't need any fancy server trickery to make this work - As long as you don't prefix a directory with an underscore, Craft will automatically allow public routing from the root of your templates directory - therefore simply omit the templates/ prefix when referencing your JS file - i.e., access it at website.com/assets/js/search.js.

3
  • Actually, this isn't working for me—it returns a 404 for these files. If I disable gzip compression, the files become accessible. Commented Nov 5, 2024 at 16:28
  • Hm, I've tested it and it works ok for me. You probably have something else going on in your server config, or possibly there's some caching happening somewhere. Commented Nov 5, 2024 at 18:17
  • I tested the specified rule on a fresh project and still get a 404 Not Found, so I don’t think it’s project-specific. Oddly, the JS file is accessible directly via its URL, but including it in the page triggers a 404. The rest of my nginx-site.conf is from Craft CMS’s default DDEV configuration. Commented Nov 6, 2024 at 9:11
0

This issue arises in the context of a multi-site configuration in Craft CMS.

To properly reference the file, it’s necessary to contextualize the URL based on the current site:

{% do view.registerJsFile(siteUrl('/assets/js/search.js')) %}

Using siteUrl() here ensures that the URL is constructed relative to the current site.

Without this adjustment, a 404 error occurred, even though the file was accessible.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.