Nuxt error.vue on live server not working - error-handling

I think I have a rather simple question, but I can't wrap my head around this problem.
Reproduction:
Localhost: I made an error.vue in the layouts folder, as mentioned by Nuxt in their docs. When I go to localhost/this-is-a-404, the error.vue file is showing as expected!
screenshot from the localhost
Live server: When I upload my dist (ssr) via FTP, everythings works fine except the error.vue page. Is has no styling and I think it's the default error page for any page.
screenshot from the live server:
error.vue
<template>
<div class="hero alternate b-white">
<div class="container">
<section class="columns hero-top">
<div class="column is-7 is-offset-1">
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="90" fill="#DBE1EC" viewBox="0 0 48 48" id="error-icon">
<path d="M22 30h4v4h-4zm0-16h4v12h-4zm1.99-10C12.94 4 4 12.95 4 24s8.94 20 19.99 20S44 35.05 44 24 35.04 4 23.99 4zM24 40c-8.84 0-16-7.16-16-16S15.16 8 24 8s16 7.16 16 16-7.16 16-16 16z" />
</svg>
<h1 class="basic-padding-bottom-small" v-if="error.statusCode === 404">Ooops... <br>Deze pagina bestaat niet!</h1>
<h1 v-else>Ooops... <br> er ging iets fout!</h1>
<div class="button-group ">
<nuxt-link to="/" class="button smoke">
Terug naar home
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" class="feather feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</nuxt-link>
</div>
</div>
</section>
</div>
</div>
</template>
<script>
export default {
name: 'NuxtError',
props: {
error: {
type: Object,
default: null
}
},
computed: {
statusCode() {
return (this.error && this.error.statusCode) || 500
},
message() {
return this.error.message || '<%= messages.client_error %>'
}
},
head() {
return {
title: this.message,
meta: [{
name: 'viewport',
content: 'width=device-width,initial-scale=1.0,minimum-scale=1.0'
}]
}
}
}
</script>
<style lang="scss">
#import "assets/scss/app.scss";
#error-icon{
margin-bottom: 40px;
}
</style>
Am I missing something?
Thanks in advance!
Aaron

Try adding the following to your nuxt.config.js:
generate: {
fallback: true
}
Here's the nuxt explanation about that in the how to deploy on Netlify page. Even though you're not deploying on Netlify, the issue could be the same.
For a single page app there is a problem with refresh as by default on netlify the site redirects to "404 not found". For any pages that are not generated they will fallback to SPA mode and then if you refresh or share that link you will get Netlify's 404 page. This is because the pages that are not generated don't actually exist as they are actually a single page application so if you refesh this page you will get a 404 because the url for that page doesn't actually exist. By redirecting to the 404.html Nuxt will reload your page correctly in SPA fallback.
The easiest way to fix this is by adding a generate property in your nuxt.config and setting fallback: true. Then it will fallback to the generated 404.html when in SPA mode instead of Netlify's 404 page.
Also, I wouldn't upload my dist folder via FTP, as that would only get the generated stuff to your server. Anything dynamic won't be there.
I recommend having the entire app in the server, preferably with a version control (git). Also, if you have a pipeline built in place where you're always auto deploying a certain branch, it would make your life much easier.

Related

Nuxt3 - NuxtLink to anchor not scrolling on click or page refresh

I'm simply trying to have a page scroll to an anchor point in Nuxt3 and nothing I can do will get it to work. It doesn't scroll on click, or on page refresh with the anchor in the url.
<nuxt-link :to="{path: '/', hash: '#projects'}">Let's go</nuxt-link>
Tried a bunch of other SO answers, adding custom scrollBehaviour code to the nuxtConfig didn't work and trying to install vue-scrollTo in Nuxt3 just gave me this error when running the app with the vue-scrollTo module
ERROR Cannot restart nuxt: serialize is not defined
Any help would be greatly appreciated!
Full code
<script setup>
import '#/assets/css/main.css';
const { data } = await useAsyncData('home', () => queryContent('/').find())
const projects = data
</script>
<template>
<div>
<div class="flex flex-col h-screen">
<div class="lg:p-20 p-10 text-white bg-orange-500">
<p class="font-playfair lg:text-7xl text-4xl mb-5">Kia Ora, my name is <span class="font-medium italic">George Bates</span></p>
<p class="font-lato lg:text-3xl text-xl mb-5">Content creator and web developer in Auckland, New Zealand</p>
</div>
<div class="lg:p-20 p-10 text-white flex flex-grow" style="background-image: url('images/header.jpg'); background-position: center; background-size: cover;">
<nuxt-link :to="{path: '/', hash: '#projects'}">Let's go</nuxt-link>
</div>
</div>
<main class="lg:p-20 p-10" id="projects">
<p class="text-3xl font-playfair mb-5 font-semibold pb-2 text-orange-500">Some of my work</p>
<Projects :projects="projects" />
</main>
</div>
</template>
You said that you already tried to add a custom scrollBehavior, but how did you do that?
I'm very new to Vue & Nuxt, but thanks to this Github answer, you can customize the scroll behavior, and this works for me:
File app/route.options.ts:
import type { RouterConfig } from '#nuxt/schema';
// https://router.vuejs.org/api/#routeroptions
export default <RouterConfig>{
scrollBehavior(to, from, savedPosition) {
return {
el: to.hash,
behavior: 'smooth',
};
},
};
(Here I put a smooth behavior, but default seems to be auto)
And with a sample of code like:
...
<NuxtLink :to="{path: '/', hash: '#anchor'}">Let's go!</NuxtLink>
...

