T
TanStack2w ago
harsh-harlequin

Setting status-code from loader

Has anyone found a good way to set the response status code from a loader during SSR? setResponseStatus does nothing. I need to set the status code to 404, but without throwing an error in the loader. Ideally, I would like to render the page as usual using the loader's result, but use the status code to signal indexers, etc., that the site is "expired". Alternative approaches: 1. Throw the result of notFound() and fetch the data from the API on the client (outside of the loader). 2. Using middlewares somehow propagating status code through headers and similar, and map the response object.... 3. ???
1 Reply
harsh-harlequin
harsh-harlequinOP7d ago
After having spend some debugging, this solution seem to work. We can't use setResponseStatus directly because it isn't honoured by h3.
import { createFileRoute } from '@tanstack/react-router';
import { createIsomorphicFn } from '@tanstack/react-start';
import {
getResponseStatus,
setResponseStatus,
} from '@tanstack/react-start/server';
import { FastResponse } from 'srvx';

const isStatusCode404 = createIsomorphicFn().server(() => {
return getResponseStatus() === 404;
});
const setStatusCode404 = createIsomorphicFn().server(() => {
setResponseStatus(404);
});

export const Route = createFileRoute('/details/{id}')({
server: {
handlers: {
GET: async ({ next }) => {
// @ts-expect-error - response is not typed
const { response, ...rest } = await next();
if (isStatusCode404()) {
return {
...rest,
response: new FastResponse(response.body, {
status: 404,
headers: response.headers,
}),
};
}
return {
...rest,
response: response,
};
},
},
},
loader: async ({ params, context, deps }) => {
...
if (shouldSet404) {
setStatusCode404();
}
return loadedData;
},
...
});
import { createFileRoute } from '@tanstack/react-router';
import { createIsomorphicFn } from '@tanstack/react-start';
import {
getResponseStatus,
setResponseStatus,
} from '@tanstack/react-start/server';
import { FastResponse } from 'srvx';

const isStatusCode404 = createIsomorphicFn().server(() => {
return getResponseStatus() === 404;
});
const setStatusCode404 = createIsomorphicFn().server(() => {
setResponseStatus(404);
});

export const Route = createFileRoute('/details/{id}')({
server: {
handlers: {
GET: async ({ next }) => {
// @ts-expect-error - response is not typed
const { response, ...rest } = await next();
if (isStatusCode404()) {
return {
...rest,
response: new FastResponse(response.body, {
status: 404,
headers: response.headers,
}),
};
}
return {
...rest,
response: response,
};
},
},
},
loader: async ({ params, context, deps }) => {
...
if (shouldSet404) {
setStatusCode404();
}
return loadedData;
},
...
});

Did you find this page helpful?