heyitsiveen
heyitsiveen7mo ago

Error: Switched to client rendering because the server rendering errored: UNAUTHORIZED

What could be the possible reason for this error? This is how my NextJS structure looks when using tRPC. - /app/settings/page.tsx
export const dynamic = 'force-dynamic'

export default function Settings() {
prefetch(trpc.categories.getMany.queryOptions())
return (
<HydrateClient>
<CategoriesView />
</HydrateClient
)
}
export const dynamic = 'force-dynamic'

export default function Settings() {
prefetch(trpc.categories.getMany.queryOptions())
return (
<HydrateClient>
<CategoriesView />
</HydrateClient
)
}
- /components/settings/view/categories-view.tesx
'use client'
export const CategoriesView = () => {
return <CategoriesSection />
}
'use client'
export const CategoriesView = () => {
return <CategoriesSection />
}
- /components/settings/section/categories-section.tsx
export const CategoriesSection = () => {
return (
<Suspense fallback={<p>Loading...</p>}
<ErrorBoundary fallback={<p>Error</p>}
<CategoriesSectionSuspense />
</ErrorBoundary>
</Suspense>
)
}

const CategoriesSectionSuspense = () => {
const trpc = useTRPC()
const { data } = useSuspenseQuery(trpc.categories.getMany.queryOptions())

return <CategoriesDataTable data={data} />
}
export const CategoriesSection = () => {
return (
<Suspense fallback={<p>Loading...</p>}
<ErrorBoundary fallback={<p>Error</p>}
<CategoriesSectionSuspense />
</ErrorBoundary>
</Suspense>
)
}

const CategoriesSectionSuspense = () => {
const trpc = useTRPC()
const { data } = useSuspenseQuery(trpc.categories.getMany.queryOptions())

return <CategoriesDataTable data={data} />
}
No description
16 Replies
BeBoRE
BeBoRE7mo ago
Cookies aren’t being properly passed on when fetching in SSR, still a restriction with useSuspenseQuery.
heyitsiveen
heyitsiveenOP7mo ago
when I tried to comment back the shouldDehydrateQuery I'm not getting that error, but the continuously sending a request is my problem when I'm not logged in and try to refresh the page, It will always sending a request on the api even I have a Suspense and ErrorBoundary, so on the network tab on chrome dev tools I have a thousands request
No description
BeBoRE
BeBoRE7mo ago
Yeah, you shouldn’t retry on server I use this to prevent retries on server render:
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 1000 * 1 * 30,
retry: (count, error) => {
const toAttempt = isServer ? 0 : 3;

if (!isTRPCClientError(error) || !error.data) {
return toAttempt < count;
}

if (error.data.httpStatus >= 400 && error.data.httpStatus < 500) {
return false;
}

return toAttempt < count;
},
},
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 1000 * 1 * 30,
retry: (count, error) => {
const toAttempt = isServer ? 0 : 3;

if (!isTRPCClientError(error) || !error.data) {
return toAttempt < count;
}

if (error.data.httpStatus >= 400 && error.data.httpStatus < 500) {
return false;
}

return toAttempt < count;
},
},
heyitsiveen
heyitsiveenOP7mo ago
so the shouldDehydrateQuery should be enabled? and I will only add this to prevent the continuously sending request?
heyitsiveen
heyitsiveenOP7mo ago
here's the sample of the error that I'm talking about continuously sending request
No description
heyitsiveen
heyitsiveenOP7mo ago
when the shouldDehydrateQuery is enabled even I have Suspense and ErrorBoundary
BeBoRE
BeBoRE7mo ago
You should leave the shouldDehydrateQuery as is Keep whatever the defaults were given by trpc
heyitsiveen
heyitsiveenOP7mo ago
Okay thank you, I will try your code. And actually, the guide I followed is this tRPG Tanstack React Query (Server Components).
BeBoRE
BeBoRE7mo ago
Yeah, they sometimes do not provide good defaults
heyitsiveen
heyitsiveenOP7mo ago
your code is missing the variable of isServer where I can get this
heyitsiveen
heyitsiveenOP7mo ago
No description
heyitsiveen
heyitsiveenOP7mo ago
can you provide the full code? @BeBoRE
BeBoRE
BeBoRE7mo ago
React query gives you this
export const isTRPCClientError = (
error: Error,
): error is TRPCClientError<AppRouter> => {
return error instanceof TRPCClientError;
};
export const isTRPCClientError = (
error: Error,
): error is TRPCClientError<AppRouter> => {
return error instanceof TRPCClientError;
};
import {
defaultShouldDehydrateQuery,
isServer,
QueryClient,
} from "@tanstack/react-query";
import {
defaultShouldDehydrateQuery,
isServer,
QueryClient,
} from "@tanstack/react-query";
heyitsiveen
heyitsiveenOP7mo ago
oohh I see, thank you, I'm new to trpc and react query, I just following the youtube clone by @CodeWithAntonio
Gabriel
Gabriel3w ago
I am still getting this issue! What was the solve for this? @heyitsiveen
nohaxito
nohaxito3w ago
I have the same
Error: Switched to client rendering because the server rendering errored: UNAUTHORIZED
Error: Switched to client rendering because the server rendering errored: UNAUTHORIZED
error, but in my case is because on the first page load (in nextjs) the headers and cookies are "undefined". I tried this code:
export const trpc = createTRPCOptionsProxy<AppRouter>({
queryClient: getQueryClient,
client: createTRPCClient({
links: [
httpBatchLink({
url: `${process.env.NEXT_PUBLIC_SERVER_URL}/trpc`,
async fetch(url, options) {
const headers = await nextHeaders();

return fetch(url, {
...options,
credentials: 'include',
headers: {
Cookie: headers.get('Authorization') || '',
},
} as RequestInit);
},
}),
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
],
}),
});
export const trpc = createTRPCOptionsProxy<AppRouter>({
queryClient: getQueryClient,
client: createTRPCClient({
links: [
httpBatchLink({
url: `${process.env.NEXT_PUBLIC_SERVER_URL}/trpc`,
async fetch(url, options) {
const headers = await nextHeaders();

return fetch(url, {
...options,
credentials: 'include',
headers: {
Cookie: headers.get('Authorization') || '',
},
} as RequestInit);
},
}),
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error),
}),
],
}),
});
but the same error, is there a way to await for the headers or something to avoid the error? (the stack for the backend is hono + better auth btw)
No description
No description

Did you find this page helpful?