Skip to content

bmac/remix-response

Repository files navigation

remix-response

Semantic response helpers for your Remix app.

remix-response provides response helpers that wait on all promises to resolve before serializing the response.

Basic Usage

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: [] }
    // ...
}

Don't go chasin' waterfalls

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,
  });
};

Errors

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;
}

API

Members

ok

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),
  });
};
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 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),
  });
};
resetContent

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),
  });
};
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 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/');
};
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 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/');
};
permanentRedirect

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 &quot;@remix-run/node&quot;;
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 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 &quot;@remix-run/node&quot;;
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 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 &quot;@remix-run/node&quot;;
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 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([]),
  });
};
notFound

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']),
  });
};
methodNotAllowed

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']),
  });
};
notAcceptable

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' }),
  });
};
conflict

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'),
  });
};
gone

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()),
  });
};
preconditionFailed

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.'),
  });
};
expectationFailed

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('πŸš«β˜•'),
  });
};
teapot

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.'),
  });
};
preconditionRequired

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),
  });
};
tooManyRequests

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.'),
  });
};
serverError

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 }
  });
};
notImplemented

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 }
  });
};

Constants

ok

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'),
  });
};

ok

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.

created

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.

noContent

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.

resetContent

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.

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/');
};

Kind: global variable

Param Description
url

A url to redirect the request to

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/');
};

Kind: global variable

Param Description
url

A url to redirect the request to

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/');
};

Kind: global variable

Param Description
url

A url to redirect the request to

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);
  }
};

Kind: global variable

Param Description
url

A url to redirect the request to

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 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

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 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

permanentRedirect

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 &quot;@remix-run/node&quot;;
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.

badRequest

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 &quot;@remix-run/node&quot;;
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.

unauthorized

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 &quot;@remix-run/node&quot;;
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.

forbidden

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.

notFound

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.

methodNotAllowed

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.

notAcceptable

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.

conflict

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.

gone

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.

preconditionFailed

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.

expectationFailed

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.

teapot

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.

preconditionRequired

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.

tooManyRequests

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.

serverError

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.

notImplemented

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.

ok

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.

About

Semantic response helpers for your remix app.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published