Since my experience in front-end development is mostly with React, I recently built a full-stack movie app using the Next.js App Router and PostgreSQL to get more comfortable with these technologies. The app supports searching, adding, editing, and deleting movies, as well as authentication. It’s open source.
This post is a companion to the source code and gives an overview of the project structure along with explanations of files and directories using a tree UI component.
It’s assumed that you have a basic familiarity with the Next.js App Router.
movie-app project structure:
Notes
Redirect from middleware not working properly with server functions
During working on this project I encountered one problem. Currently even Nextjs docs mention that you can perform auth checks inside middleware (though they mention this should not be your only line of defense). So you often encounter code like this inside middleware:
if (isProtectedRoute && !session) { return NextResponse.redirect(new URL('/login', req.nextUrl)) }
This works most of the time but there was one situation where it was causing a problem.
Suppose we are on a protected page and the session expires. If then I invoked a server function from that page:
startTransition(async () => { // Call a server function const result = await addMovie(data); // ... });
the addMovie
call triggered the middleware. Because we are on a protected page and the session had expired,
the middleware attempted to redirect using NextResponse.redirect
(as shown in the previous if
check).
However apparently since the middleware was called due to server function, the redirect didn't
happen. The addMovie
function itself never ran and simply returned undefined
.
My current solution is from here, to configure the middleware such that it ignores server functions. I do auth checks in server functions though.
Source Code
You can find the source code here.