---
title: storefrontRedirect
description: >-
  Queries the Storefront API to see if there is any redirect [created for the
  current
  route](https://help.shopify.com/en/manual/online-store/menus-and-links/url-redirect)
  and performs it. Otherwise, it returns the response passed in the parameters.
  Useful for conditionally redirecting after a 404 response.
api_version: 2024-04
api_name: hydrogen
source_url:
  html: 'https://shopify.dev/docs/api/hydrogen/2024-04/utilities/storefrontredirect'
  md: >-
    https://shopify.dev/docs/api/hydrogen/2024-04/utilities/storefrontredirect.md
---

# storefront​Redirect

Queries the Storefront API to see if there is any redirect [created for the current route](https://help.shopify.com/en/manual/online-store/menus-and-links/url-redirect) and performs it. Otherwise, it returns the response passed in the parameters. Useful for conditionally redirecting after a 404 response.

## storefront​Redirect(**[options](#arguments-propertydetail-options)**​)

### Parameters

* **options**

  **StorefrontRedirect**

  **required**

### Returns

* **Promise\<Response>**

### StorefrontRedirect

* storefront

  The \[Storefront client]\(/docs/api/hydrogen/2024-04/utilities/createstorefrontclient) instance

  ```ts
  Storefront<I18nBase>
  ```

* request

  The \[MDN Request]\(https://developer.mozilla.org/en-US/docs/Web/API/Request) object that was passed to the \`server.ts\` request handler.

  ```ts
  Request
  ```

* response

  The \[MDN Response]\(https://developer.mozilla.org/en-US/docs/Web/API/Response) object created by \`handleRequest\`

  ```ts
  Response
  ```

* noAdminRedirect

  By default the \`/admin\` route is redirected to the Shopify Admin page for the current storefront. Disable this redirect by passing \`true\`.

  ```ts
  boolean
  ```

* matchQueryParams

  By default, query parameters are not used to match redirects. Set this to \`true\` if you'd like redirects to be query parameter sensitive

  ```ts
  boolean
  ```

### Storefront

Interface to interact with the Storefront API.

* query

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(query: RawGqlString, ...options: IsOptionalVariables<StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames, Omit<StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>> extends true ? [(StorefrontCommonExtraParams & Pick<StorefrontQueryOptions, "cache"> & ClientVariables<StorefrontQueries, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [StorefrontCommonExtraParams & Pick<StorefrontQueryOptions, "cache"> & ClientVariables<StorefrontQueries, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<ClientReturn<StorefrontQueries, RawGqlString, OverrideReturnType> & StorefrontError>
  ```

* mutate

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(mutation: RawGqlString, ...options: IsOptionalVariables<StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames, Omit<StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>> extends true ? [(StorefrontCommonExtraParams & ClientVariables<StorefrontMutations, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [StorefrontCommonExtraParams & ClientVariables<StorefrontMutations, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<ClientReturn<StorefrontMutations, RawGqlString, OverrideReturnType> & StorefrontError>
  ```

* cache

  ```ts
  Cache
  ```

* CacheNone

  ```ts
  () => NoStoreStrategy
  ```

* CacheLong

  ```ts
  (overrideOptions?: AllCacheOptions) => AllCacheOptions
  ```

* CacheShort

  ```ts
  (overrideOptions?: AllCacheOptions) => AllCacheOptions
  ```

* CacheCustom

  ```ts
  (overrideOptions: AllCacheOptions) => AllCacheOptions
  ```

* generateCacheControlHeader

  ```ts
  (cacheOptions: AllCacheOptions) => string
  ```

* getPublicTokenHeaders

  ```ts
  (props?: Partial<Pick<StorefrontClientProps, "contentType">> & Pick<StorefrontClientProps, "publicStorefrontToken">) => Record<string, string>
  ```

* getPrivateTokenHeaders

  ```ts
  (props?: Partial<Pick<StorefrontClientProps, "contentType">> & Pick<StorefrontClientProps, "privateStorefrontToken"> & { buyerIp?: string; }) => Record<string, string>
  ```

* getShopifyDomain

  ```ts
  (props?: Partial<Pick<StorefrontClientProps, "storeDomain">>) => string
  ```

* getApiUrl

  ```ts
  (props?: Partial<Pick<StorefrontClientProps, "storefrontApiVersion" | "storeDomain">>) => string
  ```

* i18n

  ```ts
  TI18n
  ```

### StorefrontQueries

Maps all the queries found in the project to variables and return types.



### AutoAddedVariableNames

```ts
'country' | 'language'
```

### StorefrontCommonExtraParams

* headers

  ```ts
  HeadersInit
  ```

* storefrontApiVersion

  ```ts
  string
  ```

* displayName

  ```ts
  string
  ```

### StorefrontQueryOptions

```ts
StorefrontCommonExtraParams & {
  query: string;
  mutation?: never;
  cache?: CachingStrategy;
}
```

### CachingStrategy

Use the \`CachingStrategy\` to define a custom caching mechanism for your data. Or use one of the pre-defined caching strategies: CacheNone, CacheShort, CacheLong.

* mode

  The caching mode, generally \`public\`, \`private\`, or \`no-store\`.

  ```ts
  string
  ```

* maxAge

  The maximum amount of time in seconds that a resource will be considered fresh. See \`max-age\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#:\~:text=Response%20Directives-,max%2Dage,-The%20max%2Dage).

  ```ts
  number
  ```

* staleWhileRevalidate

  Indicate that the cache should serve the stale response in the background while revalidating the cache. See \`stale-while-revalidate\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate).

  ```ts
  number
  ```

* sMaxAge

  Similar to \`maxAge\` but specific to shared caches. See \`s-maxage\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage).

  ```ts
  number
  ```

* staleIfError

  Indicate that the cache should serve the stale response if an error occurs while revalidating the cache. See \`stale-if-error\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error).

  ```ts
  number
  ```

### StorefrontError

* errors

  ```ts
  StorefrontApiErrors
  ```

### StorefrontApiErrors

```ts
JsonGraphQLError[] | undefined
```

### StorefrontMutations

Maps all the mutations found in the project to variables and return types.



### NoStoreStrategy

* mode

  ```ts
  string
  ```

### AllCacheOptions

Override options for a cache strategy.

* mode

  The caching mode, generally \`public\`, \`private\`, or \`no-store\`.

  ```ts
  string
  ```

* maxAge

  The maximum amount of time in seconds that a resource will be considered fresh. See \`max-age\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#:\~:text=Response%20Directives-,max%2Dage,-The%20max%2Dage).

  ```ts
  number
  ```

* staleWhileRevalidate

  Indicate that the cache should serve the stale response in the background while revalidating the cache. See \`stale-while-revalidate\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate).

  ```ts
  number
  ```

* sMaxAge

  Similar to \`maxAge\` but specific to shared caches. See \`s-maxage\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage).

  ```ts
  number
  ```

* staleIfError

  Indicate that the cache should serve the stale response if an error occurs while revalidating the cache. See \`stale-if-error\` in the \[MDN docs]\(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error).

  ```ts
  number
  ```

### I18nBase

* language

  ```ts
  LanguageCode
  ```

* country

  ```ts
  CountryCode
  ```

Examples

### Examples

* #### Example code

  ##### Description

  I am the default example

  ##### JavaScript

  ```js
  import {storefrontRedirect, createStorefrontClient} from '@shopify/hydrogen';
  import * as remixBuild from '@remix-run/dev/server-build';
  import {
    createRequestHandler,
    getStorefrontHeaders,
  } from '@shopify/remix-oxygen';

  export default {
    async fetch(request, env, executionContext) {
      const {storefront} = createStorefrontClient({
        cache: await caches.open('hydrogen'),
        waitUntil: (p) => executionContext.waitUntil(p),
        privateStorefrontToken: env.PRIVATE_STOREFRONT_API_TOKEN,
        publicStorefrontToken: env.PUBLIC_STOREFRONT_API_TOKEN,
        storeDomain: env.PUBLIC_STORE_DOMAIN,
        storefrontHeaders: getStorefrontHeaders(request),
      });

      const handleRequest = createRequestHandler({
        build: remixBuild,
        mode: process.env.NODE_ENV,
      });

      const response = await handleRequest(request);

      if (response.status === 404) {
        /**
         * Check for redirects only when there's a 404 from
         * the app. If the redirect doesn't exist, then
         * `storefrontRedirect` will pass through the 404
         * response.
         */
        return storefrontRedirect({request, response, storefront});
      }

      return response;
    },
  };
  ```

  ##### TypeScript

  ```ts
  import {storefrontRedirect, createStorefrontClient} from '@shopify/hydrogen';
  import * as remixBuild from '@remix-run/dev/server-build';
  import {
    createRequestHandler,
    getStorefrontHeaders,
  } from '@shopify/remix-oxygen';

  export default {
    async fetch(request: Request, env: Env, executionContext: ExecutionContext) {
      const {storefront} = createStorefrontClient({
        cache: await caches.open('hydrogen'),
        waitUntil: (p: Promise<unknown>) => executionContext.waitUntil(p),
        privateStorefrontToken: env.PRIVATE_STOREFRONT_API_TOKEN,
        publicStorefrontToken: env.PUBLIC_STOREFRONT_API_TOKEN,
        storeDomain: env.PUBLIC_STORE_DOMAIN,
        storefrontHeaders: getStorefrontHeaders(request),
      });

      const handleRequest = createRequestHandler({
        build: remixBuild,
        mode: process.env.NODE_ENV,
      });

      const response = await handleRequest(request);

      if (response.status === 404) {
        /**
         * Check for redirects only when there's a 404 from
         * the app. If the redirect doesn't exist, then
         * `storefrontRedirect` will pass through the 404
         * response.
         */
        return storefrontRedirect({request, response, storefront});
      }

      return response;
    },
  };
  ```
