You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js的getStaticProps中获取User Agent实现SSG页面设备检测

问题根因

getStaticProps 是 NextJS 的构建阶段执行方法,仅在项目打包时运行一次,生成的静态页面会被所有访问用户复用。此时 react-device-detect 读取的是构建服务器的 User Agent,而非访问用户的浏览器 UA,因此会一直返回固定的桌面端判断结果。
且 getStaticProps 的设计定位就是无请求上下文的静态生成,本身不会提供用户请求的 req 参数,因此不可能在纯 SSG 的 getStaticProps 中获取单个用户的 UA。

方案1:客户端侧判断(保留纯 SSG,最轻量)

如果不需要首屏渲染时就返回对应设备的内容,直接在客户端侧做判断即可,为避免 hydration 不匹配问题,建议在组件挂载后再赋值设备判断结果:

import { useState, useEffect } from 'react';
import { isMobile } from 'react-device-detect';

function AwesomePage() {
  const [deviceType, setDeviceType] = useState('');

  // 仅在客户端挂载后执行判断,避免服务端预渲染与客户端内容不一致
  useEffect(() => {
    setDeviceType(isMobile ? 'Yes, I am a mobile' : 'Nope, Desktop!');
  }, []);

  return <h1>{deviceType}</h1>
}

export default AwesomePage;

方案2:改用 SSR 渲染(首屏直接返回正确设备内容)

如果需要首屏就返回适配设备的内容,可将渲染模式换成 SSR,使用 getServerSideProps 可以拿到请求上下文的 req 对象,手动传入 UA 给 react-device-detect 做判断:

import { getSelectorsByUserAgent } from 'react-device-detect';

export async function getServerSideProps(context) {
  // 从请求头获取用户真实UA
  const userAgent = context.req.headers['user-agent'] || '';
  // 手动传入UA生成设备判断结果
  const { isMobile } = getSelectorsByUserAgent(userAgent);
  const deviceType = isMobile ? 'Yes, I am a mobile' : 'Nope, Desktop!';

  return {
    props: {
      mobileDevice: deviceType
    }
  }
}

function AwesomePage({ mobileDevice }) {
  return <h1>{mobileDevice}</h1>
}

export default AwesomePage;

方案3:Middleware + 多版本 SSG 预渲染(兼顾静态页速度与设备适配)

如果既想保留 SSG 的静态响应速度,又需要首屏返回对应设备的内容,可以配合 NextJS 的 Middleware 实现:

  1. 构建时预渲染移动端、桌面端两个版本的静态页
  2. 中间件拦截用户请求,根据 UA 自动分发对应版本的静态页

首先在项目根目录新增 middleware.js:

import { NextResponse } from 'next/server';
import { getSelectorsByUserAgent } from 'react-device-detect';

export function middleware(request) {
  const userAgent = request.headers.get('user-agent') || '';
  const { isMobile } = getSelectorsByUserAgent(userAgent);
  const response = NextResponse.next();
  // 也可以根据UA直接重写到对应路径,实现多版本静态页分发
  response.headers.set('X-Device-Type', isMobile ? 'mobile' : 'desktop');
  return response;
}

// 配置中间件生效的页面路径
export const config = {
  matcher: '/awesome-page',
}

之后可以通过 generateStaticParams(NextJS 13+ App Router)或 getStaticPaths(Pages Router)预生成两个设备版本的静态页即可。


内容的提问来源于stack exchange,提问作者Deepak Kamat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:03:03