Search code examples
wordpressvue.js.htaccessmod-rewritevuejs3

Wordpress at root and vue in sub dir. Masking of vue with wordpress URL. URL points root and page load is of vue


At root there is WordPress site. And in subdirectory calles 'vue' there is vue build is there. In wordpress URL if 'podcaster' or 'crowd' is not a part of a URL then I want to load vue page without changing browser URL.

Below is my folder structure enter image description here

Target is:

www.example.com/podcaster //display in the address bar, points to WP (var/www/html/)
www.example.com/crowd //display in the address bar, points to WP (var/www/html/)
www.example.com/username  //display in the address bar, points to VUE (var/www/html/vue)
www.example.com           //display in the address bar, points to WP (var/www/html/)

Below is the WordPress root directory .htaccess:

    # BEGIN WordPress
    # The directives (lines) between "BEGIN WordPress" and "END WordPress" are
    # dynamically generated, and should only be modified via WordPress filters.
    # Any changes to the directives between these markers will be overwritten.
        <IfModule mod_rewrite.c>
            Options +FollowSymLinks -MultiViews
            RewriteEngine On
            # Rewrite rule for vue
                RewriteCond %{REQUEST_URI} !^/crowd/
                RewriteCond %{REQUEST_URI} !^/podcaster/
                RewriteRule (.+) /vue/$1 [L]
        
            RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
            RewriteBase /
        
            RewriteRule ^index\.php$ - [L]
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule . /index.php [L]
        
        </IfModule>
        
        # END WordPress

Below is vue sub directory .htaccess:

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

Solution

  • You've not stated exactly what the problem is, however...

    RewriteCond %{REQUEST_URI} !/podcaster/
    RewriteRule ^(.*)$ /vue/$1 [L,NC]
    

    This will result in requests for the root being internally rewritten to the /vue subdirectory (I'm assuming you've placed this at the top of the WordPress .htaccess file in the root directory). You've stated that WordPress should be served from the root. In which case you should change the RewriteRule pattern from .* (0 or more) to .+ (1 or more) to avoid being triggered for requests to the root (base URL / homepage).

    You will also need to ensure that rewritten requests (by the WordPress front-controller - to index.php - in the code that follows) are not also rewritten (otherwise everything will ultimately be rewritten to the /vue subdirectory). We can do this by adding another condition that checks against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to 200 (as in 200 OK status) after the later rewrite.

    UPDATE: And I suspect you also have a number of static resources (CSS, JS, images, etc) that also need to be excluded, so we probably need to add a filesystem check for those, so the request is not rewritten if it already maps to a file (or directory).

    For example, bringing the above points together, this becomes:

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{REQUEST_URI} !/podcaster/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.+) /vue/$1 [L]
    

    I've removed the NC flag as that was superfluous here. Note also that the condition is successful when the string "/podcaster/" (note that slashes) does not appear anywhere in the URL-path. Should this not be restricted to the start of the URL-path perhaps? eg. !^/podcaster/.

    Also, where is the rest of the WordPress .htaccess file? The WordPress front-controller (the part that normally appears after the # BEGIN WordPress comment marker) should appear after your custom directive. If you place your custom rewrite at the end of the WordPress .htaccess file, after the WP front-controller section then your directive will not doing anything since all requests will be routed to WordPress.

    Note that you should place your custom directives before the # BEGIN WordPress comment marker. You should never edit the code between the # BEGIN WordPress and # END WordPress comments since this block of code is maintained by WordPress and your code could be overwritten when WP updates (unless you take additional steps to prevent this). There is no need to repeat the RewriteEngine or <IfModule> directives.

    Below is vue .htaccess which in "vue" sub directory

    <ifModule mod_rewrite.c>
        RewriteEngine On
      RewriteBase /vue/
      RewriteRule ^vue/index\.html$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /vue/index.html [L]
    </ifModule>
    

    The Vue .htaccess file isn't quite right (although should work OK). The first RewriteRule directive (which is simply an optimisation) should not include the vue subdirectory in the regex. In other words, it should be written:

    RewriteRule ^index\.html$ - [L]
    

    Since the URL-path that is matched is relative to the filesystem path that contains the .htaccess file.

    In fact, you can remove all instances of vue from this file (which makes it simpler and more portable), providing you also remove the RewriteBase directive entirely. For example:

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

    Relative substitution strings (ie. index.html in the 2nd RewriteRule directive above) are relative to the directory that contains the .htaccess file (providing you don't have a RewriteBase directive that states otherwise). So, the above naturally rewrites the request to /vue/index.html without having to explicitly state the directory.