Search code examples
.htaccessmobilehttp-status-code-404web-deployment

Webpage not found on mobile devices - 404


I was about to set up a website and have now uploaded it to the server.

While there are no problems displaying the page on desktop devices, a 404 error is issued on mobile devices. If I open the page in desktop view on mobile, the page is displayed.

diemoebelbewegung.de

The site does not use wordpress or similar CMS. I am not using an .htaccess file at the moment, could this be a problem?

I'm a complete beginner in server settings and just uploaded all the files. The site should be fully responsive.


Edit:

Found out that there has to be some kind of redirection of mobile devices to a subfolder /m .

So for now I just made a second copy of all files in this subfolder m. This solves my problem for now but not on long term.

Any ideas where this redirection of mobile devices to the subfolder m could come from? Or how to avoid having to store the files twice on the webserver.

Edit

May this be some serverside default redirective? And is there maybe a method to overwrite this with an .htaccess rule?

Another idea would be to redirect only Desktop devices to the subfolder /m

Edit

@MrWhite 's answer solves the problem provisional:

RewriteEngine on

# Required for the canonical redirect, if the trailing slash is omitted.
RewriteBase /

# Redirect any "direct" requests for the /m subdirectory back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^m(/.*|$) $1 [R=301,L]

# Rewrite all requests to the /m subdirectory (if not already)
RewriteRule !^m/ m%{REQUEST_URI} [L]

Still it is not clear why this 'redirection' to /m occurs at all.


Solution

  • One way would be to redirect only desktop devices to the /m directory and have all the content stored in /m. Is there a way to do so via .htaccess?

    In theory this should be possible as a "workaround". However, finding where this "redirect" (or rather "internal rewrite") is occurring and fixing that would be the preferred method.

    As noted, this does appear to be an internal rewrite to the /m subdirectory, not strictly a "redirect" (which implies an external 3xx HTTP redirect). There is no change in the URL. This is probably conditional based on the User-Agent string.

    Anyway, to implement this in .htaccess for all requests (ie. desktop as well) then you can do something like the following using mod_rewrite in the root .htaccess file:

    RewriteEngine on
    
    # Rewrite all requests to the /m subdirectory (if not already)
    RewriteRule !^m/ m%{REQUEST_URI} [L]
    

    This rewrites all requests to the /m subdirectory, so you only have one code base to maintain, ie. the one in the /m subdirectory.

    We can also "correct" any direct requests for the /m subdirectory and redirect back to the root, preventing a potential duplicate content issue with search engines. The following directive would need to go before the above rewrite (after the RewriteEngine directive).

    # Required for the canonical redirect, if the trailing slash is omitted.
    RewriteBase /
    
    # Redirect any "direct" requests for the /m subdirectory back to the root
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^m(/.*|$) $1 [R=301,L]
    

    The condition that checks against the REDIRECT_STATUS environment variable ensures we only target direct requests by the client and not rewritten requests.

    The $1 backreference in the substitution contains the URL-path less the m/ prefix (ie. the subdirectory). In situations where /m is requested without a trailing slash, the substitution string would otherwise be empty - hence the need for the RewriteBase directive to avoid a malformed redirect. (Alternatively, the RewriteRule directive could be modified to RewriteRule ^test(?:/(.*)|$) /$1 [R=302,L] to avoid the need for RewriteBase).

    IMPORTANT: Test first with 302 (temporary) redirects to avoid potential caching issues.

    Clear your browser cache before testing.

    Summary

    With all the directives in-place.

    RewriteEngine on
    
    # Required for the canonical redirect, if the trailing slash is omitted.
    RewriteBase /
    
    # Redirect any "direct" requests for the /m subdirectory back to the root
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^m(/.*|$) $1 [R=301,L]
    
    # Rewrite all requests to the /m subdirectory (if not already)
    RewriteRule !^m/ m%{REQUEST_URI} [L]
    

    Aside: I notice you are not currently canonicalising the www subdomain? ie. www vs non-www.


    UPDATE: An alternative method for the canonical redirect above to try:

    # Redirect any "direct" requests for the /m subdirectory back to the root
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/m(/|$)
    RewriteRule ^m(/.*|$) $1 [R=301,L]
    

    THE_REQUEST server variable contains the first line of the request headers as sent from the client. And should not change when the request is rewritten. However, if the request is being proxied then this probably won't work either.