BACKEND2026-03-15📖 15 min read

5 Next.js Best Practices You Should Know in 2026

5 Next.js Best Practices You Should Know in 2026

A curated look at five essential Next.js best practices for 2026, covering App Router, Server Components, and more — explained clearly enough for beginners to follow along.

髙木 晃宏

代表 / エンジニア

👨‍💼

"I want my website to load faster." "I know I should be using modern tech, but I don't know where to start." If you've ever thought something along those lines, you're not alone. In this post, I'll walk through the latest Next.js best practices — drawing from my own hands-on experience — to help you get the most out of this framework.

Next.js has become the go-to React framework for company websites and web services around the world. After a wave of major updates between 2024 and 2025, the framework has settled into a mature, stable feature set by 2026. I've hand-picked five practices that are most likely to have a direct impact on your business. I'll keep things as jargon-free as possible, so stick with me to the end.

Make App Router Your Default Architecture

Next.js offers two routing systems: the older "Pages Router" and the newer "App Router." Put simply, App Router is designed to give you better page load performance and more SEO-friendly architecture out of the box.

Honestly, I used to think Pages Router was good enough — until I actually migrated to App Router and noticed a clear difference in how fast pages felt. For any new project, I'd recommend going with App Router without hesitation. And if you have an existing site, you can migrate incrementally, so there's no need to panic.

Pages Router vs. App Router: What's Actually Different

Let me get a bit more concrete about the differences. With Pages Router, placing a file at pages/about.tsx automatically creates a route at /about. It's simple and intuitive, but it comes with limitations around shared layouts and data-fetching patterns.

App Router uses a directory-based structure like app/about/page.tsx. It might look more complex at first glance, but this structure makes nested layouts feel natural. For example, you can have a header and footer shared across all pages, a sidebar that only appears in the blog section, and so on — all without fighting the framework. What used to require workarounds like _app.tsx and getLayout patterns is now baked into the framework itself.

A Case for Incremental Migration

"Rewriting an entire working site all at once sounds terrifying." I hear this a lot, and the concern is valid. One client we worked with took a measured approach: they migrated only the homepage and contact page to App Router first, leaving the rest on Pages Router for the time being.

Next.js fully supports running both routers side by side in the same project. There's no risk of your entire site going down during the transition. Start with your highest-traffic pages, verify the impact, then expand from there. This approach lets you capture the benefits of modern architecture while minimizing disruption to your business.

Richer UI with Parallel Routes and Intercepting Routes

Two App Router features worth knowing about are Parallel Routes and Intercepting Routes.

Parallel Routes let you render multiple independent content regions within a single page. On a dashboard, for instance, a "Revenue Chart" and a "Recent Notifications" panel can each load independently. If one is slow, the other still appears right away — a noticeable improvement in perceived performance.

Intercepting Routes shine when building modal-style interactions. Imagine a photo gallery where clicking an image opens a modal with the full-size view, but navigating directly to that URL shows it as a standalone full page. This kind of "decouple the URL from the UI behavior" pattern is achievable without any extra libraries.

Speed Up Your Pages with Server Components

Server Components render page content on the server and send the result to the browser. This reduces the amount of JavaScript the user's device needs to download, making pages load faster.

I spent a while going back and forth on when to use which approach, but once I settled on "start with Server Components by default, and only move things to the browser when truly necessary," development became much smoother. Faster page loads correlate directly with higher contact form conversion rates, so this isn't just a technical concern — it's a business one.

Why Server Components Are Faster

In a traditional React application, the browser downloads all the JavaScript, and that JavaScript then builds the page. This is called client-side rendering, and it has a well-known problem: the bigger your JavaScript bundle gets, the slower the initial page load becomes.

With Server Components, the HTML is assembled on the server and delivered to the browser ready to display. The only JavaScript that needs to run in the browser is for interactive parts — button click handlers, animations, and the like. On one project, making this switch cut the JavaScript sent to the browser by roughly 40%. That might sound abstract, but the difference in perceived speed on a mobile 3G connection is significant.

When to Use Server Components vs. Client Components

The most common question I get in practice: "Where do I draw the line between Server and Client Components?" It took some trial and error, but here's the rule of thumb I've settled on.

Good fits for Server Components:

  • Content that just fetches and displays data from a database or API
  • Static information like blog posts, product listings, and company pages
  • Navigation menus and footers with no interactivity beyond standard links

Cases that require Client Components:

  • Form fields with managed state (character counters, real-time validation, etc.)
  • UI interactions like dropdowns, accordions, and tab switchers
  • Anything that uses browser APIs (geolocation, localStorage, etc.)

The key insight is to keep your Client Component surface area as small as possible. Rather than making an entire page a Client Component, carve out only the interactive parts as small, focused Client Components and leave everything else as Server Components. This approach is sometimes called the "islands architecture."

