The New Next.js App Router

Rate this content
Bookmark

Next.js 13.4 recently released the stable version of the "App Router" – a transformative shift for the core of the framework. In this talk, I'll share why we made this change, the key concepts to know, and why I'm excited about the future of React.

27 min
02 Jun, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Today's Talk is about the Next.js App Router, which has evolved over the years and is now a core feature of Next.js. The Talk covers topics such as adding components, fetching remote data, and exploring layouts. It also discusses submitting form data, simplifying code, and reusing components. The App Router allows for coexistence with the existing pages router and enables data fetching at the layout level using React Server Components.

Available in Español

1. Introduction to Next.js App Router

Short description:

Today, I'm gonna be doing something a little different because my talk will be entirely in VS Code. I'm Lee and I work at Vercel and I lead the Next.js community. We recently released something called the Next.js App Router. Today, I'm gonna be walking through a demo of what the App Router looks like. Next.js has evolved a lot over the years. It was originally released in 2016 and it had a certain way of building. I'm gonna talk about the journey through a real application of how we landed on the App Router today. The core of Next.js is routing. We released Next.js in 2016 with file system-based routing. This is what Next.js was built on six years ago. We're going to be building an internal app dashboard that shows a list of invoices and has some settings pages with layouts. Let's start scaffolding out this page a little bit more. We'll use the home layout for the nav bar and invoices. This is the shell of our homepage.

Today, I'm gonna be doing something a little different because my talk will be entirely in VS Code. Woo! So, like she said, I'm Lee and I work at Vercel and I lead the Next.js community. If you haven't heard of Next.js, it's a React framework. And we recently released something called the Next.js App Router. Has anyone heard of the App Router? OK, that's more hands than I expected, that's awesome.

So for those who haven't, what I'm gonna be walking through today is a demo of what the App Router looks like. So the premise of this talk is called Next.js Metamorphosis. And the name for that is because Next.js has evolved a lot over the years. It was originally released in 2016 and it had a certain way of building. And I'm gonna talk about the journey through a real application of how we landed on the App Router today.

So what I have here is my editor on the left running a Next.js application and then my browser. And the first thing we're gonna start off with is the core of Next.js, which is routing. We released Next.js in 2016. We said we love file system-based routing. We wanted to make it as easy as possible for you to get started. Just drop a file in a folder and it will create a new route. So I have pages slash index.tsx here. So if I do export default function home page and I say return React summit and save. We see React Summit. This is all it takes to get your first route up and available on your local server or in production and this is what Next.js was built on six years ago.

Now what we're going to be building today is kind of an internal app dashboard that shows a list of invoices, it's got some settings pages that have some layouts and we'll get into more some of the advantages of some of the new things we've been using. So let's start scaffolding out this page a little bit more. So rather than returning a string here, let's return some layout component and we'll see if my VS code is not giving me my helpful auto-completes, but that's okay. We can manually type things out. That's fine. We'll do import layout for components and I have two different layouts from application. We have a home layout so we'll use that one here. There we go. Okay, so we have a nav bar that's going to be shared throughout our application and then we have my invoices. So this is kind of the shell of our homepage.

2. Adding Components and Fetching Remote Data

Short description:

Now let's add some components like cards and tables to display statistics about our account. We'll fetch remote data using the get initial props API and pass it to our React components. This API runs on the server and on page transitions. To improve this, the API was split into two separate functions: getinitialprops and get server side props.

Now inside of here, we also want to have some components and display some UIs. So let's do some cards that are going to display some statistics about our account, maybe how much money is in our account, what the invoices are and then we'll also do, oh, there we go, it's coming back, it's trying to help me out a little bit here. Components slash table, let me just manually import the card as well too, import card from components card.

I scaffolded out some UI components for us to use ahead of time. Cards, cards, okay, cool. So we have some cards that don't have any data right now. And then we have a table with some static data.

