tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
78.54k stars 2.33k forks source link

[bug] ReferenceError: window is not defined #5982

Closed The-True-Hooha closed 1 year ago

The-True-Hooha commented 1 year ago

Describe the bug

Running tauri with next.js and I get this error ReferenceError: window is not defined after importing import { appWindow } from '@tauri-apps/api/window';.

Behavior does not change even after commenting out the { appWindow } import statement

Reproduction

No response

Expected behavior

No response

Platform and versions

OS: windows "next": "13.0.6", tauri = { version = "1.2.2" }

Stack trace

No response

Additional context

No response

FabianLars commented 1 year ago

This is one of the drawbacks of SSR-first frameworks like nextjs in tauri-land. Generally there are 2 cases where this error can come up

If this does not help you please show us the code where the problem occurs.

The-True-Hooha commented 1 year ago

Thank you, you fixed actually..

But then, decided to move the project to react

Hecsall commented 1 year ago

Sorry to revive this issue, but I recently encountered the same error using Next.js and after a bit of research, I think I found a workaround. Maybe this will help future users.

Reading through Next.js documentation, there is a section discussing the import of External libraries with dynamic import.

In the example below here's what I did:

// components/windowTitlebar.js

import { useEffect, useState } from 'react'

export function WindowTitlebar() {
  const [appWindow, setAppWindow] = useState()

  // Import appWindow and save it inside the state for later usage
  async function setupAppWindow() {
    const appWindow = (await import('@tauri-apps/api/window')).appWindow
    setAppWindow(appWindow)
  }

  useEffect(() => {
    setupAppWindow()
  }, []) 

  // These 3 functions will see the "appWindow" stored inside the state
  function windowMinimize() {
    appWindow?.minimize()
  }
  function windowToggleMaximize() {
    appWindow?.toggleMaximize()
  }
  function windowClose() {
    appWindow?.close()
  }

  // Use "onClick" on buttons and call the 3 functions above
  return (
    <>
      <div data-tauri-drag-region>
        <button onClick={windowMinimize}>min</button>

        <button onClick={windowToggleMaximize}>max</button>

        <button onClick={windowClose}>close</button>
      </div>
    </>
  )
}

Then you use this component like this:

// pages/_app.js
...
import { WindowTitlebar } from '/components/windowTitlebar'

export default function App({ Component, pageProps }) {
  return (
    <>
      <WindowTitlebar />
      <Component {...pageProps} />
    </>
  )
}

Also don't forget to set the allowList for window inside tauri.conf.json

// src-tauri/tauri.conf.json

{
  ...
  "tauri": {
    "allowlist": {
      ...
      "window": {
        "all": true
      }
    },
    "windows": [
      {
        ...
        "decorations": false
      }
    ]
  }
}

I'm still not 100% sure this is the best way to get around this issue, but at least it seems to work.

sujan-s commented 5 months ago

@Hecsall You, Sir, are a lifesaver.

JRS296 commented 5 months ago
"use client";
import { WebviewWindow, appWindow } from "@tauri-apps/api/window"

export default function TitleBar() {
    const [appWindow, setAppWindow] = useState<WebviewWindow>()

    async function setupAppWindow() {
        const appWindow = (await import('@tauri-apps/api/window')).appWindow
        setAppWindow(appWindow)
    }

    useEffect(() => {
        setupAppWindow()
    }, [])

    function windowMinimize() {
        appWindow?.minimize()
    }
    function windowToggleMaximize() {
        appWindow?.toggleMaximize()
    }
    function windowClose() {
        appWindow?.close()
    }
    return (
       ...
    );
}

In case you're using TypeScript, don't forget to add the useState type, had a bit of trouble there myself.

artthurz commented 3 months ago

Thank you @Hecsall!

ompateldeveloper commented 2 weeks ago

@Hecsall Thanks man, you saved me