[Feature]: Return arbitrary Response object directly from loader #1880
Replies: 8 comments 6 replies
-
You can 100% return a new Response object with any status code and body from a loader. If the route has a default export the data will be JSON.parse-d so your data should be compatible with that, for example don’t return a Buffer. Also the json helper function can receive a status code or ResponseInit as second argument and there you can make the response created by it to be an unauthorized response. |
Beta Was this translation helpful? Give feedback.
-
Hi @sergiodxa - thanks for your help! Our route has a default export and we want to return an HTML response directly from the loader under certain conditions. We haven't been able to make this work - perhaps because of the JSON.parse restriction you mention? If the capability already exists we'd love to use it! Here's failing loader: export const loader: LoaderFunction = async () => {
return new Response("<!DOCTYPE html><html><body>Test</body></html>", {
status: 401,
});
}; The error we receive is somewhat cryptic (it results in a 500 in the browser):
|
Beta Was this translation helpful? Give feedback.
-
@colinclerk if the route has a default export the data of the loader is used to supply data for that route component, instead of sending html, send data and render that html directly in the component of the route. Another option is to don’t have a default export so the route becomes a Resource Route. |
Beta Was this translation helpful? Give feedback.
-
Yes, this is where we're stuck. We're building an SDK and don't want to ask the developer to modify both their default export and their loader. We'd like to be able to return arbitrary Response objects from the loader, just like we can return redirect For context, we're able to do this from
|
Beta Was this translation helpful? Give feedback.
-
For anyone who came here through the PR - in the comments above I was originally confused about the behavior of the |
Beta Was this translation helpful? Give feedback.
-
This is interesting though I'm not convinced yet 😅. Loaders are designed for route components, not just arbitrary responses (resource routes can have arbitrary responses though). You have to consider both document requests as well as script transitions where multiple fetches are in flight to be aggregated into the next page in the browser. I would give developers a component to render in their catch boundary for the 401 case. |
Beta Was this translation helpful? Give feedback.
-
I thought I need this feature to create graphql from remix-app-server with graphql-helix The last step: I don't know how to send grapqhl response... Can someone help? Thanks! |
Beta Was this translation helpful? Give feedback.
-
I'm running into another use case for this right now. I'm implementing a system on my site to block specific clients. The logic for determining whether to block a given request works fine, but I want to return a new Response('You are not allowed to access this site', {
status: 403,
}); The 403 status seems to translate correctly when throwing that response from the loader, but the actual response body is HTML with "403" as text and a lot of CSS and JS that I don't want to be sending. Essentially I want the response to work the way that returning this from a resource route would work, but the existence of a default component seems to break it. Any ideas? |
Beta Was this translation helpful? Give feedback.
-
What is the new or updated feature that you are suggesting?
We would like to return an arbitrary Response object directly from a loader.
Why should this feature be included?
Our use case is that we're building an authentication library and we have special handling for the 401 Unauthorized case. We'd like to provide our handling directly through the loader, instead of asking developers to also modify the CatchBoundary.
Beyond our use case, it was a little confusing to learn that
redirect()
orResponses can be returned directly from a loader, but arbitrary Response objects cannot. We'd love a convention like returned Response objects are passed directly to the browser, while thrown Response objects go through the CatchBoundary.json()
Beta Was this translation helpful? Give feedback.
All reactions