The core of Next.js is built on React, allows you to compose components but very frequently you need to actually fetch some remote data and pass it to your components. So the first API that Next.js released to do this back in 2016 was called get initial props. So let's use that to actually fetch some data and put it on the page. So I'll say homepage.getinitialprops and this is gonna be an async function that we want to fetch some data from. So we'll do cons data equals await get card data. And then we're gonna return that data to the page. So let's see. Nope, I'll type it out myself because oh, there we go. Okay. From our library from our database, I'm gonna import this function get card data that's gonna return some JSON here, we're gonna return that data from this function, and that gets forwarded to our React component. So inside of our React component, I have props so I can de-structure out data here. And we'll just throw on some any type here. Gotta love that. And then down below on our cards component, we can forward along that data by passing props. So I'll do data here and I'll hit save. We have data on our page. Woo! Love it. This works. And we're able to fetch remote data, but it does come with some tradeoffs or some things that maybe are not obvious. So this runs on the server, but it also runs on page transitions. So this first API left some room for improvement for us to clarify how you would actually import and use these functions for fetching remote data. So the metamorphosis of this, the next evolution of this API was breaking this into two separate guys. So export async function get server side props, and okay, cool.

3. Exploring Data Fetching and Layouts

Short description:

Copilot helps with async functions that return objects. You can choose fresh data on each request or pre-render during build. Slow APIs can cause loading spinners and blank pages. It's challenging to define loading states next to components. Fetching data on the client side can have tradeoffs. We'll build out settings pages with different layouts.

Copilot is going to help me out today. We'll see if that works. So this is basically the same thing structure-wise. You have an async function that's going to return an object. In this case there's a key for props. So if I hit save, it also forwards the data long to the page. But the difference is that this is explicitly marked as get server side. So it makes it a little bit more clear to developers, hey, this is running on the server side and it's forwarding that information over to components.

Now the counter to this or the pair to this is get static props. So you get the option whether you want to choose do I want my data to be fresh on every request, or do I want to pre-render this during the build and potentially incrementally update it later.

Now let's talk about some of the potential areas for improvement with this. Let's say our API is slow. And to simulate this I'll just throw on a two second delay here into get card data and you see our browser loading spinner spin and spin and spin and spin. Now when you're doing this top down data loading you have all or nothing data fetching for your page. Either you have all of your data or you have none of it. So maybe to make this a little bit more dramatic I'll go to about blank and then I'll go back to local host and you see this is what your users are seeing. This is what your customers are seeing. A loading spinner and potentially a blank page. That's not a great experience. Ideally we could show some kind of visual indication to our viewers whether that's maybe something like a loading state on the components. That would be kind of nice. Now unfortunately one of the areas for improvement here is that it's not easy to declaratively define your loading state next to your component. Ideally this card component knows about the data it needs, it knows how to load and it knows how to define its fallback or the loading state that we're showing here. Now the way this would work in the Pages router of Next.js is that you often had to change your strategy of fetching data. So instead of fetching data on the server if I wanted to have this co-location of data, UI loading states, I would need to fetch data on the client side or just normal React in the browser. And that works but it can also cause some other tradeoffs as well, too. So there's some opportunities for improvement here that we're going to talk about in the app router, but we'll pause on this page and we'll move to another page. So in our application, we have our homepage with some invoices, some cards and a table, but we also have some settings pages that look slightly different and have a different layout. So we're going to build out those. So let me do an export default function settings page and we're going to return some layout here.

4. Creating Settings Page Layout and Form

Short description:

This part focuses on importing the layout from the settings layout and creating a different settings page layout with a top bar and sub navigation. It also demonstrates how to create a form to submit data, including components like name, bio, and a button. The button can take in children and is used to update the profile.

This is going to be import layout from settings layout. And I have the you don't need to have all those paths. See if that works. Test. Yes. Could be a I don't remember if it's the default or name to export. Let's see if that works. Yes. Whoo.

Okay. So we have the same Nav bar that's shared across our application and then we have a slightly different settings page layout here that has this top bar but also this sub navigation for our page. So we're going to have two different pages here. We're going to have a profile page for settings and a display settings page.

Now inside of here, let's do a form. So we're going to show how to actually submit some data here and we're going to do this by scaffolding out name component. Let's do maybe a well let's see if this works. Name no. OK. Bio, these are just going to be inputs that we can use our application. Maybe a button. Yes, OK. And maybe this button is going to take in some children because we can just forward along those that child to our component. And we'll say this is going to be something like update profile, for example. Let's will it auto do it? No, it won't. OK. Import name bio components. Basically don't remember what the path is here. What is it? Component, is it in settings layout? It probably is. It's better when it automatically gives you the import, that helps a little bit. Let's see, cards, minimal, nav bar.

5. Submitting Form Data and Handling Tradeoffs

Short description:

