Json 👺
Json 👺7mo ago

Dynamically generate url for httpBatchLink

Hey there 👋 is it possible to generate a url for httpBatchLink instead of hardcoding one? I attempted the below code, but this doesn't work. Understandably, the fallback value is used for url each time the component mounts. I believe that I wouldn't even need a useEffect if I wasn't using Next, as I could directly grab these values from window.location, but since I'm using SSR, this code doesn't make it through the SSR pass.
"use client";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink } from "@trpc/client";
import { useEffect, useState } from "react";
import { trpc } from "@/utils/trpc";
import SuperJSON from "superjson";

export function TRPCQueryClientProvider({
children,
}: {
children: React.ReactNode;
}) {
const [url, setUrl] = useState<string | null>(null);

useEffect(() => {
if (typeof window !== "undefined") {
const { hostname, protocol, port } = window.location;
setUrl(`${protocol}//${hostname}:${port}/api/trpc`);
}
}, []);

const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: url ?? "http://localhost:3000/api/trpc", // Fallback in case url is not ready,
// url: "http://192.168.0.16:3000/api/trpc", // For mobile device testing
transformer: SuperJSON,
}),
],
}),
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</trpc.Provider>
);
}
"use client";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { httpBatchLink } from "@trpc/client";
import { useEffect, useState } from "react";
import { trpc } from "@/utils/trpc";
import SuperJSON from "superjson";

export function TRPCQueryClientProvider({
children,
}: {
children: React.ReactNode;
}) {
const [url, setUrl] = useState<string | null>(null);

useEffect(() => {
if (typeof window !== "undefined") {
const { hostname, protocol, port } = window.location;
setUrl(`${protocol}//${hostname}:${port}/api/trpc`);
}
}, []);

const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: url ?? "http://localhost:3000/api/trpc", // Fallback in case url is not ready,
// url: "http://192.168.0.16:3000/api/trpc", // For mobile device testing
transformer: SuperJSON,
}),
],
}),
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</trpc.Provider>
);
}
1 Reply
Json 👺
Json 👺OP7mo ago
Currently, this seems to work, however if it's likely that the fallback value would ever be used here as opposed to the return of getUrl()
const getUrl = () => {
if (typeof window !== "undefined") {
const { hostname, protocol, port } = window.location;
const url = `${protocol}//${hostname}:${port}/api/trpc`;
return url;
}
return undefined;
};

const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: getUrl() ?? "http://localhost:3000/api/trpc",
// url: "http://192.168.0.16:3000/api/trpc", // For mobile device testing
// You can pass any HTTP headers you wish here
// async headers() {
// return {};
// },
transformer: SuperJSON,
}),
],
}),
);
const getUrl = () => {
if (typeof window !== "undefined") {
const { hostname, protocol, port } = window.location;
const url = `${protocol}//${hostname}:${port}/api/trpc`;
return url;
}
return undefined;
};

const [queryClient] = useState(() => new QueryClient());
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
httpBatchLink({
url: getUrl() ?? "http://localhost:3000/api/trpc",
// url: "http://192.168.0.16:3000/api/trpc", // For mobile device testing
// You can pass any HTTP headers you wish here
// async headers() {
// return {};
// },
transformer: SuperJSON,
}),
],
}),
);

Did you find this page helpful?