#How to avoid "window is not defined" - NextJS + rspc + Tauri

12 messages · Page 1 of 1 (latest)

frosty raft
#

Hi there! I'm running into a really strange error when using the Tauri integration for RSPC. The following code returns "ReferenceError: window is not defined". I think this is because TauriTransport must be using window somehow.

How do I import TauriTransport for when I'm exclusively client-side? Is there a workaround I'm missing here?

import { FetchTransport, createClient } from "@rspc/client";
import { createReactQueryHooks } from "@rspc/react";
import { QueryClient } from "@tanstack/react-query";
import { TauriTransport } from "@rspc/tauri";

import type { Procedures } from "../../src/bindings";

export const client = createClient<Procedures>({
    transport:
        typeof window === "undefined" ?
            // HYPOTHESIS TauriTransport cannot even be imported since it uses the window api
            new FetchTransport("http://localhost:9000/rspc") :
            new TauriTransport();
});

export const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            retry: false, // If you want to retry when requests fail, remove this.
        },
    },
});

export const {
    useContext,
    useMutation,
    useQuery,
    useSubscription,
    Provider: RSPCProvider,
} = createReactQueryHooks<Procedures>();
surreal kestrel
#

the rspc package imports the appWindow var from the tauri api and if you do that yourself that means in nextjs context to be forced to use dynamic imports (the await import() syntax). ig this also applies here

frosty raft
#

Could you say more about the await import() syntax? I'm not sure how to do that here without assigning transport as a Promise

#

I was gonna do

export const client = createClient<Procedures>({
  transport:
    typeof window === "undefined" ?
        new FetchTransport("http://localhost:9000/rspc") :
        // HYPOTHESIS TauriTransport cannot be used server-side, so this should fix
        import("@rspc/tauri").then(({ TauriTransport }) => {
            return new TauriTransport();
        }).catch((err) => {
            return new FetchTransport("http://localhost:9000/rspc");
        })
});

But this will fail because I can't force the promise to resolve. How would you rewrite this whole .ts file to dynamically import?

surreal kestrel
#

honestly no idea

#

once you use one promise you "infect" everything with it but i can't think of something that would make it fit into your code here 🤔

#

well, unless you're okay with not exporting the client itself but a promise that resolves to a client. that may make it possible 🤔

frosty raft
#

Shoot. Only work-around I can think of is just using WebsocketTransport("http://localhost:9000/rspc") in the client-side case. This is a very in-the-weeds rspc question, but do you know how to expose a websocket server for rspc on the Tauri server-side ? Their documentation doesn't give good answers for how to do this with Tauri + React. For example, here's how they do it with Axum (https://github.com/oscartbeaumont/rspc/blob/main/examples/src/bin/axum.rs)

  let addr = "[::]:4000".parse::<std::net::SocketAddr>().unwrap(); // This listens on IPv6 and IPv4
  println!("listening on http://{}/rspc/version", addr);
  axum::Server::bind(&addr)
      .serve(app.into_make_service())
      .await
      .unwrap();
GitHub

A blazingly fast and easy to use TRPC-like server for Rust. - rspc/examples/src/bin/axum.rs at main · oscartbeaumont/rspc

#

well, unless you're okay with not exporting the client itself but a promise that resolves to a client. that may make it possible 🤔
Experimenting with this! We'll see if it makes the app feel way slower hah

surreal kestrel
frosty raft
#

Oh wow that’s a good idea. trying it!

frosty raft
#

This solved it!! Thank you so much for the help here @surreal kestrel ! Great general advice too. When in doubt, fork it and fix it!