Where is it? It's in the settings layout. My editor doesn't want to update. Let's see if that works. It works. One day VS Code will help me out more. I have a name input, a bio input, a normal button that takes in some child. And I want to submit this form. The way most of you have been building Next.js or React applications is you use an event handler to do this. We have a function handle submit that takes in the event handler. We're going to not reload the page. We're going to get the values from the inputs. And then we're going to call an API route in Next.js. This API route allows us to write some back end code, expose an API if we'd like. This works, but it does come with some tradeoffs, notably that this requires client side JavaScript to run, so the progressive enhancement story could be better.

Where is it? It's in the settings layout. My editor doesn't want to update. Let's see if that works. It works. One day VS Code will help me out more.

I have a name input, a bio input, a normal button that takes in some child. And I want to submit this form. The way most of you have been building Next.js or React applications is you use an event handler to do this. Go to our form and say, you know what? On submit we want to call some function handle submit. Because I would absolutely fat finger this, I'm going to drop in a snippet for this one because it's a lot of code. And we'll see how we can delete some of this code here in a second.

We have a function handle submit that takes in the event handler. We're going to not reload the page. We're going to get the values from the inputs. And then we're going to call an API route in Next.js. This API route allows us to write some back end code, expose an API if we'd like. We have API submit here, that forwards the body of our two inputs. And then it basically just echoes out or returns those values. So I actually went ahead and set up this API ahead of time. It's basically just console logging out the values on the server. So let me close this. I'll save here. And let me just pull this up here. And let's say I want to change this to React Summit. I'll hit update profile. And on the bottom left here, you can see in my console output on the server, we see the name in the bio from our API route logging out the information. So this is pretty typical. You need to have this code running on the server so that you can securely connect to your database or pass along an environment variable that has a secret key. You wouldn't want to have this run in the browser and expose those values. Now this works, but it does come with some tradeoffs, notably that this requires client side JavaScript to run, so the progressive enhancement story could be better.

6. Simplifying Code and Reusing Components

Short description:

There's a lot of extra code that you need to write. We're going to see some ways that we can reduce a lot of that code and simplify the mental model. Let's talk about reusing layouts and components. We have a component called minimal mode that allows toggling of data shown in the invoice table. We can co-locate our data fetching with our components to avoid passing data from server to client. Let's make our application smoother by deleting unnecessary code.

And also, as you can tell, there's a little bit of ceremony code here. That would be the nice way of putting it. There's a lot of extra code that you need to write. And we're going to see some ways that we can reduce a lot of that code, and also simplify the mental model hopefully a little bit as well, too.

Now, while we're here, I also want to talk about that layout. You notice I've been importing this component that has the layout for our application. Well, what about when I want to have another page that uses the same layout? I actually won't write this one out fully because it's pretty small. But if I want to have this display page that's also in the settings, we're going to use... We're going to use... Let me just close this here. So pages slash settings slash display. We're going to use that same layout, and it's going to take in a component I'm going to call minimal mode. So let's take a look at what this looks like. I'll click over to display. We have this component called minimal mode that allows you to toggle how much data we want to show in our invoice table.

Now what you would love to do is reuse, that's the great power of React, reuse that table component, the same table component that we used on the home page. So this works. We can input it here, but this comes with another opportunity for improvement. Right now, this table data, if I actually jump into this file, this is not asynchronous, this is static data, which means that I'm able to actually do this. But if all of the sudden, this was instead data equals data, and I needed to forward in some data from a remote location, that would mean that this page would need to have some kind of data loading function, a get server-side props, the index page would need to have that same data loading function. Everywhere you would consume that component would need to pass that data and serialize it from server to client. It would be great if we could co-locate our data fetching with our components.

So, now that we've got this scaffolding of our application across the index route and the settings route, let's take a look at how we can make some of these things a little bit smoother. So, what I'm going to do is actually go to our index route. I'll just copy-paste all this code. And, then I'm going to go to this brand new app directory and I have a new subfolder and then a new file page. So, page is this special convention that marks a piece of UI that's routable. So, I'm going to paste in our code previously and let's start deleting code. That sounds fun. So, let's take this promise.

7. Fetching Card Data and Handling Slow Data

Short description:

We removed the Next.js specific API and instead used an asynchronous function to fetch data. The layout for our application can now be defined through the file system, streamlining the process. We can handle slow data fetching by presenting a loading state to the user. The data fetching is now co-located with our cards component, allowing for more flexibility in handling data delays.

