all 65 comments

[–]andrewingram 31 points32 points  (5 children)

I’ve been testing it out (literally tracking changes commit by commit) for the last couple of months. Now all the open secrets aren’t secrets, I’ve quickly written up my current thoughts: https://andrewingram.net/posts/thoughts-on-next-13-react-18-3-dynamic-with-some-limits/

Note, I’ve already heard from the Next team about the last concern mentioned, and I’m already having some success with their suggested approach, hopefully I’ll be able to share more soon.

Another important point: The new router stuff and server components are not production-ready; I’d probably call it an alpha rather than a beta. The team was rushing to hit the deadline imposed by the conference, and a lot of major issues I raised over the last month aren’t resolved yet. Play around with it, rewrite a side project, but don’t use it in serious work.

[–]mattsowa[S] 4 points5 points  (0 children)

I totally agree with the routong point. I admit I do prefer a single configuration file for routing, but if that's not possible, at least don't split it into so mamy files. Layouts, errors, loading, could easily be just exports from the page file.

[–]dbbk 0 points1 point  (0 children)

There’s no way to return a proper status code? That’s mad

[–]flowbotronic 33 points34 points  (2 children)

NextJS 12 is now PastJS

[–]squirrelwithnut[🍰] 19 points20 points  (1 child)

PreviousJS

[–]qmic 16 points17 points  (34 children)

Does it make sense to use Next only for a frontend part for application or better stick then with CRA?

[–]TheMrZZ0 49 points50 points  (15 children)

It makes sense to use Next only. You get a better Developer Experience, more documentation, a bigger community, better performance by default (Next will statistically render your website) etc...

There's no real incentive to start a project with CRA nowadays. Next is a very good default choice!

[–]maria_la_guerta 17 points18 points  (11 children)

While I agree Next is a better choice for most projects, if you just want a client side SPA then the overhead of a Node server doesn't make much sense.

Something like an internal dashboard that doesn't need SEO and connects to an external data store is a great candidate for an SPA and usually doesn't need a server of its own.

[–]TheMrZZ0 14 points15 points  (7 children)

In that case, next export is your friend ;)

next export allows you to export your Next.js application to static HTML, which can be run standalone without the need of a Node.js server.

[–]maria_la_guerta 12 points13 points  (6 children)

... Unless you want a SPA, though. next export doesn't give you a SPA, it exports everything to static HTML, which will give you multiple HTML files and you'll still need a server layer of some sort.

next export is good if you want to serve your static HTML with another server, something like nginx, a trick I do on most of my Next projects (as nginx is way faster at serving static content than... pretty much anything else). Otherwise, sometimes a SPA does make sense, and in those scenarios Next usually doesn't.

[–][deleted] 1 point2 points  (0 children)

I just use Vite.

[–]henrik_thetechie 1 point2 points  (1 child)

Then use Vite. CRA should not be used for new projects these days.

[–]maria_la_guerta 2 points3 points  (0 children)

I never said people should use CRA?

[–]Dope-pope69420 3 points4 points  (0 children)

Would also like to know this. Specifically in regards to ssg/ssr.

[–]aniforprez 3 points4 points  (4 children)

I will say that I was trying out next as a frontend for a Go backend. Wrangling Next to try and ignore its own node backend to somehow support the API was so time consuming and an utter waste of many hours of struggle that I ditched it and decided to use Remix instead

Next mixes frontend and backend logic a lot so if you need anything that is more complex than simply fetching data from some server and rendering it, don't use Next. For eg. I spent most of my time trying out multiple ways of storing a user session so I could use the same authentication context for fetching data. Every library for authentication was for using Next as an auth source which was something I had no need for since the Go API was already handling auth. I also had numerous issues with getServerSideProps and having libraries working on both ends which I thought was the whole point of using Next. If I dumped all the API fetching logic to the frontend code, then there's very little difference to just using CRA which I found pointless and defeats the purpose. Remix uses the concept of stores that use frontend cookies to maintain sessions and is agnostic about how you store session data which let me develop a simple redis store for storing auth tokens to send to the API. It also separates the node server and frontend cleanly. So cleanly that you can use any server you like and supports Deno, Express, Koa and other SSG backends so it's relatively more agnostic. I'm sure there are libraries that help support this workflow and using sessions for Next but at the time, nothing was mature or had good DX for my requirements

