NEXTJS error: export encountered error on following paths [duplicate] - reactjs

I'm trying to build my Next.js project but it keeps giving me this error in the terminal:
Error: Build optimization failed: found page without a React Component as default export in
pages/components/context/Context
That's the React context API file, there isn't supposed to be any default export there. Is this a bug or what?

You should move your components outside the pages folder. pages/ should only be used for page components as Next.js routing is based on its structure.
Next.js has a file-system based router built on the concept of pages.
When a file is added to the pages directory it's automatically available as a route.
By default, Next.js assumes anything under the pages folder is a page component and will try to build each file as a page.
Even though the above is the default behaviour, you can configure your Next.js app to include non-page files in the pages directory.
To do so, you can modify the pageExtensions entry in the next.config.js file as shown below. Then rename your page components to have a file extension that includes .page (_document.page.js, _app.page.js, index.page.js, etc).
module.exports = {
pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js']
}
With this configuration, Next.js will ignore any file that doesn't contain .page for the purpose of building pages/API routes and routing.

In my case, I had an empty file index.js in a folder. Using Nextjs Default Router

It seems to be not declared default export keyword in context component.
Try it as follow:
const Context = ()=>{
...
}
export default Context

I had the same error.
If you comment out all other code but leave this NextJS won't get mad at you:
export default function Home1() {
return <>{/* nothing */}</>;
}
I like to keep older index files and components locally and on github so this is a nice hack. I just copy all of the existing code add it to a new file and then add 1 to it for example:
index1.js
You can also leave a comment to kind of bring you and other devs up to speed as to why you did this for example:
//good for history of index implementation and associated syntax logic

Related

Share i18next translations between nextjs and component workspaces

We have a yarn 2 monorepo setup with the following workspaces:
/root
/app (nextjs)
/components (individual react functional components)
/storybook
/constants
Currently, /app has the i18next translation files stored local to the workspace, but I would like to move that into the constants workspace so that all workspaces can share the same translations. I had no issue moving the translations there and loading them in both the /app and /storybook workspaces.
Also, currently, all translations happen only in /app. The /components workspace has no translations, and the translated text is passed in props to the dumb components. So, a component in /app looks something like this:
import ListBox from "#root/components/ListBox";
import {useTranslation} from "react-i18next";
export default const Page() {
const [t] = useTranslation();
const label = t("listBoxLabel"); // <-- exists in en.json as a key
return (
<div>
<ListBox label={label} />
</div>
)
}
As such, storybook also has to provide the "label" prop to render the component in stories, doing this in pretty much the same manner.
What I would like to do is instead translate the text at the /components workspace level, so that the translations can be done in one place, where it's used, to reduce prop drilling and also simplify things.
Something like this:
/components/ListBox.js:
import {useTranslation} from "react-i18next";
export default const ListBox() {
const [t] = useTranslation();
const label = t("listBoxLabel"); // <-- exists in en.json as a key
return <p>{label}</p>
}
When I run this code, it just prints out the translation key "listBoxLabel", in both storybook and the nextjs app.
I was able to fix storybook by wrapping stories with I18nextProvider and changing the dependencies in the /components workspace for i18next and react-i18next to move them from a normal dependency to a peer dependency, and storybook properly renders the translation. However, then the NextJS /app throws an error that the react-i18next Module Not Found when it imports the /components/ListBox.js code. It seems to require the /components workspace keep a normal dependency for that, but doesn't translate it in that case. If I remove the /components dependencies altogether, /storybook won't compile and start for the same reason.
Duplicating this exact code in the app or storybook, however, displays the correct translation. So, it has something to do with importing it from a sibling workspace in the monorepo, and I'm not sure exactly how to go about fixing that for the nextjs app.
Just a note: I don't use the next-i18next component. Instead, I am simply using react-i18next directly, without any providers configured. I did attempt to wrap the app with the I18nextProvider component similar to the storybook stories, but it didn't work.
Does anyone have any ideas where to look further or what to try for this? I would think loading a component from a workspace component library where the translations happen within the library would be a common scenario, but I haven't been able to find anyone else running into this issue.
I don't know exactly what's causing this, but it appears to be a nextjs, webpack, or yarn bug. I discovered the problem was related to this in my tsconfig.js file in the #root/app workspace:
{
"compilerOptions": {
"paths": {
"#root/components/*": ["../components/*"]
}
}
}
I was able to fix this by removing this setting, but it broke other code (some components were typescript), so I just explicitly declared those component modules in the custom.d.ts file as modules.
Where the next/yarn bug comes in: after I removed this line, and restarted the dev server, the i18n translations were still broken. Until I went and touched the components/ListBox.js file. This caused something to rebuild within next, and the translations showed up.
The ListBox.js file is not typescript, so I don't understand why this causes a problem.
While trying to resolve this issue, yarn kept getting into a bad state, next was telling me I didn't have typescript installed when I did, and multiple other tedious random errors...what a mess.

avoid page creation inside the pages folder

