Set Up Hydrogen Theme

Get started

Create a free Pack account and explore our Quick Start guide.
Continue with the following guide or check out the README file in the Pack's Hydrogen Theme Repository.

Requirements

  • Node.js version 16.14.0 or newer

After cloning your project, begin by installing your node packages:

npm install

Using our CLI tool

To streamline the setup of your Hydrogen Theme, we provide a command-line interface (CLI) tool that simplifies the process. This tool automates several steps, making it easier and faster to get your development environment ready. Here’s how to use it:

  1. Cloning and Setting Up the Hydrogen Theme: Open your terminal and run the following command:

    npx @pack/create-hydrogen@latest
    

    This command does the following:

    • Clones the Hydrogen Theme repository to your local machine.
    • Installs all the necessary node packages using npm install.
    • Prepares your development environment for immediate use.
  2. Running Your Project Locally: Once the setup is complete, you can start your development server with:

    npm run dev
    

    This command serves your project on http://localhost:3000, allowing you to view and test your site in a local development environment.

  3. No Pack Account Required: If you don't have a Pack account yet, no worries! The CLI tool allows you to run the Hydrogen Theme with default Shopify data. This means you can start exploring the capabilities of the Hydrogen framework and how it integrates with Shopify without any initial setup or configuration.

  4. Next Steps: After exploring the Hydrogen Theme project, you might want to customize it further by connecting it to your Shopify Hydrogen storefront. You can do this by setting up environment variables as described below.

Environment Variables

To run your application locally, you need a .env file at the root of your project. Automate the creation of a .env file by pulling variables directly from your Shopify Hydrogen storefront using the Hydrogen CLI. Execute the following command and adhere to its prompts.

npx shopify hydrogen env pull

Alternatively, manually create a .env file and copy the values from your Shopify Hydrogen storefront. Locate the variables by navigating to the Hydrogen storefront > Storefront Settings > Environments & Variables. The necessary variables include:

SESSION_SECRET="XXX"
PUBLIC_STOREFRONT_API_TOKEN="XXX"
PUBLIC_STORE_DOMAIN="XXX"
PACK_PUBLIC_TOKEN="XXX"
PACK_SECRET_TOKEN="XXX"

Building for Production

This command emulates the deployment process Shopify Oxygen uses when deploying your site live.

npm run build

Building for Local Development

This command initiates a server locally on your machine at http://localhost:3000.

npm run dev

Pack Customizer Content

Access Pack Customizer data using the pack object in the Hydrogen context. Consider this example:

export async function loader({params, context, request}: LoaderFunctionArgs) {
  const {handle} = params;
  const storeDomain = context.storefront.getShopifyDomain();

  const searchParams = new URL(request.url).searchParams;
  const selectedOptions: any = [];

  // Assign selected options from the query string
  searchParams.forEach((value, name) => {
    selectedOptions.push({name, value});
  });

  const {data} = await context.pack.query(PRODUCT_PAGE_QUERY, {
    variables: {handle},
  });

  const {product} = await context.storefront.query(PRODUCT_QUERY, {
    variables: {
      handle,
      selectedOptions,
    },
  });

  ...
}

The data object contains all the Pack Section Setting content from CMS Authors in the Customizer, defined per Section's Setting schema. The product object holds Shopify-specific data from the Storefront API.

Refer to Section Schema API.

Caching

Pack employs the same Caching Strategy as the Hydrogen framework. For an example, see app/lib/pack/create-pack-client.ts

NOTE: The lib/pack library will eventually be moved to its own NPM package by Pack.

export function createPackClient(options: CreatePackClientOptions): Pack {
  const {apiUrl, cache, waitUntil, preview, contentEnvironment} = options;
  const previewEnabled = !!preview?.session.get('enabled');
  const previewEnvironment = preview?.session.get('environment');

  return {
    preview,
    isPreviewModeEnabled: () => previewEnabled,
    async query<T = any>(
      query: string,
      {variables, cache: strategy = CacheLong()}: QueryOptions = {},
    ) {
      const queryHash = await hashQuery(query, variables);
      const withCache = createWithCache<QueryResponse<T>>({
        cache,
        waitUntil,
      });

      // Preview environment overrides the content environment set during client creation
      const environment =
        previewEnvironment || contentEnvironment || PRODUCTION_ENVIRONMENT;
      const fetchOptions = {
        apiUrl,
        query,
        variables,
        token: options.token,
        previewEnabled,
        contentEnvironment: environment,
      };

      // Cache is bypassed in preview mode
      if (previewEnabled) return packFetch<T>(fetchOptions);

      return withCache(queryHash, strategy, () => packFetch<T>(fetchOptions));
    },
  };
}

Data Layer

The Pack Hydrogen Theme sends pageView and addToCart (coming soon) events to Shopify Analytics via the Hydrogen hook. For details, visit: https://shopify.dev/docs/api/hydrogen/2023-07/utilities/sendshopifyanalytics

To see how events are submitted, refer to the products route (app/routes/products.$handle.tsx):

export async function loader({params, context, request}: LoaderFunctionArgs) {
  ...

   if (!data.productPage) {
    throw new Response(null, {status: 404});
  }
  // Optionally set a default variant for a consistently "orderable" product
  const selectedVariant =
    product.selectedVariant ?? product?.variants?.nodes[0];



  const productAnalytics: ShopifyAnalyticsProduct = {
    productGid: product.id,
    variantGid: selectedVariant.id,
    name: product.title,
    variantName: selectedVariant.title,
    brand: product.vendor,
    price: selectedVariant.price.amount,
  };
  const analytics = {
    pageType: AnalyticsPageType.product,
    resourceId: product.id,
    products: [productAnalytics],
    totalValue: parseFloat(selectedVariant.price.amount),
  };

  return defer({
    product,
    productPage: data.productPage,
    selectedVariant,
    storeDomain,
    analytics,
  });
}

Was this page helpful?