NextJS
Get Mobile Device Server Side

How to Detect Mobile Devices Server-Side in Next.js for Optimized Rendering

When building responsive web applications, you often need to make layout adjustments based on whether the user is on a mobile or desktop device. While CSS media queries handle most styling needs, sometimes you need server-side device detection to:

  • Load different quantities of data
  • Optimize first-fold loading, achieving better LCP (Largest Contentful Paint) scores as part of Core Web Vitals
  • Implement device-specific features or interfaces
  • Improve performance by sending only what's needed, boosting page speed
  • Initial load for Server-Side Device Detection

Here's the code that I am using for my server components:

import { headers } from "next/headers";
import UAParser from "ua-parser-js";
 
type IDevice = "mobile" | "desktop";
 
export default async function getDevice( // prefix with `get` since you can onle use in server component
  device: IDevice = "mobile" /*default mobile*/
): Promise<boolean> {
  const headersList = await headers(); // await mandatory for nextjs 15
  const userAgent = headersList.get("user-agent") || ""; //Get request headers
  const deviceType = new UAParser(userAgent).getDevice().type || "desktop"; // Parse to string
  return deviceType === device; // return true or false
}

Example of use

/page.tsx
export default async function SomeNextPage() {
  const isMobile = await getDevice(); // Don't forget the "async await" or will launch error
 
  const quantity = isMobile ? 4 : 12; // Will load different quantities according to device
  const response = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=" + limitItems);
  const posts = await response.json();
 
  return (
    <div>
      {posts.map((post) => (
        <article key={post.id} className="post">
          <h2>{post.title}</h2>
          <p>{post.body}</p>
          {isMobile ? (
            <div className="mobile-only">
              <button>Read More</button>
              <small>Tap for full content</small>
            </div>
          ) : (
            <div className="desktop-only">
              <button>View Details</button>
              <button>Save for Later</button>
              <button>Share</button>
            </div>
          )}
        </article>
      ))}
    </div>
  );
}
Last updated on