Semantic response helpers for your Remix app.
remix-response
provides response helpers that wait on all promises to
resolve before serializing the response.
yarn add remix-response
import type { LoaderArgs } from "@remix-run/node";
import { ok } from 'remix-response';
const wait = (delay: number) => new Promise((r) => setTimeout(r, delay));
const fetchListings = (search: string) => wait(600).then(() => []);
const fetchRecommendations = (user: unknown) => wait(300).then(() => []);
export const loader = async ({ request, context }: LoaderArgs) => {
const listings = fetchListings(request.url);
const recommendations = fetchRecommendations(context.user);
return ok({
listings, // Promise<[]>
recommendations, // Promise<[]>
});
};
export default function MyRouteComponent() {
const data = useLoaderData<typeof loader>(); // { listings: [], recommendations: [] }
// ...
}
The simplest way fetch data in a remix loader is to use an async function and unwrap every promise with await.
import type { LoaderArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
const wait = (delay: number) => new Promise((r) => setTimeout(r, delay));
const fetchListings = (search: string) => wait(600).then(() => []);
const fetchRecommendations = (user: unknown) => wait(300).then(() => []);
export const loader = async ({ request, context }: LoaderArgs) => {
const listings = await fetchListings(request.url);
const recommendations = await fetchRecommendations(context.user);
return json({
listings,
recommendations,
});
};
However, if we need to fetch data from multiple independent sources
this can slow down the loader response since fetchRecommendations
doesn't start until after the fetchListings
request has been
completed. A better approach would be to delay waiting until all the
fetchs have been initiated.
export const loader = async ({ request, context }: LoaderArgs) => {
- const listings = await fetchListings(request.url);
+ const listings = fetchListings(request.url);
- const recommendations = await fetchRecommendations(context.user);
+ const recommendations = fetchRecommendations(context.user);
return json({
- listings,
+ listings: await listings,
- recommendations,
+ recommendations: await recommendations,
});
};
This change improves the time it takes to run the loader function because now all the fetches are run in parallel and we only need to wait for the longest fetch to complete.
remix-response
can simplifiy things a bit further by automatically
awaiting any promises provided to the top level object before
serializing the response.
This is similar to the behavior of Promise.all
but it preserves the
object shape and keys similar to RSVP.hash
or bluebird's
Promise.props
.
- import { json } from "@remix-run/node";
+ import { ok } from 'remix-response';
export const loader = async ({ request, context }: LoaderArgs) => {
const listings = fetchListings(request.url);
const recommendations = fetchRecommendations(context.user);
- return json({
+ return ok({
- listings: await listings,
+ listings,
- recommendations: await recommendations,
+ recommendations,
});
};
When returning a response, if any of the promises reject the response
will have a 500 status code. The data object will contain all of the
properites with an object similar to Promise.allSettled
indicating
if the promises are fulfilled or rejected and the value
/reason
. This
object can be used in your ErrorBoundary
component to render the
appropriate error message.
import type { LoaderArgs } from "@remix-run/node";
import { ok } from 'remix-response';
const wait = (delay: number) => new Promise((r) => setTimeout(r, delay));
const fetchListings = (search: string) => wait(600).then(() => []);
const fetchRecommendations = (user: unknown) => wait(300).then(() => []);
export const loader = async ({ request, context }: LoaderArgs) => {
const listings = fetchListings(request.url);
const recommendations = fetchRecommendations(context.user);
return ok({
listings, // Promise<[]>
recommendations, // Promise<[]>
ohNo: Promise.reject('oops!'),
});
};
export function ErrorBoundary() {
const error = useRouteError();
// {
// status: 500,
// statusText: 'Server Error',
// data: {
// listings: { status: 'fulfilled', value: [] },
// recommendations: { status: 'fulfilled', value: [] },
// ohNo: { status: 'rejected', reason: 'oops' },
// }
// }
return (
<div>
<h1>
{error.status} {error.statusText}
</h1>
<pre>{JSON.stringify(error.data, null, 2)}</pre>
</div>
);
}
If a response is thrown in the loader this indicates an error. Thrown responses will always keep their original status even if a promise rejects. Unlike a returned response, thown responses always use a settled object format with the status and value/reason. This is to ensure the shape will always be consistent in the ErrorBoundary component.
import type { LoaderArgs } from "@remix-run/node";
import { notFound } from 'remix-response';
const wait = (delay: number) => new Promise((r) => setTimeout(r, delay));
const fetchListings = (search: string) => wait(600).then(() => []);
const fetchRecommendations = (user: unknown) => wait(300).then(() => []);
export const loader = async ({ request, context }: LoaderArgs) => {
const listings = fetchListings(request.url);
const recommendations = fetchRecommendations(context.user);
throw notFound({
listings, // Promise<[]>
recommendations, // Promise<[]>
});
};
export function ErrorBoundary() {
const error = useRouteError();
// {
// status: 404,
// statusText: 'Not Found',
// data: {
// listings: { status: 'fulfilled', value: [] },
// recommendations: { status: 'fulfilled', value: [] },
// }
// }
return null;
}
- ok
This is a shortcut for creating
application/json
responses withstatus: 201
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.import { created } from 'remix-response'; export const action = async () => { return created({ status: 'new', id: Promise.resolve(1), }); };
- created
This is a shortcut for creating a responses with
status: 204
.import { created } from 'remix-response'; export const action = async () => { return noContent(); };
- noContent
This is a shortcut for creating
application/json
responses withstatus: 205
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.import { resetContent } from 'remix-response'; export const loader = async () => { return resetContent({ form: {}, id: Promise.resolve(1), }); };
- resetContent
This is a shortcut for creating
application/json
responses withstatus: 206
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.import { partialContent } from 'remix-response'; export const loader = async () => { return partialContent({ title: 'RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1', id: Promise.resolve(2616), }); };
- partialContent
This is a shortcut for creating a redirect response with
status: 301
. The provided string will be set as the location header in the response.This should be used when the URL of the requested resource has been changed permanently. Browsers will cache this redirect.
import { movedPermanently } from 'remix-response'; export const loader = async () => { return movedPermanently('https://www.example.com/'); };
- movedPermanently
This is a shortcut for creating a redirect response with
status: 302
. The provided string will be set as the location header in the response.This should be used when the URI of requested resource has been changed temporarily. Browsers will not cache this redirectly and it is commonly used in action functions.
import { found } from 'remix-response'; export const action = async () => { return found('https://www.example.com/'); };
- found
This is a shortcut for creating a redirect response with
status: 303
. The provided string will be set as the location header in the response.This indicates that the redirects don't link to the requested resource itself, but to another page (such as a confirmation page, a representation of a real-world object or an upload-progress page). This response code is often sent back as a result of PUT or POST. The method used to display this redirected page is always GET.
import { seeOther } from 'remix-response'; export const action = async () => { return seeOther('https://www.example.com/'); };
- seeOther
This is a shortcut for creating a redirect response with
status: 304
. The provided string will be set as the location header in the response.This is used for caching purposes. It tells the client that the response has not been modified, so the client can continue to use the same cached version of the response.
import { notModified } from 'remix-response'; export const loader = async ({ request }: LoaderArgs) => { if (request.headers.get('If-Modified-Since') === 'Wed, 21 Oct 2015 07:28:00 GMT') { return notModified(request.url); } };
- notModified
This is a shortcut for creating a redirect response with
status: 307
. The provided string will be set as the location header in the response.This should be used to direct the client to get the requested resource at another URI with the same method that was used in the prior request. This has the same semantics as the
302 Found
HTTP response code, with the exception that the user agent must not change the HTTP method used: if aPOST
was used in the first request, aPOST
must be used in the second request.import { temporaryRedirect } from 'remix-response'; export const action = async () => { return temporaryRedirect('https://www.example.com/'); };
- temporaryRedirect
This is a shortcut for creating a redirect response with
status: 308
. The provided string will be set as the location header in the response.This means that the resource is now permanently located at another URI. This has the same semantics as the
301 Moved Permanently
HTTP response code, with the exception that the user agent must not change the HTTP method used: if aPOST
was used in the first request, aPOST
must be used in the second request.import { permanentRedirect } from 'remix-response'; export const action = async () => { return permanentRedirect('https://www.example.com/'); };
- permanentRedirect
This is a shortcut for creating
application/json
responses withstatus: 400
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when the action cannot or will not process the request due to something that is perceived to be a client error.
import type { ActionArgs } from "@remix-run/node"; import { badRequest } from 'remix-response'; export async function action({ request }: ActionArgs) { return badRequest({ form: request.formData(), errors: Promise.resolve({name: 'missing'}), }); };
- badRequest
This is a shortcut for creating
application/json
responses withstatus: 401
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when the action cannot or will not process the request because the user is unauthenticated.
Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response.
import type { ActionArgs } from "@remix-run/node"; import { unauthorized } from 'remix-response'; export async function action({ request }: ActionArgs) { return unauthorized({ form: request.formData(), errors: Promise.resolve({user: 'missing'}), }); };
- unauthorized
This is a shortcut for creating
application/json
responses withstatus: 403
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when the action cannot or will not process the request because the user does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike
401 Unauthorized
, the client's identity is known to the server.import type { ActionArgs } from "@remix-run/node"; import { forbidden } from 'remix-response'; export async function action({ request }: ActionArgs) { return forbidden({ form: request.formData(), errors: Promise.resolve({user: 'missing'}), }); };
- forbidden
This is a shortcut for creating
application/json
responses withstatus: 404
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when the loader find the requested resource. In the browser, this means the URL is not recognized and the brower will not suggest the URL as an autocomplete option int he future
import { notFound } from 'remix-response'; export async function loader() { return notFound({ recommendations: [] fromTheBlog: Promise.resolve([]), }); };
- notFound
This is a shortcut for creating
application/json
responses withstatus: 405
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when the request method is known by the server but is not supported by the target resource. For example, an API may not allow calling DELETE to remove a resource.
import { methodNotAllowed } from 'remix-response'; export async function action() { return methodNotAllowed({ allowedMethods: Promise.resolve(['GET', 'POST']), }); };
- methodNotAllowed
This is a shortcut for creating
application/json
responses withstatus: 406
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This indicates that the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers, and that the server is unwilling to supply a default representation.
Proactive content negotiation headers include:
Accept
,Accept-Encoding
,Accept-Language
.In practice, this error is very rarely used. Instead of responding using this error code, which would be cryptic for the end user and difficult to fix, servers ignore the relevant header and serve an actual page to the user. It is assumed that even if the user won't be completely happy, they will prefer this to an error code.
If a server returns such an error status, the body of the message should contain the list of the available representations of the resources, allowing the user to choose among them.
import { notAcceptable } from 'remix-response'; export async function action() { return notAcceptable({ allowedLanguage: Promise.resolve(['US_en', 'US_es']), }); };
- notAcceptable
This is a shortcut for creating
application/json
responses withstatus: 409
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used to indicate aa request conflicts with the current state of the server.
import { conflict } from 'remix-response'; export async function action() { return conflict({ error: Promise.resolve({ id: 'duplicate id' }), }); };
- conflict
This is a shortcut for creating
application/json
responses withstatus: 410
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used when a resource has been permanently deleted from server, with no forwarding address. Clients are expected to remove their caches and links to the resource.
import { gone } from 'remix-response'; export async function action() { return gone({ error: Promise.resolve('resource deleted'), }); };
- gone
This is a shortcut for creating
application/json
responses withstatus: 412
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used to indicated the client sent preconditions in its headers (usually
If-Unmodified-Since
orIf-None-Match
) which the server does not meet.import { preconditionFailed } from 'remix-response'; export async function action() { return preconditionFailed({ modifiedSince: Promise.resolve(Date.now()), }); };
- preconditionFailed
This is a shortcut for creating
application/json
responses withstatus: 417
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This should be used to indicated the expectation indicated by the
Expect
request header field cannot be met by the server.import { expectationFailed } from 'remix-response'; export async function action() { return expectationFailed({ error: Promise.resolve('Content-Length is too large.'), }); };
- expectationFailed
This is a shortcut for creating
application/json
responses withstatus: 418
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.The server refuses the attempt to brew coffee with a teapot.
import { teapot } from 'remix-response'; export async function action() { return teapot({ error: Promise.resolve('π«β'), }); };
- teapot
This is a shortcut for creating
application/json
responses withstatus: 428
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This is used to indicate the the request must be conditional. This response is intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict.
import { preconditionFailed } from 'remix-response'; export async function action() { return preconditionFailed({ error: Promise.resolve('Missing If-Match header.'), }); };
- preconditionRequired
This is a shortcut for creating
application/json
responses withstatus: 429
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This is used to indacate the user has sent too many requests in a given amount of time ("rate limiting").
import { tooManyRequests } from 'remix-response'; export async function action() { return tooManyRequests({ retryIn: Promise.resolve(5 * 60 * 1000), }); };
- tooManyRequests
This is a shortcut for creating
application/json
responses withstatus: 500
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.The server has encountered a situation it does not know how to handle.
import { serverError } from 'remix-response'; export async function loader() { throw serverError({ error: Promise.resolve('Unable to load resouce.'), }); };
- serverError
This is a shortcut for creating
application/json
responses withstatus: 501
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This is used to indicate the server does not support the functionality required to fulfill the request. This status can also send a
Retry-After
header, telling the requester when to check back to see if the functionality is supported by then.import { notImplemented } from 'remix-response'; export async function loader() { throw notImplemented({ error: Promise.resolve('Unable to load resouce.'), }, { headers: { 'Retry-After': 300 } }); };
- notImplemented
This is a shortcut for creating
application/json
responses withstatus: 503
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.The server is not ready to handle the request. Common causes are a server that is down for maintenance or that is overloaded. This response should be used for temporary conditions and the
Retry-After
HTTP header should, if possible, contain the estimated time before the recovery of the service. This is used to indicate the server does not support the functionalityimport { serviceUnavailable } from 'remix-response'; export async function loader() { throw serviceUnavailable({ error: Promise.resolve('Unable to load resouce.'), }, { headers: { 'Retry-After': 300 } }); };
- ok
This is a shortcut for creating
application/json
responses withstatus: 200
. Convertsdata
into JSON when all the given promises have been fulfilled. The serialized JSON body is an object that has the same key names as the promises object argument. If any of the values in the object are not promises, they will simply be copied over to the fulfilled object.This works similar to
Promise.all([])
, but takes an object instead of an array for its promises argumentimport { ok } from 'remix-response'; export const loader = async () => { return ok({ hello: 'world', promise: Promise.resolve('result'), }); };
This is a shortcut for creating application/json
responses with
status: 201
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
import { created } from 'remix-response';
export const action = async () => {
return created({
status: 'new',
id: Promise.resolve(1),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating a responses with status: 204
.
import { created } from 'remix-response';
export const action = async () => {
return noContent();
};
Kind: global variable
Param | Description |
---|---|
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 205
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
import { resetContent } from 'remix-response';
export const loader = async () => {
return resetContent({
form: {},
id: Promise.resolve(1),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 206
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
import { partialContent } from 'remix-response';
export const loader = async () => {
return partialContent({
title: 'RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1',
id: Promise.resolve(2616),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating a redirect response with status: 301
. The provided string will be set as the location header in the
response.
This should be used when the URL of the requested resource has been changed permanently. Browsers will cache this redirect.
import { movedPermanently } from 'remix-response';
export const loader = async () => {
return movedPermanently('https://www.example.com/');
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating a redirect response with status: 302
. The provided string will be set as the location header in the
response.
This should be used when the URI of requested resource has been changed temporarily. Browsers will not cache this redirectly and it is commonly used in action functions.
import { found } from 'remix-response';
export const action = async () => {
return found('https://www.example.com/');
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating a redirect response with status: 303
. The provided string will be set as the location header in the
response.
This indicates that the redirects don't link to the requested resource itself, but to another page (such as a confirmation page, a representation of a real-world object or an upload-progress page). This response code is often sent back as a result of PUT or POST. The method used to display this redirected page is always GET.
import { seeOther } from 'remix-response';
export const action = async () => {
return seeOther('https://www.example.com/');
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating a redirect response with status: 304
. The provided string will be set as the location header in the
response.
This is used for caching purposes. It tells the client that the response has not been modified, so the client can continue to use the same cached version of the response.
import { notModified } from 'remix-response';
export const loader = async ({ request }: LoaderArgs) => {
if (request.headers.get('If-Modified-Since') === 'Wed, 21 Oct 2015 07:28:00 GMT') {
return notModified(request.url);
}
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating a redirect response with status: 307
. The provided string will be set as the location header in the
response.
This should be used to direct the client to get the requested
resource at another URI with the same method that was used in the
prior request. This has the same semantics as the 302 Found
HTTP
response code, with the exception that the user agent must not
change the HTTP method used: if a POST
was used in the first
request, a POST
must be used in the second request.
import { temporaryRedirect } from 'remix-response';
export const action = async () => {
return temporaryRedirect('https://www.example.com/');
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating a redirect response with status: 308
. The provided string will be set as the location header in the
response.
This means that the resource is now permanently located at another
URI. This has the same semantics as the 301 Moved Permanently
HTTP
response code, with the exception that the user agent must not
change the HTTP method used: if a POST
was used in the first
request, a POST
must be used in the second request.
import { permanentRedirect } from 'remix-response';
export const action = async () => {
return permanentRedirect('https://www.example.com/');
};
Kind: global variable
Param | Description |
---|---|
url | A url to redirect the request to |
This is a shortcut for creating application/json
responses with
status: 400
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when the action cannot or will not process the request due to something that is perceived to be a client error.
import type { ActionArgs } from "@remix-run/node";
import { badRequest } from 'remix-response';
export async function action({ request }: ActionArgs) {
return badRequest({
form: request.formData(),
errors: Promise.resolve({name: 'missing'}),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 401
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when the action cannot or will not process the request because the user is unauthenticated.
Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response.
import type { ActionArgs } from "@remix-run/node";
import { unauthorized } from 'remix-response';
export async function action({ request }: ActionArgs) {
return unauthorized({
form: request.formData(),
errors: Promise.resolve({user: 'missing'}),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 403
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when the action cannot or will not process the
request because the user does not have access rights to the
content; that is, it is unauthorized, so the server is refusing to
give the requested resource. Unlike 401 Unauthorized
, the client's
identity is known to the server.
import type { ActionArgs } from "@remix-run/node";
import { forbidden } from 'remix-response';
export async function action({ request }: ActionArgs) {
return forbidden({
form: request.formData(),
errors: Promise.resolve({user: 'missing'}),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 404
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when the loader find the requested resource. In the browser, this means the URL is not recognized and the brower will not suggest the URL as an autocomplete option int he future
import { notFound } from 'remix-response';
export async function loader() {
return notFound({
recommendations: []
fromTheBlog: Promise.resolve([]),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 405
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when the request method is known by the server but is not supported by the target resource. For example, an API may not allow calling DELETE to remove a resource.
import { methodNotAllowed } from 'remix-response';
export async function action() {
return methodNotAllowed({
allowedMethods: Promise.resolve(['GET', 'POST']),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 406
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This indicates that the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers, and that the server is unwilling to supply a default representation.
Proactive content negotiation headers include: Accept
, Accept-Encoding
, Accept-Language
.
In practice, this error is very rarely used. Instead of responding using this error code, which would be cryptic for the end user and difficult to fix, servers ignore the relevant header and serve an actual page to the user. It is assumed that even if the user won't be completely happy, they will prefer this to an error code.
If a server returns such an error status, the body of the message should contain the list of the available representations of the resources, allowing the user to choose among them.
import { notAcceptable } from 'remix-response';
export async function action() {
return notAcceptable({
allowedLanguage: Promise.resolve(['US_en', 'US_es']),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 409
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used to indicate aa request conflicts with the current state of the server.
import { conflict } from 'remix-response';
export async function action() {
return conflict({
error: Promise.resolve({ id: 'duplicate id' }),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 410
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used when a resource has been permanently deleted from server, with no forwarding address. Clients are expected to remove their caches and links to the resource.
import { gone } from 'remix-response';
export async function action() {
return gone({
error: Promise.resolve('resource deleted'),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 412
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used to indicated the client sent preconditions in
its headers (usually If-Unmodified-Since
or If-None-Match
) which
the server does not meet.
import { preconditionFailed } from 'remix-response';
export async function action() {
return preconditionFailed({
modifiedSince: Promise.resolve(Date.now()),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 417
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This should be used to indicated the expectation indicated by the
Expect
request header field cannot be met by the server.
import { expectationFailed } from 'remix-response';
export async function action() {
return expectationFailed({
error: Promise.resolve('Content-Length is too large.'),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 418
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
The server refuses the attempt to brew coffee with a teapot.
import { teapot } from 'remix-response';
export async function action() {
return teapot({
error: Promise.resolve('π«β'),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 428
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This is used to indicate the the request must be conditional. This response is intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it and PUTs it back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict.
import { preconditionFailed } from 'remix-response';
export async function action() {
return preconditionFailed({
error: Promise.resolve('Missing If-Match header.'),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 429
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This is used to indacate the user has sent too many requests in a given amount of time ("rate limiting").
import { tooManyRequests } from 'remix-response';
export async function action() {
return tooManyRequests({
retryIn: Promise.resolve(5 * 60 * 1000),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 500
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
The server has encountered a situation it does not know how to handle.
import { serverError } from 'remix-response';
export async function loader() {
throw serverError({
error: Promise.resolve('Unable to load resouce.'),
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 501
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This is used to indicate the server does not support the functionality
required to fulfill the request. This status can also send a
Retry-After
header, telling the requester when to check back to see
if the functionality is supported by then.
import { notImplemented } from 'remix-response';
export async function loader() {
throw notImplemented({
error: Promise.resolve('Unable to load resouce.'),
}, {
headers: { 'Retry-After': 300 }
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 503
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
The server is not ready to handle the request. Common causes are a
server that is down for maintenance or that is overloaded. This
response should be used for temporary conditions and the
Retry-After
HTTP header should, if possible, contain the
estimated time before the recovery of the service. This is used to
indicate the server does not support the functionality
import { serviceUnavailable } from 'remix-response';
export async function loader() {
throw serviceUnavailable({
error: Promise.resolve('Unable to load resouce.'),
}, {
headers: { 'Retry-After': 300 }
});
};
Kind: global variable
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |
This is a shortcut for creating application/json
responses with
status: 200
. Converts data
into JSON when all the given
promises have been fulfilled. The serialized JSON body is an object
that has the same key names as the promises object argument. If any
of the values in the object are not promises, they will simply be
copied over to the fulfilled object.
This works similar to Promise.all([])
, but takes an object
instead of an array for its promises argument
import { ok } from 'remix-response';
export const loader = async () => {
return ok({
hello: 'world',
promise: Promise.resolve('result'),
});
};
Kind: global constant
Param | Description |
---|---|
data | A JavaScript object that will be serialized as JSON. |
init? | An optional RequestInit configuration object. |