---
title: Resource Routes
---
# Resource Routes
[MODES: framework, data]
When server rendering, routes can serve "resources" instead of rendering components, like images, PDFs, JSON payloads, webhooks, etc.
## Defining a Resource Route
A route becomes a resource route by convention when its module exports a loader or action but does not export a default component.
Consider a route that serves a PDF instead of UI:
```ts
route("/reports/pdf/:id", "pdf-report.ts");
```
```tsx filename=pdf-report.ts
import type { Route } from "./+types/pdf-report";
export async function loader({ params }: Route.LoaderArgs) {
const report = await getReport(params.id);
const pdf = await generateReportPDF(report);
return new Response(pdf, {
status: 200,
headers: {
"Content-Type": "application/pdf",
},
});
}
```
Note there is no default export. That makes this route a resource route.
## Linking to Resource Routes
When linking to resource routes, use `` or ``, otherwise React Router will attempt to use client side routing and fetching the payload (you'll get a helpful error message if you make this mistake).
```tsx
View as PDF
```
## Handling different request methods
GET requests are handled by the `loader`, while POST, PUT, PATCH, and DELETE are handled by the `action`:
```tsx
import type { Route } from "./+types/resource";
export function loader(_: Route.LoaderArgs) {
return Response.json({ message: "I handle GET" });
}
export function action(_: Route.ActionArgs) {
return Response.json({
message: "I handle everything else",
});
}
```
## Return Types
Resource Routes are flexible when it comes to the return type - you can return [`Response`][Response] instances or [`data()`][data] objects. A good general rule of thumb when deciding which type to use is:
- If you're using resource routes intended for external consumption, return `Response` instances
- Keeps the resulting response encoding explicit in your code rather than having to wonder how React Router might convert `data() -> Response` under the hood
- If you're accessing resource routes from [fetchers][fetcher] or [`