Issue with Vue application deployed to subdirectory when route changes from publicPath - vue.js

We have a Vue application that we're deploying to a subdirectory: /deploypath/
Right now, we have vue.config.js as:
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
publicPath: process.env.NODE_ENV === 'production'
? '/deploypath/'
: '/',
transpileDependencies: [
'vuetify'
]
})
Here's what's happening: In index.js (router) I have multiple paths configured to return multiple views and components. When a user is logged in, they can access additional pages. When they're not logged in, they're redirected to a (landing page).
I have multiple routes defined:
const routes = [
{
path: '/deploypath',
name: 'feature1',
component: FeatureOneView,
meta: {
title: 'Feature One',
}
},
{
path: '/deploypath/notloggedin',
name: 'notloggedin',
component: NotLoggedInView,
meta: {
title: 'Landing',
}
}
]
const router = new VueRouter({
mode: 'history',
routes: routes
});
Now, the issue I'm running into is that (after deploying a production build) when I visit /deploypath it works, however any other path (e. g. /deploypath/notloggedin) doesn't work. We have an Ubuntu instance running with nginx.
Are we doing something wrong with the Vue config or is there an issue on the nginx side, or other?

In case it helps anyone, a good buddy of mine helped find a solution:
cd /etc/nginx/sites-available
then:
sudo vim <insert your site's conf file here>
then press "i" to edit and within the top-level server { ... } section paste in (replace "dirname" with the name of the subdirectory you're hosting your Vue application in):
location ^~ /dirname {
try_files $uri /dirname/index.html =400;
}
then press escape (esc) on keyboard, then type ":wq" and press enter to save..
Then run:
sudo service nginx restart
then refresh your browser window and hopefully you see your Vue app!

Related

Vue + Express +GCloud routing breaks in App Service

I have a Vue3 + Express + Okta app. It works perfectly fine on local, but once I deploy it to Google Cloud's App Service I can only load the main page. Any navigation gives me 404.
I assume I am doing something dumb, but I've tried all I can think about to no avail. Help please?
Here's my router (I removed extra routes):
import { createRouter, createWebHistory } from "vue-router";
import AppHeader from "./layout/AppHeader";
import AppFooter from "./layout/AppFooter";
import Home from "./views/Home.vue";
import ListEpisodes from "./views/ListEpisodes.vue";
import { LoginCallback, navigationGuard } from '#okta/okta-vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
name: "home",
components: {
default: Home,
footer: AppFooter,
header: AppHeader
}
},
{
path: "/episodes",
name: "episodes",
components: {
header: AppHeader,
default: ListEpisodes,
footer: AppFooter
}
},
{
path: '/login/callback',
component: LoginCallback
}
]
})
router.beforeEach(navigationGuard);
export default router;
To deploy to GCP, I run npm run build for the frontend, then copy dist/ to my express app's static folder, then "gcloud app deploy".
The routing worked fine in GCP before I moved from vue2 to vue3 to integrate with okta. The extra stuff was history: createWebHistory() and router.beforeEach(navigationGuard);
Any ideas what can that be?
createWebHistory() was originally createWebHistory(process.env.BASE_URL). I thought maybe there's an issue there, so I tried creating .env file with BASE_URL=https://my_domain.
Then I removed the parameter - no difference on local, still didn't work on GCP.
Tried removing nocache from the express app as well, as that was another thing I changed before redeploying from working (vue2 many changes ago) version.
UPD: here's my app.yaml
runtime: nodejs16
service: default
instance_class: F2
Ok, I still don't know what is happening, but I found another way to do this: deploying api and frontend separately and then setting up the dispatch rules to connect Vue app to the backend.
I have used this guide with a few changes: https://medium.com/#rgoyard/how-to-deploy-a-single-page-application-and-its-backend-to-google-app-engine-353ff93bd38c
in vue.config.js for the Vue app remove/comment out the proxy redirecting to your api:
devServer: {
// proxy: {
// '^/api': {
// target: 'http://localhost:3000',
// changeOrigin: true
// },
// }
}
create frontend.yaml in the frontend dir, don't set any handlers:
runtime: nodejs18
service: default
Deploy frontend: gcloud app deploy frontend.yaml
Create api.yaml in the api dir:
runtime: nodejs18
service: api
Deploy api: gcloud app deploy api.yaml
Create dispatch.yaml in the root dir (or anywhere, really):
dispatch:
- url: '*/api/*'
service: api
Deploy dispatch rules: gcloud app deploy dispatch.yaml

Error to deploy my Vue3 app to Github Pages

I have uploaded my project with Vue3 to Github pages (check my repository), the branch is assigned to gh-pages and I have also uploaded the /dist folder, generated with the:
npm run build command.
I also modified the vue.config.js file with this data from my repository:
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: process.env.NODE_ENV === "production" ? "/pokevue/" : "/"
})
I have two questions:
The first is why isn't Vue working/loading in my web, if I followed the instructions in this guide correctly.
The second one is why this route does not show the "home" (it is broken, of course):
https://amoralesdesign.github.io/pokevue/
But when you click on the Pokémon logo it does redirect to my real Home, although if you reload the page it gives a 404.
You need to config your base router points to your github page path:
const router = createRouter({
history: createWebHistory(process.env.NODE_ENV === 'production' ? '/pokevue/' : '/'),
routes
})
The reason when you click on the logo your home page is showing is that in that case, the vue router will match your URL with the home page route.