Is there a way to avoid route creation for a .js\jsx\tsx file inside of the /pages folder?
I want to keep the file there, but I don't want nextJS to create the routing.
The purpose is that it makes more sense to keep all the components that are indeed a page under the pages' folder. But I don't always want them to be routes I can navigate to.
I tried to remove the default export, but then next crashes when I try to navigate to that route (Error: The default export is not a React Component in page: "...")
One way to achieve this is by using the Custom Page Extensions configuration in NextJs.
You can colocate test files or other files used by components in the pages directory. Inside next.config.js, add the pageExtensions config:
Edit the pageExtensions array in next.config.js with following to only allow files with *.page.(tsx|ts|jsx|js) to be loaded as pages:
const nextConfig = {
...
pageExtensions: [page.tsx', 'page.ts', 'page.jsx', 'page.js],
}
module.exports = nextConfig
Then rename page files with the .page. extension.

Error on building nextjs app "Error occurred prerendering page "/Loader" [duplicate]

I'm trying to build my Next.js project but it keeps giving me this error in the terminal:
Error: Build optimization failed: found page without a React Component as default export in
pages/components/context/Context
That's the React context API file, there isn't supposed to be any default export there. Is this a bug or what?
You should move your components outside the pages folder. pages/ should only be used for page components as Next.js routing is based on its structure.
Next.js has a file-system based router built on the concept of pages.
When a file is added to the pages directory it's automatically available as a route.
By default, Next.js assumes anything under the pages folder is a page component and will try to build each file as a page.
Even though the above is the default behaviour, you can configure your Next.js app to include non-page files in the pages directory.
To do so, you can modify the pageExtensions entry in the next.config.js file as shown below. Then rename your page components to have a file extension that includes .page (_document.page.js, _app.page.js, index.page.js, etc).
module.exports = {
pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js']
}
With this configuration, Next.js will ignore any file that doesn't contain .page for the purpose of building pages/API routes and routing.
In my case, I had an empty file index.js in a folder. Using Nextjs Default Router
It seems to be not declared default export keyword in context component.
Try it as follow:
const Context = ()=>{
...
}
export default Context
I had the same error.
If you comment out all other code but leave this NextJS won't get mad at you:
export default function Home1() {
return <>{/* nothing */}</>;
}
I like to keep older index files and components locally and on github so this is a nice hack. I just copy all of the existing code add it to a new file and then add 1 to it for example:
index1.js
You can also leave a comment to kind of bring you and other devs up to speed as to why you did this for example:
//good for history of index implementation and associated syntax logic

Gatsby error when creating a new route: Preparing requested page

I setup a new Gatsby project through the installer but when I try to create a new file in /src/pages, but if then I go to that route, the browser says
Preparing requested page
in loop. In the browser console it outputs:
[Error] Unhandled Promise Rejection: Error: We couldn't find the correct component chunk with the name "component---src-pages-home-js" (anonymous function) (loader.js:45) promiseReactionJob
This is my home.js (in a normal React environment works perfectly):
import React from "react";
const Home = () => {
return (
<div>
<title>Test</title>
<p>Hello</p>
</div>
);
};
export default Home;
Project structure:
pages
- 404.js
- index.js
- second.js
What could be the problem? I already tried to reinstall Gatsby again and tried cleaning caches or making another file, with a different file names. The file is seen by Gatsby because if I try to access the route without creating the file, it gives me the 404 page.
Thanks.
UPDATE:
If you're using a Mac with M1 Chip, make sure you installed Gatsby with Rosetta!
Also hit the same problem with M1 MacBook Air when adding pages to Gatsby sample project. The solution (found elsewhere) was to empty the browser cache.
Have you tried renaming your home.js to index.js?
After that, clean the cache by gatsby clean.
This may be due to data in your browser cache. Clear the cache in Safari with Option + Command + E
Clearing browser caché was the solution for mee too, as #JohnysSon says

Where should I put general app config in a Gatsby project?

I'm new to Gatsby, but familiar with CRA. I'm using the default Gatsby setup generated by running gatsby new <project_name> from Gatsby CLI.
I have some general config that I want run in my whole project, regardless of current page - for example:
import { enableMapSet, enableES5 } from "immer";
enableMapSet();
enableES5();
In CRA projects I put this stuff inside App.tsx, but can't figure out what the right place is in a Gatsby project.
In Gatsby, you don't have a single configuration file per se. There are several APIs exposed by Gatsby that allows you to configure one specific part of your site.
To run a set of functions regardless of the page you can use a gatsby-browser.js (placed in the root of the project).
Basically, Gatsby exposes a bunch of APIs that lets you respond to actions within the browser, and wrap your site in additional components. The Gatsby Browser API gives you many options for interacting with the client-side of Gatsby. One of them, onClientEntry fits your requirements. From its documentation:
onClientEntry
(_: emptyArg, pluginOptions: pluginOptions) => undefined
Called when the Gatsby browser runtime first starts.
Applied to your code, your gatsby-browser.js should look like:
import { enableMapSet, enableES5 } from "immer";
import React from 'react';
export const onClientEntry = () =>{
enableMapSet();
enableES5();
};
The snippet above will trigger enableMapSet() and enableES5() on every page.

Resources