How to export all Sapper routes into static files? - static

When I run yarn run export / npm run export, only one of my routes get exported as a separate static html file. I want all of them to get exported, into their own .html files.
Am I missing a setting?
The only route exporting is /login
You can check this in this repo (i cannot provide samples, since I don't know what causes this issue): https://github.com/useverto/verto

When sapper export is run you'll see that it first builds the app, runs it, and then crawls the links it finds to determine the routes it can export.
https://sapper.svelte.dev/docs#How_it_works
Because the Nav component in your app only exposes / and /login as links when loggedIn is false, the export will only see and follow those links. The /trade and /gallery links in your app are only rendered once loggedIn is true, so they'll not be seen by the export.
You can add other routes to be exported with the --entry option to the sapper export command. So in your case you could change the export command in package.json to something like...
"export": "sapper export --legacy --entry '/ trade gallery'",

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

NEXTJS error: export encountered error on following paths [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

create react app - npm run build issues

I am using create-react-app to build an application and when I run npm run build it creates a build folder with static folder inside it which is expected.
build--> static
But when I see the index.html file inside the build folder, the path to assets is /static and not /build/static which is why the page does not load properly as it is missing the assets .
Is there any config setting I can do to fix this problem ?
If all you want is to run your app, all that you have to do is run the command: npm start
But, if you are really trying to prefix the static references to upload your code on an specific subdirectory you should add on your package.json the homepage you want to use on your create-react-app.
So, if you want your react app to use /build in the beginning of each reference you should add the following line to your package.json:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"homepage": "/build",
...
}
The following message is displayed when you generate your build without the homepage in the configurations:
The project was built assuming it is hosted at the server root.
To override this, specify the homepage in your package.json.
For example, add this to build it for GitHub Pages:
"homepage" : "http://myname.github.io/myapp",
The build folder is ready to be deployed.
You may serve it with a static server:
yarn global add serve
serve -s build```
But when I see the index.html file inside the build folder, the path to assets is /static and not /build/static
This behaviour is expected.
You're supposed to deploy the build folder and serve the application from it. Since index.html is inside build, it would be served for /, and files in build/static/* will be served for /static/*.
For more specific instructions for this, please read the Deployment section of the User Guide.
It sounds like you're trying to use unimported assets.
I prefer to create an assets folder and place these sort of files here, and then import/use them accordingly.
From the documentation:
import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
function Header() {
// Import result is the URL of your image
return <img src={logo} alt="Logo" />;
}
export default Header;
If you really want to use the public folder, you can use the PUBLIC_URL variable.
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

Resources