Why is my Vue app redirecting to my Home route on refresh of any page?

This is similar to a lot of questions asked re: setting up Vue Router with an Express server using the connect-history-api-fallback middleware as directed in the Vue Router docs, but I’m still running into two issues:
When I refresh any page, I am redirected to my Home route (e.g. http://localhost:8080/451)
When I enter a direct link in the address bar (e.g. http://localhost:8080/451/alerts), I am also redirected to my Home route
I am not receiving a “Cannot GET /” error, so I am pretty confident that connect-history-api-fallback is implemented correctly.
For context, this is what my router looks like:
const router = new VueRouter({
base: __dirname,
mode: 'history',
routes: [
{
component: Home,
name: 'home',
path: '/:siteId',
},
{
component: SuperAdmin,
name: 'super-admin',
path: '/:siteId/super-admin',
},
{
component: Alerts,
name: 'alerts',
path: '/:siteId/alerts',
},
{
component: LPRAdmin,
name: 'lpr-admin',
path: '/:siteId/lpr-admin',
},
{
component: ControlCenterAdmin,
name: 'control-center-admin',
path: '/:siteId/control-center-admin',
},
],
});
And this is my configuration in the server:
const staticFileMiddleware = express.static('build/public');
app.use(staticFileMiddleware);
app.use(history({
verbose: true,
}));
app.use(staticFileMiddleware);
Has anyone dealt with and solved this or a similar issue? Thanks in advance!
For anyone who comes across this in the future, we were able to solve it! Somewhat embarrassingly, we forgot we were rerouting users to the home page after authentication every time the app mounted. We removed
this.$router.push(`/${siteId}`);
from our App.js and the issues are resolved!

VueJS app as subdomain throws 404 when a path is added

I have a portfolio site portfolio.com and a subdomain which points to a VueJS frontend hosted on Netlify vuejsapp.portfolio.com
Users upload files to the app and it generates a download link URL, say vuejsapp.portfolio.com/download/048677a. When I navigate to the link within the VueJS app (by clicking a button to redirect after it's uploaded) it redirects to the Download component without issue. But if I copy and paste that link directly in my browser it throws a 404 error. Why is this?
I know it has to do with a Vue Router configuration but I can't seem to find much information about it or perhaps I'm looking in the wrong place. Could someone tell me what I'm missing or point me to some relevant documentation please?
My router.js file:
Vue.use(Router);
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/",
name: "home",
component: Home,
},
{
path: "/about",
name: "about",
component: About
},
{
path: "/download/:id",
name: "download",
component: Download,
props: route => ({ id: route.params.id }),
}
]
});
Since the code/setup is running properly on your local environment and only breaking on Netlify its pretty clear that you're running into a wrong server configuration issue.
Your Netlify environment has to know that it should always route any requests to / and leave the routing to your Vue App. You can read more about how to resolve that in the Netlify docs.

VueJS + Webpack Dev Server not able to hot reload url subpaths

My application runs on the subdirectory http://localhost:8080/admin_suffix
suffix is a ENV variable which I can change and define in a .env file.
Once i run the webpack dev server, accessing http://localhost:8080/admin_suffix works.
Clicking on the hyperlinks in the SPA which points other subpaths works too. For example, I can navigate to http://localhost:8080/admin_suffix/subdirectory
However, when i hit reload on http://localhost:8080/admin_suffix/subdirectory, i will get an error "Cannot GET /admin_suffix/subdirectory"
I also cannot enter the subpath into the browser directly to load the page. Only ``http://localhost:8080/admin_suffix` works.
My configuration are as follows:
webpack.base.config.js:
entry: {
main: './src/main',
vendors: './src/vendors'
},
devServer: {
host: '0.0.0.0',
disableHostCheck: true
},
output: {
path: path.join(__dirname, '../dist')
}
webpack.dev.config.js:
module.exports = merge(webpackBaseConfig, {
output: {
publicPath: '/',
filename: '[name].js',
chunkFilename: '[name].chunk.js'
}
});
src/main.js:
const RouterConfig = {
mode: 'history',
routes: Routers,
base: '/admin_suffix/'
}
Enable devServer.historyApiFallback in webpack.base.config.js:
devServer: {
historyApiFallback: true,
// ...
},
This configures webpack-dev-server to fallback to index.html when the route is not found (404).
The Vue app and router are initialized from the main page (index.html), so refreshing the page while on a subroute would normally result in a 404 because the router would not have been setup yet. However, the fallback configuration mentioned above would result in the index.html being served instead, allowing the router to be setup and the subroute to subsequently complete.