# storefrontRedirect 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. ### Example code ```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; }, }; ``` ```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; }, }; ``` ## Arguments ### StorefrontRedirectGeneratedType Queries the Storefront API to see if there is any redirect created for the current route and performs it. Otherwise, it returns the response passed in the parameters. Useful for conditionally redirecting after a 404 response. #### Returns: Promise #### Params: - options: StorefrontRedirect export async function storefrontRedirect( options: StorefrontRedirect, ): Promise { const { storefront, request, noAdminRedirect, matchQueryParams, response = new Response('Not Found', {status: 404}), } = options; const url = new URL(request.url); const {pathname, searchParams} = url; const isSoftNavigation = searchParams.has('_data'); searchParams.delete('redirect'); searchParams.delete('return_to'); searchParams.delete('_data'); const redirectFrom = ( matchQueryParams ? url.toString().replace(url.origin, '') : pathname ).toLowerCase(); if (url.pathname === '/admin' && !noAdminRedirect) { return createRedirectResponse( `${storefront.getShopifyDomain()}/admin`, isSoftNavigation, searchParams, matchQueryParams, ); } try { const {urlRedirects} = await storefront.query<{ urlRedirects: UrlRedirectConnection; }>(REDIRECT_QUERY, { // The admin doesn't allow redirects to have a // trailing slash, so strip them all off variables: {query: 'path:' + redirectFrom.replace(/\/+$/, '')}, }); const location = urlRedirects?.edges?.[0]?.node?.target; if (location) { return createRedirectResponse( location, isSoftNavigation, searchParams, matchQueryParams, ); } const redirectTo = getRedirectUrl(request.url); if (redirectTo) { return createRedirectResponse( redirectTo, isSoftNavigation, searchParams, matchQueryParams, ); } } catch (error) { console.error( `Failed to fetch redirects from Storefront API for route ${redirectFrom}`, error, ); } return response; } ### StorefrontRedirect ### 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 ### noAdminRedirect By default the `/admin` route is redirected to the Shopify Admin page for the current storefront. Disable this redirect by passing `true`. ### request The [MDN Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object that was passed to the `server.ts` request handler. ### response The [MDN Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object created by `handleRequest` ### storefront The [Storefront client](/docs/api/hydrogen/2024-10/utilities/createstorefrontclient) instance ### Storefront Interface to interact with the Storefront API. ### cache ### CacheCustom ### CacheLong ### CacheNone ### CacheShort ### generateCacheControlHeader ### getApiUrl ### getPrivateTokenHeaders ### getPublicTokenHeaders ### getShopifyDomain ### i18n ### mutate ### query ### AllCacheOptions Override options for a cache strategy. ### 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). ### mode The caching mode, generally `public`, `private`, or `no-store`. ### 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). ### 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). ### 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). ### NoStoreStrategy ### mode ### StorefrontMutations Maps all the mutations found in the project to variables and return types. export interface StorefrontMutations { // Example of how a generated mutation type looks like: // '#graphql mutation m1 {...}': {return: M1Mutation; variables: M1MutationVariables}; } ### AutoAddedVariableNames 'country' | 'language' ### StorefrontCommonExtraParams ### displayName ### headers ### storefrontApiVersion ### StorefrontError ### errors ### StorefrontApiErrors JsonGraphQLError[] | undefined ### JsonGraphQLError ReturnType ### StorefrontQueries Maps all the queries found in the project to variables and return types. export interface StorefrontQueries { // Example of how a generated query type looks like: // '#graphql query q1 {...}': {return: Q1Query; variables: Q1QueryVariables}; } ### StorefrontQueryOptions 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. ### 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). ### mode The caching mode, generally `public`, `private`, or `no-store`. ### 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). ### 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). ### 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). ### I18nBase ### country ### language