Deploy to Oxygen
Oxygen is Shopify's hosting platform for Hydrogen storefronts. It runs your storefront as a Web Worker, not a Node server, and expects a module Worker, a single server bundle, and a directory of client assets.
The React Router starter template already meets these requirements. Follow this guide to deploy it, or to adapt another Vite-based storefront.
Anchor to What you'll learnWhat you'll learn
In this tutorial, you'll learn how to do the following tasks:
- Create a Hydrogen storefront in the Shopify admin.
- Create a Worker entry point and run it locally in MiniOxygen.
- Build your storefront and deploy it to Oxygen.
Anchor to RequirementsRequirements
- Build a Hydrogen storefront that runs locally. Refer to Deploy a template.
- Install the Hydrogen sales channel on your store.
- Run the production checklist against a production build.
Anchor to Step 1: Create a storefront in the Shopify adminStep 1: Create a storefront in the Shopify admin
Each Hydrogen storefront in the Shopify admin links to one app and holds its environments, environment variables, and deployments.
- In the Shopify admin, under Sales channels, click Hydrogen.
- Click Create storefront.
- Type a name for your storefront. You can change the name later.
- Choose how to deploy:
- To deploy when you push to GitHub, select Set up GitHub continuous deployment now. If you haven't connected GitHub to your store, then click Connect GitHub, and install the Shopify GitHub app. Select your GitHub account or organization, and a repository. Shopify adds an Oxygen workflow file to the repository. For more information, refer to Continuous deployment.
- To deploy from your computer or your own CI/CD system, select Set up CI/CD or manual deployments later.
- Click Create.
When you create a storefront, Shopify adds the environment variables that your app needs to query your store. Refer to Environments and variables.
Anchor to Step 2: Create the Worker entry pointStep 2: Create the Worker entry point
Create a module Worker at server.ts in your project root. Oxygen and MiniOxygen, Oxygen's local runtime, find this path without extra configuration. The Worker's fetch function receives the request, the environment bindings, and an execution context. Open the cache and bind waitUntil for each request, and then pass them to your framework's request handler:
Oxygen Worker for React Router
server.tsThe React Router template defines envContext in app/lib/env.ts, with a type for your environment variables. If you're adapting another storefront, then create the file:
Environment context
app/lib/env.tsThe global Env type in server.ts comes from your env.d.ts file. Make it extend this type, as the template's env.d.ts file does.
Hydrogen clients accept the Cache from caches.open() directly. Don't wrap it in an adapter, and don't use a process-local cache such as lru-cache.
Pass the cache and waitUntil to your Storefront API client together:
If your Worker entry point isn't at server.ts, then pass the path as entry to the MiniOxygen plugin, and as --entry to the Shopify CLI commands that run or deploy the Worker.
Anchor to Step 3: Configure MiniOxygenStep 3: Configure Mini Oxygen
MiniOxygen runs your Worker locally in the same runtime as Oxygen. Install MiniOxygen 4.2.0 or higher and the Oxygen Worker types:
Terminal
Add the oxygen() plugin to your Vite config, before your framework's plugin:
MiniOxygen Vite plugin
vite.config.tsThe ssr.optimizeDeps list prevents CommonJS errors such as module is not defined when React Router runs in MiniOxygen. assetsInlineLimit: 0 supports a strict Content Security Policy.
MiniOxygen loads environment variables from your .env files and passes them to the Worker's env argument. Declare the bindings in your Env type, and include @shopify/oxygen-workers-types in your TypeScript types.
Replace any Node-only code in your server runtime with Web APIs, including Buffer, node:* modules, the filesystem, Node streams, and Node-specific renderers. For React Router, render with renderToReadableStream instead of renderToPipeableStream, and remove @react-router/node and @react-router/serve. For the full list of differences, refer to Oxygen runtime.
Anchor to Step 4: Build and previewStep 4: Build and preview
Add scripts that build the app and run the built Worker in MiniOxygen:
Build scripts
package.jsonThe build produces two outputs: one bundled Worker module and one directory of client assets. Configure your server build without code splitting, because Oxygen runs a single Worker bundle. With the default Vite layout, the output looks like this:
Run npm run preview, and then request pages that use Hydrogen data, such as a product page, a collection page, /search, /cart, and /account. A server that starts isn't enough evidence that the Worker handles requests.
Anchor to Step 5: DeployStep 5: Deploy
Link your project to the storefront that you created in step 1, and then pull its environment variables into your local .env file:
Terminal
If env pull reports secret values that it couldn't pull, then set those values in .env yourself.
Deploy with Shopify CLI. Pass the client assets directory and the Worker directory. --worker-dir must contain index.js or index.mjs:
Terminal
If your build writes to a different layout, then change both paths to match it. Shopify CLI uploads your build and returns the deployment's URL.
On Oxygen, your Worker gets its environment variables from the storefront's environment, not from your .env file. To change them, refer to Environments and variables.