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

在Next.js中集成@mapbox/search-js-react遇document未定义错误

解决Next.js集成@mapbox/search-js-react时的document is not defined错误

核心问题

@mapbox/search-js-web依赖浏览器环境的document对象,但你的页面使用getServerSideProps进行服务端渲染(SSR),服务端环境中不存在document,导致组件初始化时抛出错误。

解决方案

使用Next.js的dynamic导入功能,禁用该组件的服务端渲染,让它仅在客户端环境加载:

1. 修改组件导入方式

替换原来的静态导入为动态导入:

import dynamic from 'next/dynamic';

// 动态导入AddressAutofill,禁用SSR
const AddressAutofill = dynamic(
  () => import('@mapbox/search-js-react').then((mod) => mod.AddressAutofill),
  { ssr: false }
);

2. 修复signOut的副作用执行

原代码中直接在组件渲染阶段调用signOut()不符合React规范,会引发不必要的重渲染,改用useEffect处理副作用:

useEffect(() => {
  if (signOOut) {
    signOut();
  }
}, [signOOut]);

修改后的完整代码

import { getSession, signOut } from 'next-auth/react';
import { useState, useEffect } from 'react';
import dynamic from 'next/dynamic';
import Dashboard from '../../../components/layout/dashboard';
import { Container, Button, Table } from 'react-bootstrap';

// 动态导入AddressAutofill,禁用SSR
const AddressAutofill = dynamic(
  () => import('@mapbox/search-js-react').then((mod) => mod.AddressAutofill),
  { ssr: false }
);

export default function Details({ signOOut }) {
  useEffect(() => {
    if (signOOut) {
      signOut();
    }
  }, [signOOut]);

  return (
    <form>
      <AddressAutofill accessToken='pk.eyJw'>
        <input
          name='address'
          placeholder='Address'
          type='text'
          autoComplete='address-line1'
        />
      </AddressAutofill>
      <input
        name='apartment'
        placeholder='Apartment number'
        type='text'
        autoComplete='address-line2'
      />
      <input
        name='city'
        placeholder='City'
        type='text'
        autoComplete='address-level2'
      />
      <input
        name='state'
        placeholder='State'
        type='text'
        autoComplete='address-level1'
      />
      <input
        name='country'
        placeholder='Country'
        type='text'
        autoComplete='country'
      />
      <input
        name='postcode'
        placeholder='Postcode'
        type='text'
        autoComplete='postal-code'
      />
    </form>
  );
}

export async function getServerSideProps(ctx) {
  const Gsession = await getSession(ctx);

  var signo = false;
  console.log('Checking Session are : ' + JSON.stringify(Gsession));
  if (Gsession) {
    if (Gsession.error == 555) {
      signo = true;
    }
  }

  return {
    props: {
      sessions: Gsession,
      signOOut: signo,
    },
  };
}

Details.auth = true;

Details.getLayout = function getLayout(page) {
  return <Dashboard>{page}</Dashboard>;
};

补充说明

动态导入禁用SSR后,组件会在客户端hydrate完成后再加载,彻底避免了服务端访问document的问题。同时调整signOut的执行时机,符合React副作用处理的规范,避免渲染阶段的异常。

内容的提问来源于stack exchange,提问作者RUSSELL HARROWER

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:36:14