Search code examples
apache.htaccessmod-rewriteurl-rewriting

For specific url 'www.example.com/mobile' I want url rewrite to another specific path: 'root_folder/mobile/index.html'


I created a website in Symfony and the mobile version in Ionic.

Now all URLs are redirected to /public/index.php.

I want to add another URL rewrite in .htaccess to redirect all www.example.com/mobile/* to ionic app that is in the root folder /mobile/index.html.

I already tried to add this in root_folder/mobile/.htaccess

RewriteEngine on

RewriteCond %{REQUEST_URI} !^/mobile/.*$
RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]

My root_folder .htaccess is:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /public/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.ch$
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|svg|webp|mp4|css|js|txt)$
RewriteRule ^(.*)?$ public/index.php [L]

<If "%{REQUEST_URI} =~ m#/mobile/?#i">
    RewriteCond %{REQUEST_URI} !^/mobile/.*$
    RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
</If>

Solution

  • RewriteCond %{REQUEST_URI} !^/mobile/.*$
    RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
    

    The RewriteRule pattern matches against the URL-path relative to the directory that contains the .htaccess file. So, the above RewriteRule will never match when inside the /mobile/.htaccess file. Likewise, the condition will never be successful, since if the .htaccess is triggered then /mobile/ must already be present in the URL-path.

    This is also an external 301 redirect, not an internal rewrite. It needs to be an internal rewrite (just like the rewrite to public/index.php in the root).

    However, presumably you also want static assets to be ignored and served directly, so you need exceptions for files (and optionally directories), just as you are doing in the root .htaccess file (when rewriting to public/index.php).

    Try the following instead, in the /mobile/.htaccess file:

    # /mobile/.htaccess
    
    RewriteEngine On
    
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.html [L]
    

    You don't need to specify /mobile in any of the directives since the RewriteRule pattern matches against the relative URL-path (as mentioned above) and the substitution string is (by default) relative to the directory that contains the .htaccess file.

    By default, the mod_rewrite directives in the /mobile/.htaccess file completely override the directives in the parent .htaccess file. The directives in the parent .htaccess file are not even processed.

    <If "%{REQUEST_URI} =~ m#/mobile/?#i">
        RewriteCond %{REQUEST_URI} !^/mobile/.*$
        RewriteRule ^mobile/(.*)$ /mobile/index.html [R=301,NC,L]
    </If>
    

    You should remove this <If> block in the root .htaccess file. (It's not actually doing anything.)