We want to go fetch some card data. We'll keep this. But what if we removed the Next.js specific API. What if we removed the forwarding of props to serialize this in between here and instead we just said, you know what? This is an asynchronous function and we're going to fetch some data in it. Well, that seems pretty simple, doesn't it? So, let me hit save here and then I'll go to locos3000 slash new and we see the, let me reload the page here. Oh, I have the loading state. It threw me through a loop there. And I was like, is it loading? We see the exact same thing that we saw before, which is we have data displayed in our cards.

Now for the good eye here, you might be wondering why are there two nav bars? And the reason for that is because that state is actually shared between all of the routes. That layout is the global piece throughout our application. Now, luckily in the App Router, there's a new way or a new convention that allows you to define your layouts through the file system. So the route layout for our application, it's importing our global styles, and it's using that nav bar, which is the part that's actually shared throughout the application. So what that means is that this layout can actually be the part that's only shared for the home page. So you know what? Let's get rid of this nav bar. We don't need that anymore. OK. So that streamlined that down a little bit.

But what about that problem I mentioned about if the data is slow, does that still exist? And the answer is yes, that problem still exists, because now you have the flexibility and the optionality to choose how you want to handle this. So let's say, you know what? We actually want to stream in data out of order. This card UI, we know that this API or this database call might be a little bit slow. We don't want to block the rendering of the page while waiting for this data to come in. Instead, we want to present the user with a loading state. So you know what? Let's remove this, and let's remove this, we'll remove this, we'll remove this, too. And we're going to do the data fetching co-located with our cards component. So I'll pop in here and let's mark this as an asynchronous function. This is a React server component. And then I'll say, you know what? If we pass the slow prop of true, then we're going to fetch our card data, and we're going to have this delay here. So now, back inside our main index route, let's declaratively define what we want the loading state to look like. So I'm going to take this and we're going to wrap it in React suspense, and we're going to throw the slow prop on here, and then we're going to define a fallback state of how we want loading to look like, and that's going to be cards loading. So I'll hit save here.

8. Reloading Page and Refactoring Code

Short description:

And now, when I reload the page, I instantly see the UI with the data streaming in. The data is co-located with the component, making it much nicer to work with. Let's move on to the second problem, the profile page or settings page. We can refactor the code to run the component entirely on the server as a server component using React server actions. This eliminates the need for a separate API fetch and allows us to use an action on the form with a server-side function.

And now, when I reload the page, actually for dramatic effect, dramatic effect is fun. I'll go to about blank, localhost new. We instantly see the UI, the data that's slow gets to stream in out of order, and it gets to be co-located with the component. So you keep the data close to where the UI is actually being rendered. That's a big improvement. I think that's much nicer to work with. So that's one problem down.

I'll try to go fast here. The second one is the profile page or the settings page. Let me just go back to here. I'll copy-paste this code over into the new page, and let's look at how we can refactor this from the previous way to a new way in the app router. So as I mentioned, one of the opportunities for improvement is there's a lot of ceremony code. What if we didn't have to make a fetch to a separate API? And what if instead we could run this component entirely on the server as a server component? Well, we wouldn't be able to use an event handler. We need something new. And with the introduction of React server actions and the integration into Next.js app router with the caching and revalidating layer, we made it so that you can do something like this.

I want to have an action on my form, and actually I'm going to denote this button as a type of submit because it's just using the HTML form here. It's just using a button with type submit. And this action is going to take a function. This could be like save to db or something. Now, instead what we can do here, let's just get rid of this entirely, actually, because we don't need an event handler. We're going to have an async function save to db. Copilot is very wrong here. It needs to learn how this works still. And it's going to take in not from data, but form data, which uses the web form data here. And this function is going to run on the server. So the way that we denote this as a server action is through the use server directive. If I can type, there we go. And then we can get the data from form data, the name, and the bio. And then let's just console log these out here. That looks right to me.

9. Refactoring Layouts and Co-locating Data

Short description:

We refactor the shared layout between the home page and settings pages into the file system layouts. The layout component is lifted up to the layout file, eliminating the need for separate API routes. The display page and settings page can reuse the shared layout. Data can be co-located with UI using react server components, allowing for asynchronous functions and caching of data.

