Creating a home page dynamically in NextJs - javascript

I'm trying to create all my pages using NextJs with the slugs/uri I get when fetching the data, however when trying to create the home page it says.
Error: The provided path `/` does not match the page: `/[slug]`.
[slug].tsx is located in the page folder. I removed the index.js since I would like to have the home page the same page layout as other pages.
Currently getting the static paths like this:
export async function getStaticPaths() {
const allPages = await getAllPostsWithSlug();
return {
paths: allPages.edges.map(({ node }) => `${node.uri}`) || [],
fallback: true,
};
}
The error I got makes sense, but I couldn't really find a solution to create my home page in the same page template.

As per the documentation, you can use an optional catch-all route.
Name your page file [[...slug]].js, and then use something like the this for the paths prop in getStaticPaths:
paths: [
{ params: { slug: [] } },
{ params: { slug: ['foo'] } },
{ params: { slug: ['bar'] } },
]
FWIW - if you want to share components from the main template (i.e. header, nav, footer etc), I recommend using a custom _app.js page. If your homepage really is identical to your other pages, it might be worth re-visiting the design!
Good luck!

Since [...slug] is not the same as [slug] as it grabs sub-paths as well, you can achieve a closer match using just [slug].js and adding a rewrite to your next.config.js like so:
async rewrites() {
return [
{
source: '/',
destination: '/homepage',
},
]
},
Then you handle the homepage slug as your homepage, just like any other CMS page or post.
(/homepage can be anything you want, e.g. /index)

Related

Nuxt Dynamic routes returns 404 after static generation

guys. I have a shop page with two params: page and sort. like below:
example.com/shop/
example.com/shop/page/2/
example.com/shop/sort/newest/
example.com/shop/sort/oldest/page/2/
this is my route configs:
router: {
extendRoutes(routes, resolve) {
routes.push(
{
path: '/shop/sort/:sort/page/:page(\\d+)',
component: resolve(__dirname, 'pages/shop/index.vue'),
name: 'shop-sort-page',
},
{
path: '/shop/sort/:sort',
component: resolve(__dirname, 'pages/shop/index.vue'),
name: 'shop-sort',
},
{
path: '/shop/page/:page(\\d+)',
component: resolve(__dirname, 'pages/shop/index.vue'),
name: 'shop-page',
},
)
}
},
Now, after i generate my website, Nuxt doesn't generate sort pages. when i go to /sort/ or /sort/oldest/page/2/ it returns 404.
what do I need to do?
if I need to generate all these pages by myself, then what are these routes.push() used for?
I also want to add "name" and "filter" params. you see generating a dynamic route for all these parameters is impossible. what can I do?
thanks.
Im using Nuxt 2, by official doc, you need to add route for each parameter https://nuxtjs.org/docs/configuration-glossary/configuration-generate/#routes
For workaround solution, I may create a redirect page for dynamic page and url is
example.com/shop/redirect?page=2&sort=newest
In redirect page:
mounted(){
const p_page= this.$route.query.page
const p_sort = this.$route.query.sort
this.$router.push(`/shop/sort/${p_sort}/page/${p_page}`)
}

Language as param in Vue Router

I would like to have a language param in my path. For example if there is en before the path, print en.
If I enter http://localhost:8080/en it will give me en but if I enter http://localhost:8080/en/aaaa it will return me undefined
how can I get en anyway?
const routes = [
{
path: "/:lang?",
children: [
{
path: home,
component: home
}
]
}
]
router.beforeEach((to, _, next) => {
console.log(to.params.lang);
}
Under the assumption that you are planning on adding different language support for your app, I would recommend instead using i18n because it will abstract away things like appending params for different languages.
To your specific question on why you are getting undefined, that could simply be because there is no view page or route for the /aaa route. So Vue is just confused on where you want to go.
You can use pure javascript to get the current url and get the parameters through a split.
let myListParams = window.location.href.split('/');

Next.js overlaps static route with dynamic route

I am using Next.JS application routing system.
I have created a dynamic route with structure like pages/[country]/[language]/index.js.
Also there is a static route with structure pages/cz/cz/index.js.
Issue appears then i am on static page and trying to navigate throught Link component to access static route content in my case should go to home page & reload same page, instead of that dynamic route content is rendered.
In my case link is just simple navigation to home page <Link to="/"> for both routes.
But maybe issue lies on how index.js file is setup for predefined & dynamic routes.
cz/cz/index.js
export { default } from '../../../components/HomePage/';
const { getStaticProps } = createRoute({
path: '/',
locale: 'cs',
});
export { getStaticProps };
[country]/[language]/index.js
export { default } from '../../../components/HomePage/v2';
const { getStaticPaths, getStaticProps } = createRoute({
path: '/',
exclude: ['cs'],
otherLocales: ['cs'],
});
export { getStaticPaths, getStaticProps };
createRoute
export default function createRoute({
path,
otherLocales,
getPathParams,
locale,
} = {}) {
const locales = _.without(include, ...exclude);
return {
getStaticPaths: createGetStaticPaths({
locales,
getPathParams,
}),
getStaticProps: createGetStaticProps({
path,
locale,
locales,
otherLocales,
}),
};
}
Pages structure
So why [country]/[language]/index.js overrides cz/cz/index.js ?
So is there anything available in nextJS route to match a URL absolutely?
Or insure that going from static route should go to static route?
Following next.js documentation predefined routes take precedence over dynamic routes, and dynamic routes over catch all routes.
Take a look at the following examples:
pages/post/create.js - Will match /post/create
pages/post/[pid].js - Will match /post/1, /post/abc, etc. But not /post/create
pages/post/[...slug].js - Will match /post/1/2, /post/a/b/c, etc. But not /post/create, /post/abc
In your case you have defined predefined routes cz/cz/index.js and this route have priority
If you happen to be using redirects, note that they are processed before next ever goes to the pages.
Redirects are checked before the filesystem which includes pages and /public files.
https://nextjs.org/docs/api-reference/next.config.js/redirects

"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.

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!

Categories