tl;dr; Use data()
in your loader
function and make your headers
function pass it on to get headers be dependent on what's happening in the loader
function.
I recently rewrote the front end of this website from Remix to react-router
v7. A route is a page, which can be something like /about
or have a parameter in it like /blog/:slug
.
The way react-router
v7 (the "framework mode") works is that your route looks like this:
import type { Route } from "./+types/post"
export async function loader({ params }: Route.LoaderArgs) {
const post = await fetchPost(params.slug)
return { post }
}
export default function Component({loaderData}: Route.ComponentProps) {
return <h1>{loaderData.post.title}</h1>
}
So good for so far. But suppose you want this page to have a certain header, depending on the value of the post
object. To set headers, you have to add an exported function called, surprise surprise; headers
. For example:
export function headers() {
return {
"X-Stretchy-Pants": "it's for fun",
};
}
The headers
function is called with a Route.HeaderArgs
argument which is an object with the keys called loaderHeaders
, parentHeaders
, actionHeaders
, and errorHeaders
.
That loaderHeaders
refers back to the loader
function and what it returns. You don't get the { post }
thing that you returned in the loader
. To get custom headers you have to make this change:
+import { data } from "react-router"
import type { Route } from "./+types/post"
+export async function loader({ params }: Route.LoaderArgs) {
+ const post = await fetchPost(params.slug)
+ return data(
+ { post },
+ { headers: {joke: post.jokeOfTheDay }}
+ )
+}
+export function headers({ loaderHeaders }: Route.HeadersArgs) {
+ return {
+ "X-Daily-Joke": loaderHeaders.joke
+ };
+}
export default function Component({loaderData}: Route.ComponentProps) {
return <h1>{loaderData.post.title}</h1>
}
In Remix, which came before react-router
v7, you did not have to do this. It was enough to do:
import { json } from "@remix-run/node"
export async function loader({ params }: LoaderFunctionArgs) {
// ...
return json(
{ post },
{
headers: {
"X-Daily-Joke": post.jokeOfTheDay
}
},
)
}
Comments