Issues with downloading a PDF after deploying Vue.js app

So I'm creating a Vue.js web app to act as my resume. On there, I want users to be able to actually download a copy of my resume, but I can't seem to get it working correctly. On my Home.vue page, I have:
<template>
<div class="flex-grow overflow-auto max-h-screen w-full dark:text-gray-300">
<div class="m-auto pt-4 lg:grid lg:grid-cols-2 lg:grid-rows-2 lg:gap-8">
<div class="m-auto">
<img class="rounded-md" alt="headshot" src="../assets/headshot.jpg">
</div>
<div class="m-auto">
<h2 class="text-2xl pl-2 py-4 text-center lg:text-left lg:text-8xl lg:px-8">Quick blurb</h2>
</div>
<div class="lg:col-span-2 mx-auto lg:h-8">
<p class="text-base text-center lg:text-2xl">
Email
|
LinkedIn
|
GitHub
|
<a href="my_resume.pdf" download>Resume</a>
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
When I'm running it locally, I have no issue downloading it. When I run yarn build and run a server from dist/, I have no issue downloading it. It's only when I deploy it on AWS Amplify and test it from there do I run into the issue (basically acting like it can't find it). I've tried putting
<a href="/my_resume.pdf" download>Resume</a>
as well as
<a :href="`${publicPath}my_resume.pdf`" download>Resume</a>
....
data () {
return {
publicPath: process.env.BASE_URL
}
}
to no avail. It's in the public/ folder, along with the index.html and an icon that it has no issues accessing. I have no idea what the issue is.
I dont know what version of vue you use and how did you configure your webpack, so i dont know if my solution is gonna work for you, but here i go:
Add assets folder to your public folder and add in it your pdf:
example
2.to your source folder add file vue.config.js if its not already there: example
define assets as your assets folder in your vue.config.js:
module.export ={
assetsDir: 'assets'
}
<a href="assets/my_resume.pdf" download>Resume</a>
here is the documantation: https://cli.vuejs.org/config/#assetsdir

Nuxt.js could not found component with errors "Failed to mount component: template or render function not defined."

I am having problems with my Nuxt.js site.
I have defined a page, with a dynamic slug param, like this:
/solutions/:slug
If I visit the page directly in the browser, it loads correctly!
But if I click the nuxt-link in my NavBar component, I get the following error in the console, and the page does not load:
vue.runtime.esm.js?2b0e:619
[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<Nuxt>
<Layouts/default.vue> at layouts/default.vue
<Root>
I have a default layout file that looks like this:
layouts/default.vue
<template>
<div>
<NavBar />
<Nuxt />
</div>
</template>
<script>
import NavBar from "~/components/Layout/NavBar"
export default {
components: {
NavBar,
},
}
</script>
My navbar contains the following nuxt-link:
components/Layout/NavBar.vue
<template>
<b-navbar wrapper-class="container" fixed-top>
<template slot="end">
<nuxt-link
:to="{
name: 'solutions-slug',
params: { slug: 'performance' },
}"
class="navbar-item"
target="self"
>
<span class="icon is-medium">
<i class="ic ic--larger ic-b1-graph-bars-chart-rise" />
</span>
<span class="label">
Performance
</span>
</nuxt-link>
</template>
</b-navbar>
</template>
I have a page, defined by the slug param:
pages/solutions/_slug.vue
<template>
<div class="solution">
This is my solution page.
</div>
</template>
I am trying to understand why clicking the nuxt-link fails to load the page, even though I see the URL change in the browser correctly.
Thanks
After version v2.13, Nuxt can auto-import your components when used in your templates.
check the nuxt.config.js if components attribute is true then you don't need to import your component on the .vue files.
in your layouts/default.vue remove script tag ;-)
<template>
<div>
<NavBar />
<Nuxt />
</div>
</template>
If you need to categorize your components by folder, do the following.
goto nuxt.config.js and change your components attribute
export default {
components: {
dirs: [
'~/components',
{
path : '~/components/site/',
prefix: 'Site'
},
{
path : '~/components/admin',
prefix: 'Admin'
},
{
path : '~/components/admin/sub',
prefix: 'AdminSub'
}
]
}
}
for example, we have these components :
components
| site
- header
| admin
- header
- footer
| sub
- header
- footer
when we need to call components just separate prefixes and component names with a dash or write camelcase.
in your layouts/default.vue remove script tag ;-)
<template>
<div>
<!-- with dash -->
<site-header></site-header>
<admin-header></admin-header>
<admin-sub-header></admin-sub-header>
<!-- cammel -->
<SiteHeader></SiteHeader>
<AdminHeader></AdminHeader>
<AdminSubHeader></AdminSubHeader>
</div>
</template>
Attention: For Root Components /components/nav.vue, We Must Use CammelCase <Nav/> and if we call this component like this <nav/> it doesn't work.
Probably the problem is not related to anything described above.
First, check if your configuration is correct. I see you are using 'nuxtjs/content' module, so you are probably using Contentful as well. In the past, I have encountered a similar situation ('Failed to mount component: template or render function not defined' issue) due to incorrect installation of the 'dotenv' module that I used to store variables.
In my case, the application did not load variables from the .env file. As a consequence, they went to the Contentful client unidentified and caused the js error. For some reason, this error did not always appear in the console. Instead, the above-mentioned Warn appeared.
Make sure you have the 'dotenv' module correctly installed (if you use it). I remember that in my case it was necessary to install 'nuxtjs/dotenv' instead of the usual dotenv.
Let me know if this is the case. Good luck

