--- 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: 2023-07 api_name: hydrogen source_url: html: 'https://shopify.dev/docs/api/hydrogen/2023-07/utilities/storefrontredirect' md: >- https://shopify.dev/docs/api/hydrogen/2023-07/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\ ### StorefrontRedirect * storefront The \[Storefront client]\(/docs/api/hydrogen/2023-07/utilities/createstorefrontclient) instance ```ts Storefront ``` * 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 ``` ```ts { /** The [Storefront client](/docs/api/hydrogen/2023-07/utilities/createstorefrontclient) instance */ storefront: Storefront; /** The [MDN Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object that was passed to the `server.ts` request handler. */ request: Request; /** The [MDN Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object created by `handleRequest` */ response?: Response; /** By default the `/admin` route is redirected to the Shopify Admin page for the current storefront. Disable this redirect by passing `true`. */ noAdminRedirect?: boolean; } ``` ### Storefront Interface to interact with the Storefront API. * query The function to run a query on Storefront API. ```ts (query: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] : [StorefrontQuerySecondParam] : [StorefrontQuerySecondParam?]) => Promise ``` * mutate The function to run a mutation on Storefront API. ```ts (mutation: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] : [StorefrontMutateSecondParam] : [StorefrontCommonOptions<{ readonly [variable: string]: unknown; }>?]) => Promise ``` * cache The cache instance passed in from the \`createStorefrontClient\` argument. ```ts Cache ``` * CacheNone Re-export of \[\`CacheNone\`]\(/docs/api/hydrogen/2023-07/utilities/cachenone). ```ts () => NoStoreStrategy ``` * CacheLong Re-export of \[\`CacheLong\`]\(/docs/api/hydrogen/2023-07/utilities/cachelong). ```ts (overrideOptions?: AllCacheOptions) => AllCacheOptions ``` * CacheShort Re-export of \[\`CacheShort\`]\(/docs/api/hydrogen/2023-07/utilities/cacheshort). ```ts (overrideOptions?: AllCacheOptions) => AllCacheOptions ``` * CacheCustom Re-export of \[\`CacheCustom\`]\(/docs/api/hydrogen/2023-07/utilities/cachecustom). ```ts (overrideOptions: AllCacheOptions) => AllCacheOptions ``` * generateCacheControlHeader Re-export of \[\`generateCacheControlHeader\`]\(/docs/api/hydrogen/2023-07/utilities/generatecachecontrolheader). ```ts (cacheOptions: AllCacheOptions) => string ``` * getPublicTokenHeaders Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See \[\`getPublicTokenHeaders\` in Hydrogen React]\(/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:\~:text=%27graphql%27.-,getPublicTokenHeaders,-(props%3F%3A) for more details. ```ts (props?: Partial> & Pick) => Record ``` * getPrivateTokenHeaders Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See \[\`getPrivateTokenHeaders\` in Hydrogen React]\(/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:\~:text=storefrontApiVersion-,getPrivateTokenHeaders,-(props%3F%3A) for more details. ```ts (props?: Partial> & Pick & { buyerIp?: string; }) => Record ``` * getShopifyDomain Creates the fully-qualified URL to your myshopify.com domain. See \[\`getShopifyDomain\` in Hydrogen React]\(/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:\~:text=StorefrontClientReturn-,getShopifyDomain,-(props%3F%3A) for more details. ```ts (props?: Partial>) => string ``` * getApiUrl Creates the fully-qualified URL to your store's GraphQL endpoint. See \[\`getStorefrontApiUrl\` in Hydrogen React]\(/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:\~:text=storeDomain-,getStorefrontApiUrl,-(props%3F%3A) for more details. ```ts (props?: Partial>) => string ``` * isApiError Determines if the error is resulted from a Storefront API call. ```ts (error: any) => boolean ``` * i18n The \`i18n\` object passed in from the \`createStorefrontClient\` argument. ```ts TI18n ``` ```ts { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](/docs/api/hydrogen/2023-07/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](/docs/api/hydrogen/2023-07/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](/docs/api/hydrogen/2023-07/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](/docs/api/hydrogen/2023-07/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](/docs/api/hydrogen/2023-07/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:~:text=%27graphql%27.-,getPublicTokenHeaders,-(props%3F%3A) for more details. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in Hydrogen React](/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:~:text=storefrontApiVersion-,getPrivateTokenHeaders,-(props%3F%3A) for more details.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in Hydrogen React](/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:~:text=StorefrontClientReturn-,getShopifyDomain,-(props%3F%3A) for more details. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in Hydrogen React](/docs/api/hydrogen-react/2023-07/utilities/createstorefrontclient#:~:text=storeDomain-,getStorefrontApiUrl,-(props%3F%3A) for more details.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } ``` ### IsOptionalVariables ```ts Omit< OperationTypeValue['variables'], AutoAddedVariableNames > extends EmptyVariables ? true // No need to pass variables : GenericVariables extends OperationTypeValue['variables'] ? true // We don't know what variables are needed : false ``` ### AutoAddedVariableNames ```ts 'country' | 'language' ``` ### EmptyVariables ```ts {[key: string]: never} ``` ### GenericVariables ```ts ExecutionArgs['variableValues'] ``` ### StorefrontQueries Maps all the queries found in the project to variables and return types. ```ts export interface StorefrontQueries { // Example of how a generated query type looks like: // '#graphql query q1 {...}': {return: Q1Query; variables: Q1QueryVariables}; } ``` ### StorefrontQuerySecondParam ```ts (RawGqlString extends keyof StorefrontQueries ? StorefrontCommonOptions : StorefrontCommonOptions) & {cache?: CachingStrategy} ``` ### StorefrontCommonOptions ```ts { headers?: HeadersInit; storefrontApiVersion?: string; } & (IsOptionalVariables<{variables: Variables}> extends true ? {variables?: Variables} : {variables: Variables}) ``` ### 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 ``` ```ts AllCacheOptions ``` ### StorefrontMutations Maps all the mutations found in the project to variables and return types. ```ts export interface StorefrontMutations { // Example of how a generated mutation type looks like: // '#graphql mutation m1 {...}': {return: M1Mutation; variables: M1MutationVariables}; } ``` ### StorefrontMutateSecondParam ```ts RawGqlString extends keyof StorefrontMutations ? StorefrontCommonOptions : StorefrontCommonOptions ``` ### NoStoreStrategy * mode ```ts string ``` ```ts { mode: 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 ``` ```ts export interface AllCacheOptions { /** * The caching mode, generally `public`, `private`, or `no-store`. */ mode?: string; /** * 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). */ maxAge?: number; /** * 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). */ staleWhileRevalidate?: number; /** * 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). */ sMaxAge?: number; /** * 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). */ staleIfError?: number; } ``` ### I18nBase * language ```ts LanguageCode ``` * country ```ts CountryCode ``` ```ts { language: LanguageCode; country: CountryCode; } ``` ### 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) => 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; }, }; ```