MIGRATING TO NEXT.JS APP ROUTER
The App Router isn't just a new file convention — it's a different mental model for how a Next.js application is structured. The shift from pages/ to app/ brings React Server Components to the forefront, which means the default is now to render on the server, and you opt into client-side interactivity with the 'use client' directive rather than the other way around.
The biggest practical change is data fetching. getServerSideProps and getStaticProps are gone. Instead, async Server Components fetch data directly — you just await a database call or fetch inside the component body. This colocation of data and UI is cleaner conceptually, though it requires rethinking patterns built around the old lifecycle.
Layouts are the other major improvement. The nested layout system means shared UI — navbars, sidebars, footers — only renders once and persists across navigation without remounting. In the Pages Router, you'd lift shared layout into _app.tsx or repeat it on every page. App Router solves this cleanly at the file system level.
The rough edges during migration mostly come from third-party libraries that haven't updated for RSC yet. Anything that uses React context, hooks, or browser APIs needs to be inside a Client Component boundary. Mapping out those boundaries early — deciding what truly needs to be interactive — makes the migration go much smoother.
For this portfolio, the migration was straightforward because there's minimal server-side data fetching. The main win was the persistent header layout and cleaner route organization. For a larger app with complex data dependencies, the planning work upfront pays off in a significantly simpler codebase.