I got an nginx vHost that hosts:

  • a CMS in /
  • a magento shop in /store

Things are running fine except one thing:

Removing index.php from the URL. At the moment the following URLs are working

example.com/store/index.php/my-funny-test-product.html and (as there are a few subshops in magento) 

Now I have to build a redirect so that the index.php can be stripped off the URL.

example.com/store/my-funny-test-product.html or example.com/store/city/my-funny-test-product.html

I got it to work on my local Apache with this .htaccess

RewriteEngine on
RewriteBase /store/

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule .* index.php [L]

Based on this I built the following rewrite

location /store {
   rewrite ^/store /store/index.php;

Now example.com/store/my-funny-test-product.html works but CSS images and the like are broken! I tried adding if (!-e $request_filename) to fix that but then got an nginx 40x error.

How can I achieve a working rewrite of example.com/store/my-funny-test-product.html and example.com/store/city/my-funny-test-product.html to the subfolder /store without breaking css & co and without having index.php in the URL?

Here's the full vhost config

    ## The whole setup stays close with the magento recommendations
    ## http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/configuring_nginx_for_magento

server {
    listen myip:80;
    server_name .example.com;

    root /var/www/mydomain/public_html;

    location / {
        index index.html index.php;
        try_files $uri $uri/ @handler;  

    ## here comes my rewrite stuff to remove index.php from the subfolder ##
   location /store {
       rewrite ^/store /store/index.php;

    ## followed by some deny rulesets not relevant here ##

    location @handler { ## Magento common front handler
        rewrite / /index.php;

    location ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
        rewrite ^(.*.php)/ $1 last;

    location ~ .php$ { ## Execute PHP scripts
        if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss

        expires        off; ## Do not cache dynamic content
        fastcgi_param  HTTPS $fastcgi_https;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  MAGE_RUN_CODE default; ## Store code is defined in administration > Configuration > Manage Stores
        fastcgi_param  MAGE_RUN_TYPE store;
        include        fastcgi_params; ## See /etc/nginx/fastcgi_params
  • Why are you trying to use rewrite at all instead of just try_files ? – AD7six Nov 22 '14 at 11:22
  • @AD7six Good point. I'll give it a try. Can you suggest something for this specific case? – Tsolen Nov 22 '14 at 11:29
  • try_files approach is for situations, where you are not sure where exaclty does the file exist. When you are sure some location does not have the specific script, it's useless and counterproductive to patch this with try_files (resulting in a bunch of redundant syscalls that nobody isn't need of) and you should point the nginx to a path where the file definitely is. probably with a rewrite. so the first method was right, and @AD7six personally neglects the Occam's Razor approach. – drookie Nov 22 '14 at 12:24
  • @EugeneM.Zheganin the code in the question currently uses try_files and rewrites I refer to this: try_files $uri $uri/ @handler; + location @handler { rewrite / /index.php; } is that your preferred Occam's Razor solution? There are more rules, but that should simply be try_files $uri $uri/ /index.php; or equivalent/very similar. Also note the purpose of the rewrite rules here comes my rewrite stuff to remove index.php from the subfolder - that's asking for an index directive. I encourage you to provide an answer if you still think I'm in some way suggesting complexity is better. – AD7six Nov 22 '14 at 12:33
  • 1
    You're trying to solve the wrong problem. Instead, you should configure Magento to not generate the links with index.php in the first place. – Michael Hampton May 22 '16 at 9:33

Now example.com/store/my-funny-test-product.html works but CSS images and the like are broken!

Use try files

Requests for css files (or, any actual files in /var/www/example.com/public_html/store) aren't working at the moment because the requeset is routed unconditionally to /store/index.php. The minimal change necessary to make that work - is to use try_files:

## here comes my rewrite stuff to remove index.php from the subfolder ##
location /store {
    # rewrite ^/store /store/index.php; NO
    try_files $uri /store/index.php;

In this way, if the following file exists:


Then the following url will return its content:


And any request starting with /store that does not directly map to a file will be passed to /store/index.php.


Then add the following code to this newly created .htaccess file

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]
  • 1
    Can you add some details to explain this code? – Pierre.Vriens Apr 15 '16 at 5:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.