Root loader not being called in CatchBoundary #5186
Replies: 10 comments 2 replies
-
Depending on if this is a document request or a data request, Remix will work slightly different. If you're navigating to a non-existent route on a document request (full page), Remix throws the new Response(404) before it runs any loaders, so However if you've already rendered the initial document and making a client-side navigation to a non-existent route, Remix will still throw the 404 response, but this time, You can verify this behavior by typing in the URL http://localhost:3000/not-found. It should not have root data. Add a link in your route to I'm pretty sure this is by design. So I would not rely on that data being present in the catch boundary, since that's typically used to indicate some type of error. |
Beta Was this translation helpful? Give feedback.
-
This bug/feature has been since the beginning; in practice, for example, it means our 404 pages can't show the correct theme. It would be nice if loaders were called in catch boundaries. |
Beta Was this translation helpful? Give feedback.
-
The only time you won't get root data is if the error/catch boundary is hit on a full document request. My recommendation is to handle this case in the export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
if (responseStatusCode === 404) {
// fetch theme from (cookie?, host?)
// render page with catch boundary
const markup = renderToString(...)
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
});
} |
Beta Was this translation helpful? Give feedback.
-
@kiliman yeah, as I see it, it is like that by design. The funny thing is that the root loader doesn't get called only when a
@revelt have you found any workaround? maybe doing something in
@kiliman how would you recommend me to get the domain and pass it down to be available to put on my metatags? Is there a way to modify that |
Beta Was this translation helpful? Give feedback.
-
The problem is that the loader thrown the response that caused the CatchBoundary to render, that means you can't get the full response of the loader because your loader already run and thrown a response earlier. What you can do is to add the theme or any other data you need to the body of the thrown response. |
Beta Was this translation helpful? Give feedback.
-
@sergiodxa how would you recommend me to pass down the domain name to the 404 page? Maybe doing something in |
Beta Was this translation helpful? Give feedback.
-
@elkevinwolf that would be a way, your entry.server could define a context provider with the domain name and then you can access it, and in entry.client you can do the same reading from Another way is to read the domain name and pass it as the data of the thrown response export function loader({ request }: LoaderArgs) {
let hostname = getHostname(request.url)
throw json({ hostname }, 404)
} With this, your CatchBoundary will have access to hostname in useCatch |
Beta Was this translation helpful? Give feedback.
-
Good idea of wrapping with a context. Regarding the |
Beta Was this translation helpful? Give feedback.
-
Update: I managed to hack around this by adding a Splat Route throwing a 404 error status code.
import { notFound } from "remix-utils"
export function loader() {
throw notFound(null)
}
export default function NotFound() {
return null
} |
Beta Was this translation helpful? Give feedback.
-
Converting this to a discussion as I'm cleaning up the issues. If this is a request for a new feature, please post a Proposal in the discussions tabs. |
Beta Was this translation helpful? Give feedback.
-
What version of Remix are you using?
1.6.4
Steps to Reproduce
CatchBoundary
.Expected Behavior
This should be logged to the console (taken from an existing route).
Actual Behavior
This was logged to the console (taken from a non-existing route).
Beta Was this translation helpful? Give feedback.
All reactions