vue-router with parameter can't run deploy on netlify - javascript

Home.vue
<template>
<h3>Home</h3>
</template>
Test1.vue
<template>
<h3>TEst page {{symbol}}</h3>
</template>
<script>
export default {
data() {
return {
symbol: this.$route.params.id
}
},
}
</script>
export default new Router({
mode: 'history',
routes: [
{
path: '/test/:id',
component: Test1
},
{
path: '/home',
component: Home
},
]
})
I can't call through the website [netlifylink/test/1]. It's "Page Not Found
Looks like you've followed a broken link or entered a URL that doesn't exist on this site".
But can still access localhost:8080/test/1
i call localhost:8080/home and [netlifylink/home] is work. why?
help me please.Sorry for grammar.

It's also in the Vue documentation deployment section
https://cli.vuejs.org/guide/deployment.html#netlify
In order to receive direct hits using history mode on Vue Router, you need to create a file called _redirects under /public with the following content:
# Netlify settings for single-page application
/* /index.html 200

There are special deploy instructions for SPAs on Netlify. On this page: https://www.netlify.com/docs/redirects/ if you go to the History Pushstate and Single Page Apps section you will see this:
If you’re developing a single page app and want history pushstate to work so you get clean URLs, you’ll want to enable the following rewrite rule:
/* /index.html 200
This will effectively serve the index.html instead of giving a 404 no matter what URL the browser requests.
You need to add this to the _redirects file under the root of your built site.

create a file called netlify.toml in the root of your project and then paste this:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200

Related

"TypeError: Failed to fetch dynamically imported module" on Vue/Vite vanilla setup

We have a vanilla Vue/Vite setup and I'm receiving TypeError: Failed to fetch dynamically imported module on sentry logs.
It seems like the errors are correlated in time with new deployment to prod, although I don't have enough data to confirm. It doesn't happen on local and appears only on deployed code.
I've seen some similar questions for react's setups, but none with a satisfactory response.
I've also found a similar question regarding dynamically imported svgs, but our errors happen for full components.
The only place where we use dynamic imported components is on routing:
export const router = createRouter({
history: routerHistory,
strict: true,
routes: [
{
path: '/',
name: routes.homepage.name,
component: () => import('#/views/Home.vue'),
children: [
{
path: '/overview',
name: routes.overview.name,
component: () => import('#/views/Overview.vue'),
},
// other similar routes
],
},
],
});
Our deps versions:
"vue": "^3.0.9",
"vue-router": "^4.0.5",
"vite": "^2.0.5",
Any additional information on this issue and how to debug it would be much appreciated!
When you dynamically import a route/component, during build it creates a separate chunk. By default, chunk filenames are hashed according to their content – Overview.abc123.js. If you don't change the component code, the hash remains the same. If the component code changes, the hash changes too - Overview.32ab1c.js. This is great for caching.
Now this is what happens when you get this error:
You deploy the application
Your Home chunk has a link to /overview route, which would load Overview.abc123.js
Client visits your site
You make changes in your code, not necessarily to the Overview component itself, but maybe to some children components that Overview imports.
You deploy changes, and Overview is built with a different hash now - Overview.32ab1c.js
Client clicks on /overview link - gets the Failed to fetch dynamically imported module error, because Overview.abc123.js no longer exists
That is why the errors correlate with deployments. One way to fix it is to not use lazy loaded routes, but that's not a great solution when you have many heavy routes - it will make your main bundle large
In my case the error was caused by not adding .vue extension to module name.
import MyComponent from 'components/MyComponent'
It worked in webpack setup, but with Vite file extension is required:
import MyComponent from 'components/MyComponent.vue'
I had the exact same issue. In my case some routes worked and some didn't. The solution was relatively easy. I just restarted the dev server.
The accepted answer correctly explains when this error is triggered but does not really provide a good solution.
The way I fixed this is by using an error handler on the router. This error handler makes sure that when this error occurs (so thus when a new version of the app is deployed), the next route change triggers a hard reload of the page instead of dynamically loading the modules. The code looks like this:
router.onError((error, to) => {
if (error.message.includes('Failed to fetch dynamically imported module')) {
window.location = to.fullPath
}
})
Where router is your vue-router instance.
My situation was similar.
I found that my Quasar setup works fine on the initial page but not page that are loaded dynamically through an import('../pages/page.vue');.
Short response:
I replaced import('../pages/TestPage.vue') in the middle of the route file by import TestPage from '../pages/TestPage.vue' at the top.
More detailed response:
In my situation I don't expect to have much pages, a single bundle with no dynamic loading is fine with me.
The solution is to import statically every page I need.
In my routes.ts I import all the pages I need.
import IndexPage from '../pages/IndexPage.vue';
import TestPage from '../pages/TestPage.vue';
Then I serve them statically in my routes :
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: 'test', component: () => TestPage },
{ path: '', component: () => IndexPage }
],
},
// Always leave this as last one,
// but you can also remove it
{
path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue'),
},
];
I recently expriencied this. The error was caused by an empty href inside an a tag: <a href="" #click="goToRoute">. You can either remove the href or change the a tag to something else, ie. button. Let me know if this helps.
I had the same problem. I found that I had not started my project.

NuxtLink redirecting to wrong url

I have a static generated Nuxt site. When I host it loaclly everything works fine but when I load it in GitHub Pages, NuxtLinks hrefs are not correct.
For example one of my link is:
<NuxtLink to="/iot">IoT</NuxtLink>
On localhost my site index is located in http://localhost:3000 and I correctly land on http://localhost:3000/iot.
On (since it's in a Repo) my site index is located in https://lorenzofiamingo.com/prisma/ and I land on in https://lorenzofiamingo.com/iot instead of in https://lorenzofiamingo.com/prisma/iot.
How can I amend this behavior (correcting the root)?
Configure router.base to set the base URL:
// nuxt.config.js
export default {
router: {
base: '/prisma/'
}
}

How to make path for pages in NextJS case insensitive

I have a file under the pages folder named about.tsx. So the path for the page is /about and I'm able to access the page by visiting example.com/about. However, if I visit example.com/About, it will redirect to a 404 page.
I've checked the Nextjs repo, seems like this is the expected behavior. Therefore, is there a workaround that can make the path case insensitive so that example.com/About will also work and direct users to the /about page?
With using next v12
There are a lot of similar questions here that has this answer already. I'd like to note that this answer is handling redirecting with the url parameters by adding this after the pathname:
${request.nextUrl.search}
Add a new file in /pages named _middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === request.nextUrl.pathname.toLocaleLowerCase())
return NextResponse.next();
return NextResponse.redirect(`${request.nextUrl.origin}${request.nextUrl.pathname.toLocaleLowerCase()}${request.nextUrl.search}`);
}
I agree that's Next.js's behavior, they only handle exact page name about instead of both about & About using the same file page/about.tsx
But the solution is you keep implementing a main page (e.g: about.tsx) and setup other pages to redirect to that page (e.g: About -> about) following this guide https://nextjs.org/docs/api-reference/next.config.js/redirects
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/About',
destination: '/about',
permanent: true,
},
]
},
}
// Set permanent:true for 301 redirect & clean SEO!

List of files instead of a rendered page when using electron-vue (vue.js with electron)

i am very new to vue.js and electron. I am trying to render a page with some javascript.
So i have these .vue files or components. these can contain only one script tag as far as i know. So whenever i add anything to the script. the application breaks and shows me a directory which shows me files
this is how the application apears if i don't modify the script in dashboard.vue
this is how it apears if i change anything in the script of dashboard.vue
The dashboard does not contain any script for now. But when i add a script tag this problem occurs.
my dashboard script is
<script>
export default {
name : 'Dashboard',
data(){
return {
msg : "Welcome"
}
}
}
</script>
This is how the router is configured . It works fine if i don't have a script tag in dashboard.vue
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Dashboard',
component: require('#/components/Dashboard').default
},
{
path: '/Products',
name: 'Products',
component: require('#/components/Products').default
},
{
path: '*',
redirect: '/'
}
]
})
I want to know why this error occurs. and i need to run some script when dashboard is loaded from vue router. I have tried looking up this issue. i can't find anything. I am not that familiar with webpack and vue-loader either. Though i have went through the documentation.

Dynamic import splits code but doesn't lazy load

I want to introduce lazy loading to Vue Router, so that some parts of the code will be loaded only on demand.
I'm following the official documentation for Lazy Loading in Vue Router:
https://router.vuejs.org/en/advanced/lazy-loading.html
So for a test I've changed how the Vault module is imported in my router file:
import Vue from 'vue';
import Router from 'vue-router';
// Containers
import Full from '#/containers/Full';
// Views
// TODO: views should be imported dynamically
import Dashboard from '#/views/Dashboard';
const Vault = () => import('#/views/Vault');
import Page404 from '#/views/Page404';
import Page500 from '#/views/Page500';
import Login from '#/views/Login';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
redirect: '/dashboard',
name: 'VENE',
component: Full,
children: [
{
path: 'dashboard',
name: 'dashboard',
component: Dashboard
},
{
path: 'vault',
name: 'vault',
component: Vault
},
],
},
{
path: '/login',
name: 'Login',
component: Login,
},
{
path: '/404',
name: 'Page404',
component: Page404,
},
{
path: '/500',
name: 'Page500',
component: Page500,
},
],
});
All fine, however, when I open the app for the first time, the extracted bundle which was supposed to be lazy loaded, is loaded up front:
When I go to that view using router it appears in Dev Tools Network Tab again, but says it's loaded from the disk, so the bundle is clearly loaded on first page load, which is totally against the idea of lazy loading.
This is occurring for a couple reasons. I should say, you've set everything up correctly for lazy-loading the Vault component. One tip, I've found it helpful to add the webpack chunk name to the dynamic import:
const Vault = () => import(/* webpackChunkName: "vault" */ '#/views/Vault')
This would then show up in your network tab named with the chunkName "vault"
First, I'm guessing that you're using #vue-cli looking at your file structure and /src alias. Depending on the options you select when creating your project, #vue-cli uses a webpack config for progressive web apps that prefetches all resources. While the browser has mechanisms for prioritizing these downloads, I've found that some of the prefetching appears to block other resources. The benefit of prefetching is for browsers that don't support service-workers, you use idle browser time to put resources in the browser cache that the user will probably eventually use. When the user does need that resource, it is already cached and ready to go.
Second, you do have options for disabling the prefetch plugin. #vue-cli provides escape hatches for overriding the default config. Simply edit or add vue.config.js to the root of your project.
courtesy #LinusBorg
// vue.config.js
chainWebpack: (config) => {
// A, remove the plugin
config.plugins.delete('prefetch')
// or:
// B. Alter settings:
config.plugin('prefetch').tap(options => {
options.fileBlackList.push([/myasyncRoute(.)+?\.js$/])
return options
})
}
-- Be sure to only use either option A or option B; not both. --
Source: https://github.com/vuejs/vue-cli/issues/979
I've used option A with success, but you should definitely benchmark the results yourself and go with the option that best serves your users and application.
I appreciate the configurability of #vue-cli for these and many scenarios. It's definitely worth exploring to write the application you want, rather than coercing your app to the config.

Categories