create Request Handler
Creates a request handler for Hydrogen apps. It wraps React Router's request handler and adds Hydrogen-specific functionality such as proxying Storefront API requests, collecting tracking information for analytics, and forwarding cookies to the browser.
Anchor to createrequesthandler(options)createRequestHandler(options)
- Anchor to buildbuildbuildServerBuildServerBuildrequiredrequired
React Router's server build
- Anchor to collectTrackingInformationcollectTrackingInformationcollectTrackingInformationbooleanbooleanDefault: trueDefault: true
Collect tracking information from subrequests such as cookies and forward them to the browser. Disable this if you are not using Hydrogen's built-in analytics.
- Anchor to getLoadContextgetLoadContextgetLoadContext(request: Request) => unknown(request: Request) => unknown
Function to provide the load context for each request. It must contain Hydrogen's storefront client instance for other Hydrogen utilities to work properly.
- Anchor to modemodemodestringstring
React Router's mode
- Anchor to poweredByHeaderpoweredByHeaderpoweredByHeaderbooleanbooleanDefault: trueDefault: true
Whether to include the
powered-byheader in responses.- Anchor to proxyStandardRoutesproxyStandardRoutesproxyStandardRoutesbooleanbooleanDefault: trueDefault: true
Whether to proxy standard routes such as
(Storefront API). You can disable this if you are handling these routes yourself. Ensure that the proxy works if you rely on Hydrogen's built-in behaviors such as analytics.
Examples
Example code
Description
I am the default example
JavaScript
import {createHydrogenContext, createRequestHandler} from '@shopify/hydrogen'; import {createCookieSessionStorage} from 'react-router'; import * as reactRouterBuild from 'virtual:react-router/server-build'; export default { async fetch(request, env, executionContext) { const waitUntil = executionContext.waitUntil.bind(executionContext); const [cache, session] = await Promise.all([ caches.open('hydrogen'), AppSession.init(request, [env.SESSION_SECRET]), ]); /* Create context objects required to use Hydrogen with your credentials and options */ const hydrogenContext = createHydrogenContext({ env, request, cache, waitUntil, session, }); /** * Create a request handler with Hydrogen utilities. * This handler automatically proxies Storefront API requests * and collects tracking information for analytics. */ const handleRequest = createRequestHandler({ build: reactRouterBuild, mode: process.env.NODE_ENV, getLoadContext: () => hydrogenContext, }); const response = await handleRequest(request); if (session.isPending) { response.headers.set('Set-Cookie', await session.commit()); } return response; }, }; class AppSession { isPending = false; static async init(request, secrets) { const storage = createCookieSessionStorage({ cookie: { name: 'session', httpOnly: true, path: '/', sameSite: 'lax', secrets, }, }); const session = await storage.getSession(request.headers.get('Cookie')); return new this(storage, session); } get(key) { return this.session.get(key); } destroy() { return this.sessionStorage.destroySession(this.session); } flash(key, value) { this.session.flash(key, value); } unset(key) { this.isPending = true; this.session.unset(key); } set(key, value) { this.isPending = true; this.session.set(key, value); } commit() { this.isPending = false; return this.sessionStorage.commitSession(this.session); } }TypeScript
import { createHydrogenContext, createRequestHandler, type HydrogenSession, } from '@shopify/hydrogen'; import { createCookieSessionStorage, type SessionStorage, type Session, } from 'react-router'; import * as reactRouterBuild from 'virtual:react-router/server-build'; export default { async fetch(request: Request, env: Env, executionContext: ExecutionContext) { const waitUntil = executionContext.waitUntil.bind(executionContext); const [cache, session] = await Promise.all([ caches.open('hydrogen'), AppSession.init(request, [env.SESSION_SECRET]), ]); /* Create context objects required to use Hydrogen with your credentials and options */ const hydrogenContext = createHydrogenContext({ env, request, cache, waitUntil, session, }); /** * Create a request handler with Hydrogen utilities. * This handler automatically proxies Storefront API requests * and collects tracking information for analytics. */ const handleRequest = createRequestHandler({ build: reactRouterBuild, mode: process.env.NODE_ENV, getLoadContext: () => hydrogenContext, }); const response = await handleRequest(request); if (session.isPending) { response.headers.set('Set-Cookie', await session.commit()); } return response; }, }; class AppSession implements HydrogenSession { public isPending = false; constructor( private sessionStorage: SessionStorage, private session: Session, ) {} static async init(request: Request, secrets: string[]) { const storage = createCookieSessionStorage({ cookie: { name: 'session', httpOnly: true, path: '/', sameSite: 'lax', secrets, }, }); const session = await storage.getSession(request.headers.get('Cookie')); return new this(storage, session); } get(key: string) { return this.session.get(key); } destroy() { return this.sessionStorage.destroySession(this.session); } flash(key: string, value: any) { this.session.flash(key, value); } unset(key: string) { this.isPending = true; this.session.unset(key); } set(key: string, value: any) { this.isPending = true; this.session.set(key, value); } commit() { this.isPending = false; return this.sessionStorage.commitSession(this.session); } }