Push Perceived Performance Further with Streaming

A natural companion to Server Components is Streaming — the ability to send content to the browser as it becomes ready, rather than waiting for all data to load first.

Take an e-commerce product page: the product name and price can appear instantly, while customer reviews coming from an external API take a moment longer. With Streaming, you show a loading placeholder for just the reviews section, which snaps into place the moment the data arrives. In Next.js, this is declaratively handled with loading.tsx files or React's <Suspense> component.

The old choices were "show a blank screen until everything loads" or "build your own complex loading state management." Streaming eliminates that trade-off, giving users a smoother experience and reducing bounce rates in the process.

Simplify Form Handling with Server Actions

Contact forms, booking forms, quote request forms — every site needs them. Server Actions let you handle form submissions in a surprisingly clean and straightforward way.

Looking back, I was overcomplicating things by standing up a separate API just to handle form data. Simpler code means lower maintenance costs and fewer bugs. If form complexity is a pain point for you, this is a feature worth trying.

How Server Actions Compare to the Old Way

Before Server Actions, the standard form submission flow looked something like this:

  1. Collect form data on the frontend
  2. Send a fetch or axios request to an API endpoint
  3. Create an API route (e.g., /api/contact) on the backend to receive it
  4. Validate the input
  5. Save to a database or send an email
  6. Return a response to the frontend
  7. Handle the response on the frontend to show success or error state

Server Actions eliminate steps 2 and 3 entirely. You can point a form's submission directly at a server-side function — no separate API route file needed. The "form's appearance" and "what happens after submission" live together in the same logical flow, making the code much easier to reason about.

Security You Can Trust

You might wonder: "Is it really safe to write server-side logic alongside frontend code?" It's a fair question.

In practice, Server Action functions are explicitly marked with the "use server" directive and separated into server-side code at build time. What gets sent to the browser is only a reference to call the function — the function body itself (database credentials, business logic) is never exposed to the user.

On top of that, Next.js automatically applies CSRF (Cross-Site Request Forgery) protection to Server Actions, providing a baseline level of security without any extra configuration. Input validation and sanitization are still the developer's responsibility, of course, but not having to build your own infrastructure-level defenses is a meaningful advantage.

Built-In Progressive Enhancement

Another benefit of Server Actions is out-of-the-box support for Progressive Enhancement — the idea that a form's core functionality should work even in environments where JavaScript isn't running.

Forms built with Server Actions follow the standard HTML <form> element behavior. When JavaScript is available, submissions happen seamlessly without a page reload. When it isn't, the form still submits correctly, just with a full page refresh. This ensures your service reaches every user reliably and reduces the risk of losing leads due to edge-case browser issues.

Lock Down Your SEO with the Metadata API

To help search engines understand your site, you need properly configured metadata — page titles, descriptions, and more. Next.js's Metadata API lets you manage all of this in code, on a per-page basis.

It was something I initially glossed over, but taking the time to set this up carefully led to measurable search ranking improvements in some cases. It's a small technical effort with potentially large business impact.

Static vs. Dynamic Metadata

The Metadata API has two main modes: static and dynamic.

Static metadata is ideal for pages with fixed content — your About page, Services page, and so on. You declare the title and description directly in code. Simple as that. Even as your site grows, each page can have its own optimized metadata, which adds up to real SEO benefits.

Dynamic metadata is for pages where content varies — blog posts, product pages, and similar. It generates titles and descriptions automatically based on data pulled from a database or CMS. For example, using a blog post's title as the page title and its opening paragraph as the description is something you can implement in just a few lines of code.

Open Graph and Social Media Optimization

One area of the Metadata API that's especially worth using is Open Graph (OG) tag configuration. OG tags control how your pages appear when shared on Facebook, X (formerly Twitter), LINE, and other platforms — specifically the preview image, title, and description.

Social sharing is a meaningful traffic source even for B2B company sites. Without OG tags, a shared link looks bare — just a plain URL — and click-through rates suffer accordingly. A compelling image and headline, on the other hand, make your content stand out in a feed.

The Metadata API handles OG tag configuration per page. And with a file called opengraph-image.tsx, you can even generate OG images programmatically — for instance, automatically rendering each blog post's title onto a branded image. This is one of the more effective tactics for improving visibility on social platforms.

Pairing Metadata with Structured Data (JSON-LD)

Alongside metadata configuration, it's worth considering structured data (JSON-LD). Structured data gives search engines a machine-readable description of your page's content in a standardized format.

For example, adding "Organization" structured data to your company page can make your name, logo, and location eligible to appear as enriched information in Google search results. Adding "FAQPage" structured data to a FAQ page can make your Q&As appear directly in search results as rich results.

In Next.js, you can embed <script type="application/ld+json"> tags directly inside Server Components, making structured data easy to implement. Combining the Metadata API with structured data gives search engines a clear, accurate picture of what each page is about and what information it contains. It's unglamorous work, but it builds a solid foundation for sustainable organic growth.

