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

Tauri + Next.js 首次加载报window未定义,无法创建新窗口

解决Tauri + Next.js 创建新窗口时首次加载失败的问题

问题根源

Next.js 默认启用服务端渲染(SSR),在服务端编译阶段不存在 window 对象,但 Tauri 的 WebviewWindow API 依赖浏览器环境的 window 对象,因此首次编译时会抛出 ReferenceError: window is not defined 错误。而注释后取消注释能正常运行,是因为此时处于客户端热更新阶段,代码已在浏览器环境中执行,window 对象存在。

解决思路

1. 动态导入 Tauri Window API

将 WebviewWindow 的导入放在函数内部,仅在客户端执行时才加载该模块,避免服务端编译时触发错误:

const openWindow = async (e) => {
  const table = JSON.stringify({
    host: active.host,
    port: active.port,
    user: active.user,
    password: active.password,
    database: e,
  });
  try {
    // 动态导入WebviewWindow,仅在客户端环境加载
    const { WebviewWindow } = await import('@tauri-apps/api/window');
    await new WebviewWindow("test", {
      url: "/database?data=" + table,
    });
  } catch (e) {
    console.log("error", e);
  }
};

2. 显式判断客户端环境

在执行 Tauri 相关代码前,先检查是否处于浏览器环境,确保服务端直接跳过这段逻辑:

const openWindow = async (e) => {
  // 服务端环境直接返回,避免执行依赖window的代码
  if (typeof window === 'undefined') return;

  const table = JSON.stringify({
    host: active.host,
    port: active.port,
    user: active.user,
    password: active.password,
    database: e,
  });
  try {
    const { WebviewWindow } = await import('@tauri-apps/api/window');
    await new WebviewWindow("test", {
      url: "/database?data=" + table,
    });
  } catch (e) {
    console.log("error", e);
  }
};

3. 针对 Next.js 13+ App Router:标记组件为客户端组件

如果使用 Next.js 13+ 的 App Router,需要在包含 openWindow 函数的组件顶部添加 'use client' 指令,强制该组件在客户端渲染:

'use client'; // 必须放在组件最顶部

import { useState } from 'react';
// 其他导入...

const YourComponent = () => {
  // 组件逻辑和openWindow函数...
};

export default YourComponent;

4. 针对 Pages Router:使用动态导入禁用 SSR

如果使用 Pages Router,可以将包含按钮和 openWindow 逻辑的部分抽成单独组件,然后用 dynamic 导入并禁用 SSR:

// 父组件中
import dynamic from 'next/dynamic';

// 禁用SSR,组件仅在客户端渲染
const DatabaseTable = dynamic(() => import('./DatabaseTable'), { ssr: false });

const ParentComponent = () => {
  return (
    <div>
      {loading === false ? <DatabaseTable databases={databases} /> : null}
    </div>
  );
};

然后在 DatabaseTable 组件中实现按钮和 openWindow 逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:37:45