Hydrogen + Pack Integration: Technical Implementation Guide

Integrating Pack into your existing Hydrogen project is simple and takes just a few minutes.

Pack simplifies building and managing your Hydrogen storefront with easy-to-use developer APIs, CRO tools, and a visual page editor. This makes it easier and faster to customize and enhance your storefront needs.

Prerequisites

  1. A Shopify Hydrogen project on React Router 7 (@shopify/hydrogen ^2026.1.0, react-router ^7.12.0). Still on Remix? Follow the React Router 7 migration guide first.
  2. A Pack account
  3. Node.js version 20 or higher
  4. npm (or your package manager of choice, such as yarn or pnpm)

Install the Pack dependencies

  1. Install the latest version of @pack/hydrogen

npm

npm install @pack/hydrogen@latest
  1. Install the latest version of @pack/react

npm

npm install @pack/react@latest

Update env.d.ts (optional if using Typescript)

If you are using typescript in your Hydrogen project, you will need to add some additional Pack types to your environment definition types.

env.d.ts

interface Env {
  SESSION_SECRET: string
  PUBLIC_STOREFRONT_API_TOKEN: string
  PRIVATE_STOREFRONT_API_TOKEN: string
  PUBLIC_STORE_DOMAIN: string
  PUBLIC_STOREFRONT_API_VERSION: string
  PUBLIC_STOREFRONT_ID: string
  PACK_PUBLIC_TOKEN: string
  PACK_SECRET_TOKEN: string
  PACK_STOREFRONT_ID: string
  PACK_CONTENT_ENVIRONMENT?: string
  PUBLIC_PACK_CONTENT_ENVIRONMENT?: string
  PACK_API_URL?: string
  PRIVATE_SHOPIFY_CHECKOUT_DOMAIN?: string
  PRIVATE_SHOPIFY_STORE_MULTIPASS_SECRET?: string
}

env.d.ts

import type {Pack} from '@pack/hydrogen';

...

declare module 'react-router' {
  export interface AppLoadContext {
    session: HydrogenSession;
    storefront: Storefront;
    env: Env;
    pack: Pack;
  }
}

Modify your server.ts

  1. Import createPackClient, PackSession, PackTestSession, and handleRequest from @pack/hydrogen, and the React Router server build and Oxygen helpers.

server.ts

// Virtual entry point for the app
import * as serverBuild from 'virtual:react-router/server-build'
import {
  createRequestHandler,
  getStorefrontHeaders,
} from '@shopify/hydrogen/oxygen'
import {
  createPackClient,
  PackSession,
  PackTestSession,
  handleRequest,
} from '@pack/hydrogen'
  1. Initialize Pack's sessions where you initialize the AppSession. PackSession tracks whether you are in preview mode, and PackTestSession stores A/B test assignments.

server.ts

const [cache, session, packSession, packTestSession] = await Promise.all([
  caches.open('hydrogen'),
  AppSession.init(request, [env.SESSION_SECRET]),
  PackSession.init(request, [env.SESSION_SECRET]),
  PackTestSession.init(request, [env.SESSION_SECRET]),
])
  1. Creating the pack client

server.ts

const pack = createPackClient({
  cache,
  waitUntil,
  storeId: env.PACK_STOREFRONT_ID,
  token: env.PACK_SECRET_TOKEN,
  session: packSession,
  testSession: packTestSession,
  contentEnvironment: env.PUBLIC_PACK_CONTENT_ENVIRONMENT,
})
  1. Adding the Pack client to app load context. By adding pack to your loader context, you can use this Pack client to make requests to fetch data from Pack's CMS API

server.ts

const response = await handleRequest(
  pack,
  request,
  createRequestHandler({
    build: serverBuild,
    mode: process.env.NODE_ENV,
    getLoadContext: () => ({
      cache,
      waitUntil,
      session,
      storefront,
      cart,
      env,
      pack,
    }),
  }),
)

handleRequest also answers POST /pack/consent, which PackProvider uses to pass the visitor's answer to Shopify's privacy banner to Pack. If you use another consent tool, see Consent Management. To target signed-in customers with audiences, also pass getCustomerContext to createPackClient; see Targeting signed-in customers.

Adding preview route

By adding this api.edit.tsx route, this will allow the customizer and preview links to authenticate and set your storefront in preview mode to pull in draft content.

  1. Create an api.edit.tsx file in ./app/routes
  2. Add in the action and loader handlers

/app/routes/api.edit.tsx

import { previewModeAction, previewModeLoader } from '@pack/hydrogen'
import type { ActionFunction, LoaderFunction } from 'react-router'

export const action: ActionFunction = previewModeAction
export const loader: LoaderFunction = previewModeLoader

Add Pack's PackProvider to your root.tsx

  1. Request Pack data in root loader

/app/root.tsx

import type {Route} from './+types/root';

export async function loader({context}: Route.LoaderArgs) {
  const {pack} = context;
  const isPreviewModeEnabled = pack.isPreviewModeEnabled();
  const siteSettings = await pack.query(SITE_SETTINGS_QUERY, {});

  return {
    ...pack.getPackContextData(),
    customizerMeta: pack.session.get('customizerMeta'),
    isPreviewModeEnabled,
    siteSettings,
    ...
  };
}

const SITE_SETTINGS_QUERY = `#graphql
  query SiteSettings($version: Version) {
    siteSettings(version: $version) {
      id
      status
      settings
      publishedAt
      createdAt
      updatedAt
      favicon
      seo {
        title
        description
        keywords
      }
    }
  }
`
  1. Wrap your app in the PackProvider (PreviewProvider is an alias). This will provide context to get settings and other data from Pack.

/app/root.tsx

import {PackProvider} from '@pack/react';
import {Outlet, useLoaderData} from 'react-router';

...

export default function App() {
  const {customizerMeta, isPreviewModeEnabled, siteSettings} =
    useLoaderData<typeof loader>();

  return (
    <html lang="en">
      <head>...</head>
      <body>
        <PackProvider
          customizerMeta={customizerMeta}
          isPreviewModeEnabled={isPreviewModeEnabled}
          siteSettings={siteSettings}
        >
          <Outlet />
        </PackProvider>
        ...
      </body>
    </html>
  );
}

You're done!

After this you are set to start querying data in your route loaders and rendering sections. You should be able to use the customizer and edit and add new sections.

You can take a look at our Blueprint to see how we structure and implement a Hydrogen project to manage and render sections.

Feel free to also take a look at some of our additional resources and guides below to learn more about storefront development and customization.

Guides

Setting up a Pack storefront

Learn how to set up a Pack storefront.

Read more

Learn more about @pack/hydrogen

Learn more about the @pack/hydrogen package.

Read more

Understanding Sections

Programmatically create your own sections

Read more

How to register a custom section

Learn how to register your section.

Read more

All about @pack/react

Learn more about the components and hooks from @pack/react

Read more

Was this page helpful?