Okay, new slash settings slash profile. But whoa! What is going on here? We have layout's inception. What is this? Like we showed on the home page, there's an opportunity to improve how we handle layouts. So I mentioned there was a piece of our layout that was shared between the home page and the settings pages. Let's actually refactor that into the file system layouts. And to do that, you see we have a new nested layout in the app router, and this is taking in that settings layout component that shared between the two routes. So we've actually moved that state up, and critically, this component will not re-render. So if we wanted to have state in here, when we transition between pages, like a toggle or something, that would not get reset. Now, that's not in the demo, but it's just good to know. So if I go back into here, I actually don't need this at all because it's been lifted up to the layout file, so I can remove that entirely. And we're making progress, but we still have the double nav bar, so we want to go into here and say, you know what? For the settings layout, we don't need this anymore. Boom. Goodbye. There's our new feature, double nav bar. OK. That's looking good.

Now, the moment of truth. Does this simplified function, this server action where I just call a function directly, I don't have to make a separate API route, does this work? I hope so. It does. Woo! Awesome. I don't know about y'all, but that code looks a lot more fun to write to me. So that's definitely an improvement there. The last thing I'll touch on before we go into QA is just to mention that the display page and our settings page can also take advantage of lifting up and reusing the shared layout between the two routes. And because the app router is built on react server components, we could now co-locate data with UI. If we wanted this table, for example, we wanted to say, you know what, actually, this is going to be an asynchronous function. We're going to await getting some data. This is going to run and cache that data, cache that fetch as static by default, which means that this works whether you deploy to a Node.js server, you deploy to somewhere like Vercel, or you even export it as a set of HTML and JavaScript files, because this can be cached and pre-rendered during the build. Now, let's say you want to take advantage of some server features. Maybe we want this list of invoices, and it doesn't update too often. Maybe update every 60 seconds.

10. Exploring App Router Features and Coexistence

Short description:

We can periodically update the data every 60 seconds by setting the revalidate value. The App Router allows for a clear boundary between server-side and client-side code, enabling the use of React hooks on the client. The App Router can coexist with the existing pages router in the same Next.js application. You can incrementally adopt the App Router as you and your team are ready. The App Router is stable now, but you don't have to move away from pages immediately. Both routers will continue to be supported and maintained.

Well, we can still cache that to static data by default, but then maybe we say, you know what, export const revalidate 60 seconds. So we want this route segment or this component to update every 60 seconds. That's all it takes for us to periodically update that data at most every 60 seconds.

So I know I blew through a lot of things here. There's a lot more that I could cover, even getting into talking about how client components work. So let's say maybe this minimal mode toggle, we wanted to have some state. I'll just quickly show that as well, too, since I'm right here. Let's say we wanted to have data and set data or something. We want to have used state, something like this in our minimal mode for this toggle. Well, this is going to show an error. Well, can't find used state, that makes sense. But let me actually import it here. And now what we want to do here to actually be able to use used state, we would say, you know what, to have an interactive component on the client side, we have a much more clear boundary between what runs on the server and what runs on the client. So we're going to explicitly mark this with the used client directive to say that this component has access to using any React hook in the ecosystem, built-in hooks like used state or used effect. So now, hopefully, the code is more clear, which code has the ability to also run on the client, and which code runs only on the server.

This was a whirlwind run-through of the App Router. Hopefully, this gave you a better overview of some of the new features that we're working on in Next.js. The final hat trick here is that this all works in the same Next.js application. All of the APIs that we worked on and used from day one, get initial props, everything that we've built from the start, this can all coexist in one application and harmoniously live together. So you can keep your pages router, which is working great in production today, and then incrementally adopt the App Router as yourself or your team is ready and try out some of these new things.

So thank you all for listening to my talk and I appreciate it. Because the App Router is stable now, should we move away from pages ASAP or will it still be maintained for the long term? Yeah, great question. Hopefully, the goal of my talk was to show that it's been designed for these to live together. So you don't necessarily have to move from pages to App Router today. Even though the core is stable, there's still going to be bugs and things that we're working through. And we really appreciate everybody giving feedback and trying things out as we move the core over to stable. I would say adopt things as you feel ready for your team but you shouldn't feel pressured into moving over. Both can continue to live and the pages router will continue to be supported. We're even adding some new features there as well, too. So it's definitely going to continue to be maintained.

11. Data Fetching in SSR for Layouts

Short description:

The great thing about React Server Components is that you can now fetch data at the layout level. This means that you can fetch data for a shared layout, such as user information, and share it across all pages. This was not possible before with the pages route.

