Nuxt 3 render same page on multiple routes - vue.js

I'm having a nuxt 3 app with file routing activated. I'm having a problem where I have two routes that should render the same dynamic page.
My pages directory looks like this:
This is how I want my paths render the pages:
(1) / --> [lang]/index.vue
(2) /DE --> [lang]/index.vue
(3) /EN --> [lang]/index.vue
(4) /DE/Header --> [lang]/Header/index.vue
(5) /EN/Header --> [lang]/Header/index.vue
Routes 2 to 5 render correctly. My problem is that route 1 renders /index.vue (which is an expected behaviour), but I want it to render the content from [lang]/index.vue. At the moment I copied the content to have it synced in both index.vue files, but I want to avoid copying the whole file.
I already tried a navigateTo() inside the root index.vue, but that causes both pages to render. Also, I tried to add some router options file like that:
export default <RouterConfig>{
routes: (_routes) => [
{
name: 'index',
path: '/',
component: () => import('~/pages/[id]/index.vue'),
},
],
}
but then no child routes are working anymore.
How can I achieve that route 1 (/) renders the page under pages/[lang]/index.vue?

Related

Nuxt Router Push without Changing Page

I have a homepage which is paginated, though when clicking "Next Page" it seems to be looking for a page named /page/1. Is there a way to paginate the index.vue page without creating a brand new page?
I've currently implemented the following on #click.
this.$router.push({
path: '/' + this.page,
query: { },
})
You can have dynamic parameters.
For example
url.com/1
url.com/2
So if your home page is index.vue, you need to create a vue file next to it for a dynamic parameter with name after an underscore, for example _id.vue
So the param after the root URL will be mapped to this page.
For more resources about file system and routing in NUXT

How to add page names in uppercase in nuxt without using router.js?

I am not able to make the page name as Index.vue but for other pages I did and it works.
Any idea how to resolve this one?
PS: For this project, I am preferring PascalCase for pages. I don't want to configure router.js manually.
Since Nuxt.js automatically creates the vue-router based on your /pages structure, if you really need to have a /Index route, you could create a folder called "Index", and then include your index.vue template there.
Then you're able to call the /Index route from nuxt-link:
<nuxt-link to="/Index">Click Me</nuxt-link>
first create a directory with name you want after create index.vue file in this directory
I think like this question you can make nuxt case-sensitive in routing
How to make routes case sensitive in Nuxt
By adding this code:
// nuxt.config.js
router: {
extendRoutes(routes) {
for (const key in routes) {
routes[key].caseSensitive = true
}
}
}

Vue components re-rendering on router push

I have created a global component that i share across multiple routes. i have simplified the component below for demonstration purposes.
#name area-wrapper
<template>
<div id="area">
<div id="area-menu">
<menu/>
</div>
<div id="area-content">
<slot/>
</div>
</div>
</template>
Within the menu is a navbar which has options that will change the content of the slot which i could just turn into a component v-bind:is component.
What i have done is created several page for the routing
pages
_entity <--*** forgot to include this ***
app
index.vue
_appId.vue
new.vue
Each of these pages includes the component above and then adds in their own content for id="area-content
What i have been noticing is that the entire area-wrapper is being reloaded when i move from
website.com/app/112 (pages/app/_appId.vue)
website.com/app/11 (pages/app/_appId.vue)
I have noticed that if i move the area-wrapper to a layout then it works the problem is that the component will eventually be shared with several apps but will have a different <menu/> and layouts do not have slots
I'm not sure why vue is re-rendering the entire component even though it is shared among all the pages and is the same across each page.
What am i missing here?
If this is expected behavior my question becomes, how can i create a shared component that acts like a layout that i include in several pages without adjusting the props and have it not constantly reload
+==== UPDATE ====+
i have been trying to get nest routes to work because i believe this is what i am after. However nuxt is not generating them correctly
Per the documentation(``) i need to change my stucture to
pages
_entity
messaging
settings
index.vue
msg
index.vue
messaging.vue(wrong - changed back to index.vue) -> within here add the <nuxt-child> component
messaging.vue(need to move to _entity folder to create children)
nuxt should create the child components. However it is still continuing to create full routes. i am using nuxt-i18n will that cause a problem?
routes
...
{
path: "/:entity/messaging/messaging",
component: _8a865700,
name: "entity-messaging-messaging___en"
}, {
path: "/:entity/messaging/:msg?",
component: _1ef926cc,
name: "entity-messaging-msg___en"
}, {
path: "/:entity/messaging/settings",
component: _7b358e6a,
name: "entity-messaging-settings___en"
}
I originally created the nested route within the folder.Instead, you need to put the parent page within the root of what directory the folder exists.
pages
_entity
messaging
settings
index.vue
msg
index.vue
messaging.vue(wrong - changed back to index.vue) -> within here add the <nuxt-child> component
messaging.vue(need to move to _entity folder to create children)
You should define routing in your app as suggested here (pure Vue) or here (with vue-router). Without it you are reloading a whole page (and the app) when you change the URL.