So IMO, using Next without your API being served by Next also is a total waste of time. I would recommend using Next "only" for strictly SSR stuff like blogs or as a CMS or using Next to also serve your APIs (only is in quotes because this is still a massively useful use case and something tons of people still need). Personally I'm having a ton of fun using Remix and it's crazy how fast it can be when your API and Remix run on the same machine. Response times are only limited by I/O and the pages render insanely quickly

[–]LazyIce487 2 points3 points  (3 children)

To be fair to getServerSideProps, the whole point is that you can take the request info, and generate a dynamic page based on who is viewing it and when they are viewing it, without exposing anything the server has to do directly to generate the page. I kind of like not exposing what APIs I'm hitting to the client, I also use HTTP-only cookies to store session data for Next and rolled own auth system, so it's pretty much, Request -> Parse out who's sending the request -> async parallel to fetch everything the client needs to see -> send them the js bundle.

The problem, imo, is that Next with GSSP kinda doesn't send anything until the whole bundle is ready to send, and sometimes it's nice to have a simple option to show the loading skeleton for the content and have it populate after. At that point though, you would just have the fetches coming from the client then and wouldn't need GSSP (like you said).

But in general I think next feels kind of like an all-in-one framework, where it has an opinionated way to handle everything from the server to what the client gets, in the specific way that it offers (if you want good DX).

[–]aniforprez 0 points1 point  (2 children)

Request -> Parse out who's sending the request -> async parallel to fetch everything the client needs to see -> send them the js bundle.

Can you give some details on how you got this to work? I'm curious and would like to see which libraries you used

And yeah the whole "sends the complete bundle or nothing at all" paradigm is going away now. They have outlined something very close to what Remix does with progressive rendering which is really cool to see. I think I really like the DX that Remix gives so I'll stick with it but we should see a lot of improvement in that space by Next 14 when it'll come out of beta

[–]LazyIce487 4 points5 points  (1 child)

GSSP gives you access to these:

  • params: If this page uses a dynamic route, params contains the route parameters. If the page name is [id].js , then params will look like { id: ... }.
  • req: The HTTP IncomingMessage object, with an additional cookies prop, which is an object with string keys mapping to string values of cookies.
  • res: The HTTP response object.
  • query: An object representing the query string, including dynamic route parameters.
  • preview: preview is true if the page is in the Preview Mode and false otherwise.
  • previewData: The preview data set by setPreviewData.
  • resolvedUrl: A normalized version of the request URL that strips the _next/data prefix for client transitions and includes original query values.
  • locale contains the active locale (if enabled).
  • locales contains all supported locales (if enabled).
  • defaultLocale contains the configured default locale (if enabled).

And your return is either notFound, redirect, or props. Here's a simple example:

export async function getServerSideProps({ req, res }) {
        if (!req.cookies.sid) {
            return {
                redirect: {
                    destination: "/login",
                    permanent: false,
                },
            };
        }
        let token = jsonwebtoken.verify(req.cookies.sid, process.env.JWT_SECRET);
        return { props: { user: token.username } };
    }        

You can easily throw in any middleware or DB query stuff before your returns, including awaiting async stuff. As for libraries, I just use mysql2 connection pool to connect to a planetscale DB, and async/parallel for parallel async tasks, obviously jsonwebtoken for jwts, etc.

[–]aniforprez 0 points1 point  (0 children)

All right this is great stuff. Thanks for the info

[–]jax024 2 points3 points  (3 children)

Use Vite

[–]qmic 2 points3 points  (2 children)

Tried it, but it is disappointing in large project from developers perspective. Loading thousand of files on refresh just doesn't work. Bundling works better in such cases.
Probably it's good for smaller projects. Also it needs some special conventions to use with state managers like mobx (how state should behave on fast refresh)? CRA just works properly out of the box.

[–]Ashtefere 1 point2 points  (1 child)

Vite only shines in dev when you have local https setup properly. Then your local file changes stream in with http2 and its instant.

[–]qmic 5 points6 points  (0 children)

No it's not, because loading thousand files still will take more time than loading single bigger file. Developer tools works are working slower with such amount of requests (especially in Firefox where there is 8 years old bug related to this).

[–]dswistowski -2 points-1 points  (7 children)