Cool. Awesome. That's great news. Yes. A lot of votes for when is data fetching becoming available in SSR for the layout? For example, fetching and navigation for a shared layout. Yeah. So the great thing about React Server Components, the foundation of what we built in the App Router is that all the examples I showed today were fetching data inside of the page. But if we wanted to, we could actually lift that up to the layout. And for example, I had that layout component for our settings pages. Let's say we needed to fetch some user information and share it in a navbar between all of the pages, you can actually still do that. You can mark the layout as asynchronous. You can await some data fetch. And that was not possible before in the pages route. There was no data fetching on the top level.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
JSNation 2023JSNation 2023
28 min
SolidJS: Why All the Suspense?
Solid caught the eye of the frontend community by re-popularizing reactive programming with its compelling use of Signals to render without re-renders. We've seen them adopted in the past year in everything from Preact to Angular. Signals offer a powerful set of primitives that ensure that your UI is in sync with your state independent of components. A universal language for the frontend user interface.
But what about Async? How do we manage to orchestrate data loading and mutation, server rendering, and streaming? Ryan Carniato, creator of SolidJS, takes a look at a different primitive. One that is often misunderstood but is as powerful in its use. Join him as he shows what all the Suspense is about.
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai

Workshops on related topic

React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
React Summit 2023React Summit 2023
139 min
Create a Visually Editable Next.js Website Using React Bricks, With Blog and E-commerce
WorkshopFree
- React Bricks: why we built it, what it is and how it works- Create a free account- Create a new project with Next.js and Tailwind- Explore the directory structure- Anatomy of a Brick- Create a new Brick (Text-Image)- Add a title and description with RichText visual editing- Add an Image with visual editing- Add Sidebar controls to edit props (padding and image side)- Nesting Bricks using the Repeater component- Create an Image gallery brick- Publish on Netlify or Vercel- Page Types and Custom fields- Access Page meta values- Internationalization- How to reuse content across pages: Stories and Embeds- How to create an E-commerce with Products’ data from an external database and landing pages created visually in React Bricks- Advanced enterprise features: flexible permissions, locked structure, custom visual components
React Summit 2023React Summit 2023
71 min
Building Blazing-Fast Websites with Next.js and Sanity.io
WorkshopFree
Join us for a hands-on workshop where we'll show you how to level up your React skills to build a high-performance headless website using Next.js, Sanity, and the JAMstack architecture. No prior knowledge of Next.js or Sanity is required, making this workshop ideal for anyone familiar with React who wants to learn more about building dynamic, responsive websites.
In this workshop, we'll explore how Next.js, a React-based framework, can be used to build a static website with server-side rendering and dynamic routing. You'll learn how to use Sanity as a headless CMS to manage your website’s content, create custom page templates with Next.js, use APIs to integrate with the CMS, and deploy your website to production with Vercel.
By the end of this workshop, you will have a solid understanding of how Next.js and Sanity.io can be used together to create a high-performance, scalable, and flexible website.
GraphQL Galaxy 2021GraphQL Galaxy 2021
161 min
Full Stack GraphQL In The Cloud With Neo4j Aura, Next.js, & Vercel
WorkshopFree
In this workshop we will build and deploy a full stack GraphQL application using Next.js, Neo4j, and Vercel. Using a knowledge graph of news articles we will first build a GraphQL API using Next.js API routes and the Neo4j GraphQL Library. Next, we focus on the front-end, exploring how to use GraphQL for data fetching with a Next.js application. Lastly, we explore how to add personalization and content recommendation in our GraphQL API to serve relevant articles to our users, then deploy our application to the cloud using Vercel and Neo4j Aura.

Table of contents:
- Next.js overview and getting started with Next.js
- API Routes with Next.js & building a GraphQL API
- Using the Neo4j GraphQL Library
- Working with Apollo Client and GraphQL data fetching in Next.js
- Deploying with Vercel and Neo4j Aura
React Summit 2022React Summit 2022
50 min
High-performance Next.js
Workshop
Next.js is a compelling framework that makes many tasks effortless by providing many out-of-the-box solutions. But as soon as our app needs to scale, it is essential to maintain high performance without compromising maintenance and server costs. In this workshop, we will see how to analyze Next.js performances, resources usage, how to scale it, and how to make the right decisions while writing the application architecture.