using vue-head with prerender-spa-plugin is causing title and meta tags to be displayed twice on netlify

This issue only happens when live on netlify ( despite their prerender option turned off ), not while being served locally.
the live site shows :
<title>about | anonplayer about | anonplayer</title>
title and meta tags are set using the vue-head package like so
head: {
title: {
inner: "about | anonplayer",
separator: ' ',
}, ...
and this happens for all routes of my single page app and also to meta tags where there are two sets of the tags I intended to have.
looks like this
I used the default prerender settings like so:
config.plugins.push(new PrerenderSPAPlugin({
// Required - The path to the webpack-outputted app to prerender.
staticDir: path.join(__dirname, 'dist'),
// Required - Routes to render.
routes: ['/', '/about'].concat(contracts.map(each => `/${each.abi}/${each.contract}`)),
}))
was the same, but with Angular
in my case helped replacing function this.meta.addTag() with this.meta.updateTag()
so think it's not hosting issue)

Opening a PDF file in another window with VueJS

In my previous Angular app I was able to open my resume in another window like such:
<a class="link popup" href="javascript:void(0);" onclick="javascipt:window.open('./../../assets/Resume_Christopher_Kade.pdf');">Resume</a>
While rewriting my website with Vue, I noted that it did not work as intended, after changing it to:
<a class="link popup" href="javascript:void(0);" v-on:click="openPdf()">Resume</a>
With openPdf() in my component's methods:
openPdf () {
javascipt:window.open('./../assets/Resume_Christopher_Kade.pdf');
}
When clicking the link, a new page opens to the following URL:
http://localhost:8080/assets/Resume_Christopher_Kade.pdf
while showing an empty route on my screen instead of displaying the pdf in the browser's pdf viewer.
This issue might be related to the way I handle routes in Vue:
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/work',
name: 'Work',
component: Work
},
{
path: '/posts',
name: 'Posts',
component: Posts
},
{ path: '*', component: Home }
]
})
Why isn't it as straightforward as in Angular? Am I missing something?
Did you figure it out?
My solution is for projects created with Vue CLI 3 running locally (I haven't built my project yet).
My issue was similar to yours. I just wanted <a> link that opened up my pdf file on a new tab but my url concatenated a single hash to my path and redirected me to my home page. And it was a surprisingly easy fix:
resume
Just a dot, forward slash, and my file name. And my file is located under root > public folder.
Relative Path Imports
When you reference a static asset using relative path (must start with
.) inside JavaScript, CSS or *.vue files, the asset will be included
into webpack's dependency graph...
https://cli.vuejs.org/guide/html-and-static-assets.html#relative-path-imports
Assuming that you have static folder generated by default by Vue CLI you can simply put the PDF there and do it as follows <a href="./../static/file.pdf" target="_blank">.