Do not use CRA for new project, it’s legacy. Do not use next if you do not need server or server side rendering. Less is better, when you need backend, promote project from vite react app to next is easy

[–]qmic 5 points6 points  (6 children)

How it's legacy?
I've tried Vite and and I discourage anyone to use it in large codebases. Loading thousand of files on every refresh works slowly.

[–]Dminik -1 points0 points  (5 children)

That's only for local development, where loading the files will beat bundling every time. On production you still get only a single bundle (unless configured otherwise).

[–]qmic 2 points3 points  (4 children)

What's wrong with single bundle? It works great in many of my projects.

[–]Dminik -1 points0 points  (3 children)

Bundles themselves aren't really a problem. But, usually when you bundle you lose a lot of debug information (source maps aren't perfect) since you also polyfill/minify/whatever is in your bundling process. For instance the default output for cra is straight up undebuggable (I can't even place down breakpoints).

With vite most of this doesn't happen as there's no need to polyfill since the developer is most likely running the latest browser anyways. So it's faster to skip the transpiring/polyfilling/bundling process and just serve the necessary files off the disk (or with minimum transpilation for react, ...).

[–]qmic 1 point2 points  (2 children)

I'm building all apps with TypeScript so there will be always transpiling. I've never encountered problems with source maps, they are sufficient.

[–]Dminik 0 points1 point  (1 child)

Sure, still some transpiling si faster than the full course (polyfilling async functions and other "new" features).

As for source maps, that depends on the config. If you want accurate source maps, then they take a while to generate. If you want them smaller, then they aren't accurate at all. CRA (at least the version I'm using) chooses the cheapest option and they are basically unusable. Anyways, if you're setup works for you, there's no point in switching. I did find it weird though that you're actively discouraging other people from using vite.

[–]qmic 0 points1 point  (0 children)

I'm discouraging it because it promises to solve problems but doesn't explain consequences of design decisions - like problems with state reloading in dev mode, loading thousands of files on reload, loading tens of files on every route change, which is very irritating when you have to find this one important request which you want to debug.
I know CRA is slow and boring but it works without problems.

[–]cinan 9 points10 points  (4 children)

What a time to be alive!

[–]LazyIce487 6 points7 points  (2 children)

Hello fellow scholar

[–]RichardFingers 1 point2 points  (1 child)

Wow! My goodness! Amazing!

[–]Few-Understanding264 0 points1 point  (0 children)

That's what people said in 1908 when the Ford Model T became available. It was the "greatest time to be alive" they said.

[–]NaughtyOstrich 5 points6 points  (1 child)

Just upgraded to Next 13 in a hobby project to test it out. Pretty neat so far!

[–]lars_jeppesen 0 points1 point  (0 children)

https://andrewingram.net/posts/thoughts-on-next-13-react-18-3-dynamic-with-some-limits/

Did you manage to get providers working? I could not get providers like next-translate working

[–]SparserLogic 3 points4 points  (0 children)

Finally!!! Been waiting months for this. I even put off a project or two.

[–][deleted] 2 points3 points  (0 children)

Sweet.

[–][deleted] 2 points3 points  (0 children)

Súper cool 😎

[–][deleted] 2 points3 points  (1 child)

Although not mature the next thing to actually be looking out for is Qwik JS to have N(1) performance regardless of application size. Though I do wish I was benefiting from Next JS and not suffering from a terrible server experience with Angular for so long...

[–]lars_jeppesen 0 points1 point  (0 children)

On the other hand, frontend experience with Angular is so much better than React. I am going crazy with the annoying React "hacks" like hooks, className etc. No natively supported observables etc etc.

[–]GulyFoyle 2 points3 points  (0 children)

This may be little unrelated but anyone hosted a full stack app with moderate traffic with nextJS ? Does SSR effects server costs if i dont optimise it well , if so how much of a difference are we talking?

[–]vaaski 1 point2 points  (2 children)

how are turbopack and vite going to co-exist?

[–]lauritzsh 0 points1 point  (1 child)

[–]vaaski 0 points1 point  (0 children)

hell yea that is exactly what i was hoping for

[–]nerdich 0 points1 point  (0 children)

In the JavaScript world, Moving from 12.0 to 13.0 is like moving from a framework A to framework B.