I was tasked with implementing an i18n for the company website. At present we are using Netlify with #netlify/plugin-nextjs, and I hit the wall when submitting a PR when I got an error saying that
Error: i18n support is not compatible with next export.
I have read several topics here and a few articles and I found one smart workaround https://dev.to/adrai/static-html-export-with-i18n-compatibility-in-nextjs-8cd
And other suggestions were to move to Vercel. Is this the thing I should consider? We do not use getServerSIdeProps anywhere, the website is fully SSG so what is the benefit of the next export over the SSG approach? Is SEO better with the next export?
Next-translate seems to be building pages in development on every page change so perhaps it is possible to build a separate page for every translation without the need for such a burden?
I think moving to Vercel would be doable but should I do that? Would this allow me to deploy the translation while saving the SEO that next export gives? Or should I go with the custom solution above?
Thanks
With next export you can generate static HTML pages (SSG) that can be served easily from any server of your choice, but this way you won't be able to use all of the features listed on this page:
https://nextjs.org/docs/advanced-features/static-html-export#unsupported-features
And other suggestions were to move to Vercel. Is this the thing I should consider? We do not use getServerSIdeProps anywhere, the website is fully SSG so what is the benefit of the next export over the SSG approach? Is SEO better with the next export?
When deploying to Vercel or Netlify you still have all the SEO benefits of statically generated pages (Either through Automatic Static Optimization or manual usage of getStaticProps) and full access to all Next features listed in the link above (including i18n). Hence, if you have static pages, next-export has no SEO benefits over deploying on Vercel/Netlify, as in both cases you will serve pre-rendered pages to users, but next-export just gives you better flexibility when it comes to deployment.
Next-translate seems to be building pages in development on every page change so perhaps it is possible to build a separate page for every translation without the need for such a burden?
As you mentioned, that's exactly what the example you linked above achieves: It pre-renders every page for every locale you have, which is also exactly what you'd get when deploying a Next app with a i18n package like next-translate or next-i18next on Vercel or Netlify.
I think moving to Vercel would be doable but should I do that? Would this allow me to deploy the translation while saving the SEO that next export gives? Or should I go with the custom solution above?
If you can, you should deploy on Vercel or Netlify to save a lot of time and get all the features like i18n out of the box. But, the example you provided above also makes i18n work with next-export so if you have a plain, static website that requires no other custom Next features like routing, middleware or Image optimization, it will surely work too if you don't want to deploy on Vercel/Netlify.
Related
In the Gatsby documentation it says that the default build mode is SSG:
SSG is the default rendering mode in Gatsby. While the name has the word “static” in it, it doesn’t at all mean boring or lifeless. It simply means the entire site is pre-rendered into HTML, CSS, and JavaScript at build time, which then get served as static assets to the browser.
But it seems that when you build it, the compontents and libraries have to be SSR friendly, and you need to use workarounds when using client-only libraries.
From the documentation it seems like there are three options for rendering:
SSG - Static Site Generation
DSG - Deferred Static Generation
SSR - Server Side Rendering
What if I am not interested in using SSR and just want to serve the static SSG version of a Gatsby site. Is there an option to build a purely static site, client-side site like Vite or Create React App and not have it complain about server-side rendering errors like this?
failed Building static HTML for pages - 1.639s
ERROR #95312 HTML.COMPILATION
"window" is not available during server-side rendering. Enable "DEV_SSR" to debug this during "gatsby develop".
Building a static site and doing server-side rendering are very nearly the same thing. The primary difference is when it is done (at build time instead of on demand).
The code to generate the HTML to be delivered to the client still has to be executed, and it still has to run in an environment where window is not available.
So no. You still need to do the workaround so that the code which can only run on the client is only run on the client.
So I'm finding it difficult to see the benefits of doing SSR for dynamic paths in NextJs when I can just just pre-render a few static paths, and use fallback=true to cover my bases on most pages.
Say I have an eCommerce site with 1 million product detail pages, but I only want to pre-render featured products on the home page(most clicked). If I set fallback to true in getStaticPaths, then the getStaticProps function runs every time a non featured product page is requested.
So what's the advantage of using SSR when I can just have a fallback that queries the database every time a non pre-rendered page is called?
Note: I saw a similar question on Stack Overflow, and the answer was that web-crawlers see only the fallback state of your react Component that you set for non pre-rendered pages (so the source code would only read <p>Loading...</p> or something like that, vs the SSR page which would load all your data for the product directly as the source code. But this doesn't seem to be true in my app.
Thanks for any help.
TLDR: [In NextJs..] Why can't I just use SSG for dynamic paths, with fallback=true in getStaticPaths, instead of SSR?
THANKS ALL
I tried reading the NextJs docs and couldn't find an explanation for the cons of using fallback=true in getStaticPaths
From next.js docs:
By default, Next.js pre-renders every page. This means that Next.js
generates HTML for each page in advance, instead of having it all done
by client-side JavaScript.
Two Forms of Pre-rendering
Next.js has two forms of pre-rendering: Static Generation and
Server-side Rendering. The difference is in when it generates the HTML
for a page.
Static Generation is the pre-rendering method that generates the HTML
at build time. The pre-rendered HTML is then reused on each request.
Server-side Rendering is the pre-rendering method that generates the
HTML on each request.
I put those definitions to clarify the terms in next.js. I believe your question is regarding fallback:true versus generating HTML on each request (or building page runtime vs build time). I think this note you shared is not correct
Note: I saw a similar question on Stack Overflow, and the answer was
that web-crawlers see only the fallback state of your react Component
that you set for non pre-rendered pages (so the source code would only
read Loading... or something like that, vs the SSR page which
would load all your data for the product directly as the source code.
But this doesn't seem to be true in my app.
In each case the populated page is seen by the crawlers.
Using getStaticPath in your e-commerce example is the usage of caching. those pages for popular products are already built and inside next build folder you can see them if you build your app locally. But in large applications, those static assets are stored in CDN, and whenever the server gets a request response will be in no time. so customer will have a better user experience so which will eventually affect the profit of the ecommerce site.
I think the clearest example would be thinking about a blogging website like Medium. The most popular blogs will be pre-generated since the content of the blogs do not change that often. Medium will use CDN's from different parts of the world, so user all around the world will have faster access to blogs.
Hitting databases is a very expensive operation. The more load you have on the database harder to maintain the availability, scalability, and reliability of your application.
Also, you might have a better internet connection, you use high end clients so you might access any data faster but you have to think about all people around the world who try to access data with low-quality clients or internet connections.
I have heard SSG generates static sites.
Then I thought SSG generates pure HTML that didn't include React, but I think it may not be true now.
I think:
SSG generates a usual React App and rendered HTMLs for initialization.
As it is a usual React App, if I click a button and trigger a side effect, client-side rendering will be triggered and the page will be updated.
When routing using router is triggered, next page's js file and data obtained when build will be downloaded, and then client-side rendering will be triggered.
The next page's rendered HTML for initialization isn't used here.
Is it true?
SSG (Static Site Generators) like Gatsby and Next, what they do is to create an output HTML based on a React environment code. This doesn't mean that the site is "static" in terms of interaction. This means that the page you are requesting is already created so you are avoiding response and compilation time in the server.
Summarizing, given a "traditional"/"old-fashioned" PHP site. When you request the homepage, for example, your requests go to the server, the server transpiles the PHP into HTML (what the browser can parse and print) and then you get the page. That processing time is omitted in Gatsby/Next because the HTML is already created.
When you build your site in Gatsby/Next, the data is being retrieved from the sources (using GraphQL from markdowns, CMSs, APIs, JSONs, etc) and creates the output (that's why there's a /public folder generated). All your JavaScript and React is bundled into the output HTML so your website will be "dynamic" in terms of user interactivity, React is part of the ecosystem so your side-effects (triggered by useEffect hook for example) or your rehydration process (useState hook for example) will be part of your site.
Explained as:
When you navigate into another page, you are requesting a page that is already built and generated, that's why is so blazingly fast.
I've answered this question few weeks ago on the Nuxt discussions: https://github.com/nuxt/nuxt.js/discussions/9493#discussioncomment-948643
Let's say that SSG bring several things:
SEO
speed
ecology
[probably some other things]
There are several ways of doing SSG and all of them have their pro/cons and their use-cases. For the most part, and if you're using Nuxt.js, you will probably go the target: static, ssr: true route.
This will:
generate fully static pages during build time and you'll be able to host it on Netlify, Vercel or alike
hydrate the static content with some JS after you have fetched the static files
have the Vue behavior afterwards, as a classic SPA (hence managing the routing without further server calls)
This behavior is called Isomorphic or Universal, more info in the linked discussion.
Gatsby and Next.js do work in somewhat similar ways. There are some minor differences but the general is globally the same across those 3 AFAIK.
SvelteKit and Astro handle this a bit differently. May be interesting to give it a look!
I want to build a website with Next.js and am trying to better understand their Automatic Static Optimization, and the different ways that you can use it.
So to start with, there's Gatsby.js which is a static site generator. When you run Gatsby's build command you get a /public folder which is completely static and can be deployed without any need for some kind of a back-end. If I understand correctly, this means that the entire static folder is sent to the client on the first request, and from then on everything, including routing, happens client-side.
With Next.js on the other hand, you have static generation, which means that all pages are pre-rendered on the server at build time (like Gatsby), but the application still depends on a back-end (either a full-blown server or a serverless function) for routing. I.e, the pages are pre-rendered but, unlike Gatsby, they're sent to the client per request, i.e on navigation. (I found this answer which says there's only the initial request with Next, but then, what's the difference from Gatsby?)
What I find confusing in all this, are things like Next's docs for Static HTML Export. They start by stating
next export allows you to export your app to static HTML, which can be run standalone without the need of a Node.js server.
So, sounds like this option gives us the ability to use Next just like Gatsby, i.e as a completely static folder.
But then they go on remarking that:
If your pages don't have getInitialProps you may not need next export at all; next build is already enough thanks to Automatic Static Optimization.
But Automatic Static Optimization refers only to server side static pre-rendering, and next build does not produce a Gatsby like static folder that can be deployed as a standalone.
So what am I missing here? What's the difference between Gatsby.js and Next.js? Does Gatsby can do something Next can't? Can I build a completely static site with Next without using the export command?
Most importantly, can I build and deploy a Next.js application with some pages completely static (like Gatsby), some pages only pre-rendered (getStaticProps and getStaticPaths), and some pages rendered server-side (getServerSideProps)?
Thanks a lot in advance!
The first request is for <url>/index.html so no the entire public is not sent to the client.
Gatsby optimises the loading process to ensure critical resources (HTML, CSS, JS) are loaded first, ensuring best possible user experience. From there it will load remaining resources required to render the full page and will also prefetch linked pages from the main page. Of course if you have requested a route to a different page, then the client would fetch the HTML initially for that page, but the process followed will be similar.
Gatsby is still better at this than Next.js (SSG is a very new feature for Next and this the core of what Gatsby does) - see https://dev.to/notsidney/gatsby-won-against-next-js-in-this-head-to-head-37ka.
In answer to your questions, yes you can do full SSG, partial SSR/SSG and full SSR with Next. You need to do next export if you want full SSG, otherwise for the other modes you are in standard Next territory and Next will take care of both SSG/SSR given you have a traditional web server running that can serve both static content and perform dynamic SSR.
So I noticed when I ran my react app's production build's login screen from create-react-app that all of the source code for the app was available within the static/js folder. Basically, the code doesn't look any different from the code in my ide, on the production build.
I am wondering if there is a way to hide this behind a login screen? So that a user can't directly access these files unless the login is successful. I have looked around and was unable to find anything of use.
The js files from the production build should be minimized which would look a lot different than in your IDE. I assume what looks "the same" is looking at the source using developer tools. The solution for that is to not deploy the source map files (*.js.map). Those are the files that allow developer tools to transform the minimized code back to its original look.
Removing source maps makes it difficult for someone to learn from the code easily, but if there is sufficient motivation to do so, it can still certainly be reverse-engineered. There are also some parts that wouldn't be obfuscated much at all such as the URLs for API calls which would then give someone a lot more information to use as the basis for hacking attempts.
If you need to prevent seeing any version of the source for people that are not logged in, I would recommend building your app as two apps -- one that just contains the login portion and one with the rest. Code-splitting within one app won't do the trick (at least not without using a solution that is quite a bit more complicated to manage than the two-app option), because it just makes the download process lazy and it is still pretty easy for someone to determine what the other files are and download them. However, even splitting this into two apps only helps if you host the second app differently. This will require server-side protection that only serves the JavaScript files for the second app for a user that is logged in. This means either using a different sub-domain for the second app or at least a different directory on the server that has those protections baked in. How you would implement that protection depends on the details of your authentication approach and the technology stack being used on the server. Most likely, it means using a cookie set by the login process and then having the JS files for the second app served up by something that verifies the cookie before allowing the JS files to be served to the browser.
To overcome displaying your source code in production's build, try to build your app with
GENERATE_SOURCEMAP=false npm run build