nuxt code splitting doesn't work properly

I'm just starting with nuxtjs, i have 2 pages
-index
-map
map page has one component, which is client only
and the default layout has links to the 2 pages, just the basic setup
the production build generates code split for the vendor per page but both files loads at the first page, i can't find what am i missing.
map page
<div class="container">
<client-only>
<Map />
</client-only>
</div>
</template>
<script>
import Map from '~/components/Map.vue'
export default {
components: {
Map
}
}
</script>
<style>
</style>
index page
<template>
<div class="container">
<h1 class="h-1">test hello page index</h1>
</div>
</template>
<script>
export default {
components: {
}
}
</script>
<style>
</style>
default layout
<template>
<div>
<nuxt-link to="/">home</nuxt-link>
<nuxt-link to="/map">map</nuxt-link>
<nuxt />
</div>
</template>
<style>
</style>
This is because nuxt-link prefetches the page it is linked to when it appears inside the viewport.
It's for performance reason and should not impact the initial loading of the page, since the prefetching is done during idle time.
If you would like to verify that what you are seeing is because of the prefetching, you can disable prefetching on per link basis by adding a no-prefetch attribute to nuxt-link or configuring router in nuxt.config.js
// nuxt.config.js
export default {
router: {
prefetchLinks: false
}
}
This is done only if user is on good network connection and not using save data mode. And, since this is done in browser's idle time, I'd suggest, leave it like this. Should not hurt.

fa icons are replaced by svg in laravel and vue js [duplicate]

I have en issue with angular and font awesome. On first generation of list of icons suddenly all css class based icons are translated to svg. It affects only solid icons. for example :
<i class="fas fa-2x fa-minus-square"></i>
is translated somehow to
<svg _ngcontent-c16="" class="svg-inline--fa fa-minus-square fa-w-14 fa-2x"
ng-reflect-ng-class="fas fa-2x fa-minus-square" aria-hidden="true" data-prefix="fas" data-icon="minus-square"
role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg="">
<path fill="currentColor"
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z">
</path>
</svg>
<!-- <i _ngcontent-c16="" class="fas fa-2x fa-minus-square" ng-reflect-ng-class="fas fa-2x fa-minus-square"></i> -->
Is there any option which can prevent this situation? Force somehow translation?
It can be problematic. For example I cannot use solid icons :(
If you'd like Font Awesome not to automatically replace <i> tags that look like icons with the corresponding <svg>s, you could change the configuration to disable autoReplaceSvg.
If you're loading via <script> tag, that might look like this (make sure to do the config before loading Font Awesome):
<head>
<script type="text/javascript">
// Notice how this gets configured before we load Font Awesome
window.FontAwesomeConfig = { autoReplaceSvg: false }
</script>
<script src="fontawesome.js"></script>
<script src="fa-solid.js"></script>
</head>
Or if you're building your own bundle and can access the config from within your own script you could do this:
import fontawesome from '#fortawesome/fontawesome'
fontawesome.config = { autoReplaceSvg: false }
I had the same issue, the icon tag was actually translated to SVG when I inspected the element.
The problem was I was loading fontawesome both via CSS and JS calls. When I removed the call to the JS lib and only called the CSS file, the icons rendered properly.