Nginx: index.php URLs still being served alongside pretty URLs For whatever reason https://domain.com/index.php?p=path/to/whatever and https://domain.com/index.php/to/whatever both still work and are not being redirected or rewritten to https://domain.com/path/to/whatever/.

We are enabling these in our CraftCMS configuration:

'omitScriptNameInUrls' =&gt; true,
'usePathInfo' =&gt; true


But they have not rectified the issue. Does anyone have a solution to this? Here are the important parts of our current Nginx.conf. I appreciate any help I can get on this.

location ~ /.well-known {
    allow all;
}

location / {
    try_files $uri $uri/ @rewrites;
}

location @rewrites {
    rewrite ^(.*) /index.php?p=$1 last;
}

location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt  { access_log off; log_not_found off; }

error_log  /var/log/nginx/error_craft_https.log error;

error_page 404 /index.php;

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    include fastcgi_params;
}

location ~* (?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$ {
    deny all;
}

location ~* \.(?:manifest|appcache|html?|json|xml)$ {
    try_files $uri /index.php?$query_string;
    expires -1;
    access_log /var/log/nginx/access.log;
}

location ~* \.(?:rss|atom)$ {
    try_files $uri /index.php?$query_string;
    expires 1h;
    add_header Cache-Control "public";
}

location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|h$
    try_files $uri /index.php?$query_string;
    expires 1M;
    add_header Cache-Control "public";
}

location ~* \.(?:css|js)$ {
    try_files $uri /index.php?$query_string;
    expires 1y;
    add_header Cache-Control "public";
}

location ~* \.(?:ttf|ttc|otf|eot|woff)$ {
    try_files $uri /index.php?$query_string;
    expires 1M;
    add_header Cache-Control "public";
}
I fixed it by adding rewrite ^/index.php/(.*) /$1 permanent; to my server block. This will redirect all urls containing index.php and something after it to the contents after index.php.

E.g. /index.php/about will be permanently redirected to /about. Google knows that if something is permanently redirected its the same content and will only index the redirect.

There's one drawback though, because index.php is an actual file you can still access that. So you need to keep Disallow: /index.php into your robots.txt as well.