Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue-router on apache, SPA in sub-directory, can only access pages by redirect

So I have a Vue app for a client set up on an apache dev server. I am doing this to match the production environment. The app is in a subdirectory and I set the 'base' option on vue-router to match. If I navigate to my virtual host root it redirects properly, however navigating to the same address by typing the address in gives a 404.

Here is my router code:

const routes = [
  {path: '/', redirect: '/london' },
  {path: '/:city', component: homeView}
]

const router = new VueRouter ({
  mode: 'history',
  routes,
  base: '/subdir/'
})

I also have the relevant Apaache .htaccess in the 'subdir':

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

So if I navigate to "cityapp.local/subdir" it redirects to "cityapp.local/subdir/london", but if I type "cityapp.local/subdir/london" I got the apache 404 page.

Any thoughts or help would be appreciated!

EDIT: If I set my virtual host to include the subdir and removed the base option from the router, everything works fine. However, I cannot do this on production so I hope this info helps a little.

like image 462
mtonc Avatar asked Aug 31 '18 16:08

mtonc


People also ask

What is redirect in VUE router?

A redirect means when the user visits /home , the URL will be replaced by / , and then matched as / . But what is an alias? An alias of / as /home means when the user visits /home , the URL remains /home , but it will be matched as if the user is visiting / .

How do I navigate to another page in Vue?

To navigate to a different URL, use router. push. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.

How does router-view work Vue?

Essentially, the router-view element gives Vue Router a location to render whatever component the current URL resolves to. For our example, we'll place it in the App. vue root component. Let's also add some links so that we can switch between our two routes.

Is Vue router client side?

Vue is primarily client side framework - rendering is done by JS running in the client's browser.


2 Answers

Jeez, was looking for a solution to this for a good chunk of time yesterday and today and just found the answer: Vue help forum: Vue webpack project path change

Relevant code for anyone else that my find this:

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

I honestly tried something similar yesterday. I changed the RewriteBase to the subdir but not the rewrite rules! I'm bad at .htaccesss stuff :(

like image 97
mtonc Avatar answered Nov 15 '22 21:11

mtonc


It can be a bug with your apache version.

RewriteRule of "^$" broke between 2.2.21 and 2.4.2 https://bz.apache.org/bugzilla/show_bug.cgi?id=53929

You can use Fallback ressource instead of mod_rewrite in your apache config. It works for me.

In /etc/apache2/apache2.conf

<VirtualHost *:80>
    ServerName YourServerName
    DocumentRoot /var/www/yourApp/dist
    <Directory "/var/www/yourApp/dist">
        FallbackResource /index.html
    </Directory>
</VirtualHost>
like image 37
Renan Bronchart Avatar answered Nov 15 '22 22:11

Renan Bronchart