Reduce Bounce Rates with Image Optimization

Next.js ships with a built-in image optimization component (next/image) that automatically compresses images and serves them at the right size for each device. While it varies by context, sites with slow-loading images tend to see higher bounce rates.

The setup isn't complicated, so if you haven't adopted this yet, I'd put it near the top of your priority list — especially if a significant share of your traffic comes from mobile devices.

What next/image Actually Does Under the Hood

Here's a closer look at the four optimizations next/image applies automatically:

Automatic format conversion: If the browser supports it, images are converted to next-generation formats like WebP or AVIF. Compared to JPEG, these formats can achieve the same visual quality at 30–50% smaller file sizes, with no extra work for the developer.

Responsive resizing: Even if your source image is 3000×2000px, next/image generates and serves a version sized appropriately for the user's display. No more sending a massive desktop image to a small phone screen.

Lazy loading: Images are loaded just before they come into the viewport. Images below the fold won't load until the user scrolls close to them, dramatically reducing the data needed for the initial page render.

Layout shift prevention: Space is reserved for each image before it finishes loading, preventing the jarring "content jump" effect known as CLS (Cumulative Layout Shift).

Implementation Gotchas to Watch For

next/image is powerful, but there are a few things that trip people up the first time around. Here are the ones I've stumbled on personally.

First, width and height are required in most cases. These values tell the component the image's aspect ratio upfront, which is how it prevents layout shifts. If you're working with dynamically sourced images, use the fill prop instead to have the image fill its parent container.

Second, for images hosted on external domains, you need to add those domains to images.remotePatterns in next.config.js. Skipping this produces a cryptic error that's easy to waste time debugging.

Finally, for images in the initial viewport — your hero image, main visual — always add the priority prop. This disables lazy loading for that image so it loads in parallel with the page itself. For anything the user sees immediately on arrival, prioritizing load speed is the right call.

Impact on Core Web Vitals

The effect of image optimization can be measured concretely using Core Web Vitals, Google's set of user experience metrics. Two metrics are particularly affected:

LCP (Largest Contentful Paint): The time it takes for the largest piece of content in the viewport to render. On most pages, that's the hero image. next/image optimization combined with the priority prop directly improves this number.

CLS (Cumulative Layout Shift): A measure of how much the layout shifts unexpectedly during loading. Explicit width/height values and the placeholder feature bring image-related CLS close to zero.

Core Web Vitals have been a Google ranking factor since 2021. The exact degree of their influence on rankings is debated, but there's no question that they reflect real user experience quality. Image optimization is one of the highest-leverage, lowest-effort ways to move these numbers in the right direction.

Measure Performance and Keep Improving

I've covered five best practices, but implementing them and moving on is leaving value on the table — that's been my honest experience. To maximize the impact of these changes, you need a cycle of measurement and iteration.

Regular Audits with Lighthouse

Lighthouse, a tool from Google, automatically scores your pages on performance, accessibility, SEO, and more. It runs right inside Chrome DevTools and provides specific, actionable recommendations alongside each score.

Making a habit of running Lighthouse even once a month helps you catch performance regressions before they become serious. Good moments to run it: when you add a new page, swap out a large image, or embed a third-party script. Catching problems early keeps them small.

Next.js Built-In Analytics

The @next/bundle-analyzer package gives you a visual breakdown of your JavaScript bundle — which libraries are taking up how much space. This makes it easy to identify bloated dependencies and make informed decisions about code splitting or library removal.

In many cases, sticking to built-in Next.js utilities like next/headers and next/navigation can replace third-party libraries entirely. Fewer dependencies means a smaller bundle, fewer security vulnerabilities, and less time spent on updates.

Wrapping Up

All five practices I've covered share a common goal: balancing site performance with developer experience. You don't need to adopt everything at once — picking one or two to start with and building from there is a perfectly reasonable approach.

Here's a quick recap:

  1. Make App Router your default architecture — Use App Router for all new projects. Existing sites can migrate incrementally.
  2. Speed up pages with Server Components — Design with "server first, client only where necessary" as your guiding principle.
  3. Simplify form handling with Server Actions — Cut the overhead of building a separate API layer and keep your code readable.
  4. Lock down SEO with the Metadata API — Pair it with OG tags and structured data to optimize for both search engines and social platforms.
  5. Reduce bounce rates with image optimization — The built-in next/image component alone can make a substantial dent in your Core Web Vitals scores.

Above all, keep measuring and improving after you ship. Technology will keep evolving, but the goal stays the same: delivering a great experience to every user who visits your site.

If you'd like help applying any of these practices to your own site, or have questions about your tech stack in general, feel free to reach out via aduce's contact page. We're happy to support you through everything from scoping the problem to hands-on implementation.