I love this approach and use it, but just realized it does not prevent Layout components from re-rendering upon navigation... have you found a fix for this?
Thank you! We've added documentation[1] on the current layouts solutions, which is similar to Adam's post. It's a good workaround, but I'm very excited for improving the developer experience here.
There's a fundamental flaw with the solution proposed in the documentation (getLayout as a function), which could be fixed by using a pure JSX approach: https://github.com/vercel/next.js/issues/36029
The surface-level approach and APIs/conventions looks very similar, just with some slight differences that people may subjectively prefer over Remix. Personally my immediate reaction is that I prefer Vercel's convention of requiring all visitable routes to be represented by a leaf called page.js. In Remix, you can have a file anywhere in the routes that will create a navigable path segment using the same name as the file, e.g. the file /dashboard/settings.js will be visitable at the URL /dashboard/settings, whereas in Vercel this will need to be /dashboard/settings/page.js. I prefer Vercel's way of doing things, because with Remix you often end up with a .js file as a sibling of a directory with the same name, e.g. /dashboard/settings.js and /dashboard/settings/advanced.js, which means that you can't just look in the /dashboard/settings/ directory to see all of the routes with the prefix /dashboard/settings.
It's almost an exact copy aside from the conventions and names. It very much _is_ Remix. This is pretty wild. It also brings one of my gripes from Remix: parallel fetching. In practice it makes sense, but at times there needs to be a way to fetch data on a parent route first so that child routes don't fetch again. I'm sure Vercel will find a way to solve this.
Doesn’t Outlet context solve your issue? It let you share data between parent and child path. Of course it is during rendering so you can’t use parent data in your loader.
> Of course it is during rendering so you can’t use parent data in your loader.
I specifically want the parent data to perform redirects in child routes. The only solution is to manually add the redirects at the parent level (like a whitelist).
The routing is pretty similar. A concept that predates Remix, but Remix made popular again.
What sets Remix apart is how it handles network requests through its own <Form /> wrapper, which anecdotally leads to incredibly simple data handling. Even cooler, if you restrict yourself to GET and POST, your app will work without JS. Nifty, if you ask me.
Which is a bit silly, to be honest. I understand wanting to see some credit given, and it wouldn't have cost Vercel anything to do so, but this is hardly "new Remix technology" that they're copying (also the condescending "React czar" stuff is just super inappropriate, but par for the course with the way the Remix team has been talking about Remix on Twitter since the days when they were boasting about not taking VC money).
The fundamental approach Remix (and now Vercel) takes to nested routing with React SSR is fairly straightforward. It's how everyone else (not using a framework) has been doing nested routing with React SSR for, what, at least 5 years? Granted, most of us have been using React Router for our React SSR setups, and credit very deservingly goes to the React Router guys (who are now the Remix guys) for that. Remix did a great job of delivering a framework that (via a nice compiler and file structure conventions) makes this React SSR routing architecture very easy to use! But that doesn't mean that anyone else who takes this same fundamental approach is somehow copying Remix. The home-grown React SSR setup I've worked on for the last 4+ years has been doing the same thing this whole time, and while we might be "copying what the React Router community was doing 4-5 years ago," and that might even include demos or articles written by someone who went on to found or work at Remix (again, really, thanks!), I don't think we're in any sense "copying Remix."
edit: Well, I just noticed on Twitter than the cofounder of Remix (also co-creator of React Router) is, contrary to the opinion I expressed in the paragraph above, clearly claiming that he believes Remix deserves attribution for any usage of concepts which ever existed previously in React Router. I don't agree with this. https://twitter.com/ryanflorence/status/1528862791490105344
> No shame in copying but the first prototype of this started before Remix was available. It was more inspired by traditional server routing techniques (like FB used) with React Router locality with Next.js file conventions. So it's more about convergent evolution in this case.
It’s an odd claim, because people have been asking for this (nested routes) more-or-less since Next was first released. In fact, Remix is basically a compiler for the patterns we could achieve back in the days of React Router 2 and 3 (2015-2017).
The fact that the APIs looks similar seems largely inevitable based on the fact that everyone seems to be converging around defining routes using folder and file name conventions.
It reminds me of patent trolls who patent obvious software designs. I was looking for such feature long before I heard of Remix. I know he's the react-router guy, but nested views isn't exactly some novel idea - sites have been using it forever.
I definitely understand the reaction. This is an existential threat to Remix.
However, this is why I don't use Twitter. Remix is not just "an open-source project", it's a full-fledged company. This is definitely not the time (or the forum) to lay your cards out on the table...
It's a full fledged company and somehow Ryan Florence and the other guy are quite heavy handed in pushing their business which irks me. Even react router was moved to a business org called react training if I remember so that they could sell their courses. Now there is nothing wrong with earning money but this new wave of "open source" businesses is a bit yucky.
It's not the training, it's the fact that they moved the project repo under the React Training organization, and now it's under Remix... Just comes off as a cheap attempt at marketing while ruining the OSS image of the project.
IMO it's really just a matter of time before good ideas end up in other projects. It's inevitable. Obviously everyone wants their framework to be as good and popular as possible.
That is so true. It's been driving me insane since Remix was announced/opened but I couldn't quite put my finger on why. It's because overnight there was an army of people preaching the new religion of Remix all over the place, and not a single one I asked could (at the time at least) tell me why it was better/different than Next.js (a project which IMHO rose on its merit and had to fight for every inch). They had clearly never looked seriously at Next.js before because every "feature" of Remix they were excited about was something Next.js already did. After a bit they started linking to a very long blog post from the Remix creator that supposedly explained why they were different, but after 10 minutes of looking through a post that was supposed to answer my question, all I had was anecdotal performance numbers about how Remix is "faster."
In software we definitely do tend to cargo cult and worship good languages/frameworks, but the Remix "love" is (or was at least) over the top even for us.
It's weird to me: I don't use Twitter and I don't intentionally follow influencers or celebrities in the tech world. Yet somehow RF has been the center of several bouts of developer of drama I've come across. Any idea why that might be?
And remix is ripping features from Vercel. Such as they business model, and the idea of creating their own framework for it.
Additionally, I wouldn't trust ever again the guys that rewrote and broke react-router with incompatible changes like... 6 times already? And now bragging on podcasts "Remix is 10 years old because is just built on top of react-router". Bullshit, it's just the npm package name that is this old. It is so deceptive all the ugly marketing they're doing.
Next.js is very nice. One thing that always strikes a nerve with me though is that it goes against 12 factor. There is no proper way to build once, deploy (with config) multiple times. So either you have to build for each environment, which on kubernetes means building different container images (one for each environment). Or do a full re-build when the container starts, which means slower container startup, but at least you can re-use the container across environments and properly inline environment variables. There's a discussion about this; https://github.com/vercel/next.js/discussions/24010
The fact that Vercel can do deploys to different environments almost instantly, suggests to me that internally they use some variant of the solution suggested in the first reply in that discussion.
Nearly all front end metaframeworks/starters are like this, which is why I've given up on trying to run them in Docker, because it's just over-complicating the deploy process with no real benefit due to what you mentioned, and I'd rather just use simpler tools like Netlify.
Pretty much. I've been able to use some regex-replacements on the build output in the past with varying luck. But it definitely feels like a hack and can break in weird ways. Another option is building all environments into a single container image and then selecting the right build runtime using an environment variable. This makes the build costlier, even if you can build in parallell, and a bigger image takes longer to distribute into your environment.
At that point dedicated frontend hosting infrastructures like Netlify, Vercel, Cloudflare Pages and others seems like a better choice.
Potentially pretty stupid question, I've never used any React framework like Next.js but I have used React for a while. Are these frameworks always meant to provide the backend as well? I'm using .NET as the backend, so I'm curious if they are something I should look closer at.
I mean for SSR they have to run on the backend, but even that I could imagine running parallel to the main backend. I'm just not sure if you get much benefits out of these frameworks without the tight integration on the backend.
Are next.js and other similar React frameworks worth looking at if you don't use node.js on the backend?
We have built our new corporate website with NextJS. After getting some used to the framework's particular opinions about how to do things, it was an overall good experience.
The main benefits of such a framework for us in our use case:
- 90% of the content is essentially static and can be pre-rendered, the rest is dynamic. With NextJS we can easily mix and match these cases, re-using the same code
- We use the backend part to act as a gateway to fetch content from different APIs like the CMS, HR tool, email service, etc. The very little custom backend code required we put into nextjs api functions
- It comes with a couple of niceties built-in for page speed like image optimization.
- Any frontend dev with some react knowledge can work on it. This is my problem with say WordPress, you fairly quickly hit the point where you need specialized knowledge that you can't re-use that much for other projects in the company.
Of course, the same and more can be achieved by selecting libraries to build a bespoke stack, but don't think a fairly standard website that doesn't need to change a whole lot warrants the upfront effort.
There's nothing stopping you from wiring the Next.js backend up to your databases and external APIs and for simple apps it's likely quite a nice solution. But if your backend consists of complex business logic and needs to talk to lots of different services it can be a lot cleaner to have better distinction between the backend part of your app and the frontend, and just use Next.js' backend for data fetching for the UI.
You can also not use Next.js without a Node.js runtime at all and just compile your whole app to static files to be served by a static file server like S3, nginx, etc. The advantage of this over CRA is that you get statically-rendered html (as well as normal client-rendered React interactivity) which is good for SEO and FCP[1]
> Are next.js and other similar React frameworks worth looking at if you don't use node.js on the backend?
It depends on why you’re doing so. We’ve recently moved from a C# .net backend to a TypeScript node backend and in such a case it (well obviously) makes perfect sense to utilise next.js.
In other cases where you split your front end and backend quite clearly, like using .net APIs and a JS front end it can make sense to use some degree of nextjs if you need to integrate some compiled parts into your react, maybe you need a fast loading and/or front page then it can be valuable to mix it.
If you don’t know why you’d need it, you probably don’t, however.
CRA isn’t really an alternative because it doesn’t have a server-side component. It’s also a lot less opinionated around things like routing. I’d say Remix is probably the main competitor to Next, that’s built around React Router and already has support for nested routes/layouts, and has opinionated support for the server-side too.
I'm implying that if you "don't need Next.js", because it's too heavy-weight (because e.g. you already have a dedicated team working on the back end API using a different language), then too bad: there's no lighter-weight alternative that is viable.
Nextjs has useful defaults and enough basic elements for front-end.
create-react-app is just a bunch of oppinions on how to config your app that dont really add much productivity if you are already familiar with webpack. Depending on the need I'd either go with react and my webpack config copied from last project or nextjs. Don't see the point of cra
What amazing news! Nextjs is fun to use, but the pages concept has felt a little clunky. Nuxtjs (vue's version) has a great pages abstraction, but it doesn't nest layouts, like this proposal.
There's some obvious inspiration from other frameworks, as Remix and Angular 2.x have had nested routing for years.
Hopefully this will allow for less repetition in pages and a more elegant structure to projects.
Exactly. Remix creators wrote in a blog post that they inspired by Ember.js. It looks to me people reinvent the wheel all the time. Luckily Ember.js provides all these functionalities for a decade now and just getting better.
Lee from Vercel, happy to answer questions about the RFC or future plans for Next.js. This RFC has been years in the making – and I'm pretty happy with where we've landed.
I like that you have thought about incremental adoption. However it looks like you're effectively deprecating the "/pages" directory. Which kind of sucks, as it's much more informative name, than the new generic "/app" folder.
Also, does this mean you cannot have a page named "layout" anymore?
Lastly, I appreciate all the hard work that goes into nextjs, it's a great developer experience and my goto framework.
Part of the thinking behind `app/` is that each section of your application can become its own app. Separate layouts, separate data fetching, and more. `pages/` was mapped very linearly to routes – `pages/index.js` was the index route. But with `app/`, that is not the case.
That's a good point about having a route `/layout` – I will check with the team about that.
Not seeing it in the article, but how are you handling `index` routing in the `app` folder? If you are putting it in the top directory (e.g. `/app/index.js`), is it not able to get a custom `layout.js` file (as that position is used for the global variant)?
If it's in an `index` folder (e.g. `/app/index/page.js`), how would one create a route for `example.com/index`?
The current working idea is that you wouldn't use index.js. There are Layout Components and Page Components, both explicitly defined by `layout.js` and `page.js`. We are open to other opinions here, though. Others have shared similar sentiment: https://github.com/vercel/next.js/discussions/37136
Am I correct thinking this will help create a simpler integration with - just hypothetically - Prisma calls that are dependent on app auth states in a single page? Replacing auth providers and moving them into Layouts?
I'm excited to see the wheels turning, but it feels a bit like the best feature of Next.js IMHO (SSG) is going to get more difficult, or possibly become unusable. A deprecation feels incoming. It could be confirmation bias as I've been a little worried about that for awhile since people using SSG aren't as likely to buy cloud services, so there's some incentive misalignment there, but ever since the Image component was only supported with SSR it's felt like SSG was going to either become less usable or disappear. Am I the only person who loves that feature? It really revolutionized how I approach web dev and enlarged my imagination of what was possible, so there's definitely some emotional attachment for me :-)
Naw, I don't agree. SSG is a killer feature. The fact that Next.js is able to do both SSG and SSR means that it's positioned to be a wholesale replacement for most React tech stacks. You can still have a "CSR-like" app with SSG, while having all of the Next.js conventions (such routing, layouts, etc.). Additionally, it's actually pretty useful for sites that need to be heavily SEO-optimized. Next.js is an impressive framework.
Static isn't going anywhere. In my opinion, one the best parts about Next.js is you can blend static with dynamic, on a per-page basis. Your landing page can be completely static + periodically updated in the background (i.e. ISR) and your /dashboard page could be a fully server-rendered application behind auth. You can do both without ejecting from the framework and being able to update and receive performance/security improvements. We've called Next.js a "hybrid framework" because of this, but I don't have a great name for it.
I never liked it either. At my last job I actually had a system which generated the Next.is pages folder based on a route config. The irony being that at build time, Next would then turn this folder into an internal route config that probably looked quite a lot like mine.
I don't like this approach either as maintenance gets complex over time. Changing routes in my React-router project is one file, one commit that's easy to verify, try changing a dozen routes with Next and you end up with a dozen of files moved around, with folder structure possibly impacted as well, I see this as an anti-pattern.
That's true, the pull request diff viewer does not make viewing file renaming very clear and there could be conflicts.
On the other hand, what I see in practice is adding or removing context providers and layout components in the react router file, it becomes huge, and all the diffs change all of the lines with new indentation.
I've worked with both. There are days when I prefer a programmatic approach, and days I love the file-based router. With the introduction of routing middleware [0], Next.js finally offers anything I'd want to build.
An option would be to add a catch-all route [1] at the root and implement your own code-based routing. You can still define the desired paths using getStaticPaths [2] but my guess is that some functionality like route-based code splitting will stop working.
I prefer the directory structure approach as it makes it a lot easier to find the code related to a route. In other approach you can spend a lot of time finding the right files. The directory structure based routing really makes things a lot more convenient. I can imagine it's annoying when you move routes/urls a lot
It’s always (or at least for a long time) had a layout, where you can define components that your page fits into. It’s really nice for putting a login status in a navbar, or something like toast notifications, because the layout components don’t get replaced when you navigate client-side.
But it’s not nested currently, you only get one layout - so if you want some pages to have a sidebar or something then you’re not getting the benefit of the layout system for that.
Next.js routing was wrong from the start, and now it introduces a tons of new concepts that will inevitably require the rewriting of entire apps in a far future, since it will be "the new way to do routing in Next.js".
What I really don't like is the coupling between the filesystem hierarchy and the actual routes, that is difficult to reason about when you have non english routes names with multiple route parameters.
I mean, the routing problem for server side applications was solved a lot of time ago: a simple regex for the route definition, and the related handler that will responde to that route.
I never understood why Next.js guys went with this inconvenient approach of the file system routing.
Looks like a nice improvement, looking forward to trying this out.
Nested layouts was the one stumbling block we had with next and felt very odd that we had to invent our own TabPane component to handle this pretty common use case.
Every time I hear any news about routing in a React framework I always get disappointed that the news isn't that they're introducing type-safe (TypeScript) routes to enable type-safe linking.
I'm curious about what you mean. There's no way to embed type information into a URL - every GET parameter is a string. Are you suggesting that visiting a link like /123 would go to the 'string: "123"' route, while clicking a <Link to={123}> would route you to 'number: "123"'? That would make deep linking in an app really hard to manage. I'm struggling to understand why you'd want to overload routes like that.
edit: I did implement this a while back but found it gave me only so much additional value. Though I can imagine that large applications with dozens of developers might indeed benefit from type-safe routes to avoid dead links.
When learning next recently I was immediately wondering how to do accomplish certain routing patterns that I had used in a previous project… routing to a specific tab of a modal that pops over a particular page…
Luckily that level of deep linking hasn’t been asked for, but this sounds really promising for adding some flexibility
I've stayed at the periphery of front end tech. I am comfortable with react, but often eschew it for the impedance mismatch with the server.
With the rise of server side front end practices, it dawns on me that there may be opportunities for integration with other server side runtimes? Asked naively, is there any possibility of an "FFI" integration for Next APIs? Anything more sophisticated than running a subprocess javascript VM?
I can recommend giving your component name (not file name) some identifier (like an underscore), so using VS Code's "Symbols" via command palette makes it easy to find and open them.
Next.js looks so, so much more mature than Joystick, the latter appearing to be one person's pet project. I don't understand why you shared it in this thread, and i really don't understand the "don't do drugs" bit.
Frameworks like nextjs are in an eternal existential battle to stay relevant. In my 4 years of using Next, I experienced a large number (6 or 7 releases) of major version releases.
What the industry needs is not more breaking changes, but solidified frameworks that companies can rely on.
Every major release adds another wave of technical debt as things become deprecated.
I appreciate updates, but to me this particular proposal shows a lack of long term vision for the framework, attempting to throw in all the exciting bells and whistles from competing frameworks.
This philosophy of “lets stay relevant” will ultimately cost businesses.
My comment is probably not super helpful, but after several years in javascript land I found myself exhausted by the churn and constant rapid change. I've found myself really happy to be using the PETAL stack (Phoenix Elixir Tailwind Alpine LiveView) where the pace is a lot slower. There are now similar options in Rails (Hotwire) and Laravel (LiveWire), and probably others. If you haven't heard of those, it's definitely worth a look. The only situations in which I don't use them now are when there's a need for rich offline functionality. I still have several static sites in Next.js that I'll leave in place but I've been a lot happier since shifting my bulk to PETAL. (I'm also close to replacing my last big WordPress site with an Elixir one!! Knock on wood.)
We've been very intentional about incremental adoption and reducing the number of breaking changes, as well as giving folks codemods when they upgrade and providing escape hatches. For example, when upgrading to Next.js 12, which turned on SWC by default, we had already been testing an experimental version for many months which folks could try out. Then with 12, you could opt-out in the config if you didn't want to use it by default.
We're using a version of the persistent layout pattern Adam Wathan [blogged about](https://adamwathan.me/2019/10/17/persistent-layout-patterns-...) but having first-class support for this paradigm will be awesome.