Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
finsilabs avatar

Shopify Hydrogen

  • 66 installs
  • 41 repo stars
  • Updated March 13, 2026
  • finsilabs/awesome-ecommerce-skills

Build a custom Shopify storefront with the Hydrogen React framework and Remix routing, deployed to Shopify's Oxygen edge hosting.

About

Builds headless Shopify storefronts with the Hydrogen React framework and Remix routing, deployed on Oxygen edge hosting. A developer uses it for a custom-coded Shopify frontend.

  • Hydrogen React framework with Remix routing
  • Deploys to Shopify Oxygen edge hosting

Shopify Hydrogen by the numbers

  • 66 all-time installs (skills.sh)
  • Ranked #1,172 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill shopify-hydrogen

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs66
repo stars41
Last updatedMarch 13, 2026
Repositoryfinsilabs/awesome-ecommerce-skills

What it does

Build a custom Shopify storefront with the Hydrogen React framework and Remix routing, deployed to Shopify's Oxygen edge hosting.

Files

SKILL.mdMarkdownGitHub ↗

Shopify Hydrogen

Overview

Hydrogen is Shopify's official React-based framework for building headless storefronts, built on top of Remix and deployed to Oxygen (Shopify's edge hosting). It provides first-class primitives for the Storefront API — product queries, cart management, customer accounts — alongside Shopify-specific components and hooks that handle caching, streaming, and SEO automatically. This skill covers scaffolding a Hydrogen project, querying the Storefront API, implementing cart functionality, and deploying to Oxygen.

When to Use This Skill

  • When building a custom Shopify storefront with full design and UX control
  • When the default Shopify Online Store theme is too limiting for your design requirements
  • When you need server-side rendering, streaming, and edge-deployed performance
  • When integrating third-party services (loyalty, CMS, personalization) directly into the storefront
  • When you want a Shopify-managed backend with a completely custom frontend stack

Prerequisites & Platform Notes

This skill is written for custom/headless storefronts (Node.js, Python, or similar backend). The code examples use TypeScript/Node.js and can be adapted to any stack.

Shopify: Shopify Hydrogen is Shopify's headless framework. MACH/composable patterns apply when using Shopify as the commerce backend with a custom frontend, or when mixing Shopify with other best-of-breed services. WooCommerce: WooCommerce can serve as a headless backend via its REST API and WPGraphQL. These patterns apply when decoupling the frontend from WordPress. Magento: Magento's GraphQL API and PWA Studio support headless architectures. These composable patterns apply to Magento as a backend service in a MACH stack.

You'll need:

  • Node.js 18+ (or adapt to your backend language)
  • Redis for caching/queues
  • An email sending service (SendGrid, AWS SES, or Postmark)
  • CDN (Cloudflare, CloudFront, or Fastly)

Core Instructions

1. Scaffold a Hydrogen project

   npm create @shopify/hydrogen@latest -- --quickstart
   # or with options:
   npm create @shopify/hydrogen@latest
   # Follow prompts: project name, language (TypeScript), mock shop or real credentials
   cd my-hydrogen-store
   npm run dev
   # http://localhost:3000

The project structure follows Remix file-based routing:

   app/
     routes/
       _index.tsx         # Homepage
       products.$handle.tsx  # Product detail page
       collections.$handle.tsx
       cart.tsx
     components/
     lib/
       fragments.ts       # Reusable GraphQL fragments
   server.ts              # Hydrogen + Remix entry point

2. Configure Storefront API credentials

Create a Storefront API token in your Shopify admin under Apps → Develop apps → Create an app → Storefront API.

   # .env
   SESSION_SECRET="your-session-secret"
   PUBLIC_STOREFRONT_API_TOKEN="your-public-token"
   PUBLIC_STORE_DOMAIN="your-store.myshopify.com"
   PUBLIC_STOREFRONT_API_VERSION="2025-01"

The server.ts wires Hydrogen into Remix:

   import {createHydrogenContext} from '@shopify/hydrogen';

   const hydrogenContext = createHydrogenContext({
     storefront: {
       apiVersion: env.PUBLIC_STOREFRONT_API_VERSION,
       privateStorefrontToken: env.PRIVATE_STOREFRONT_API_TOKEN,
       publicStorefrontToken: env.PUBLIC_STOREFRONT_API_TOKEN,
       storeDomain: env.PUBLIC_STORE_DOMAIN,
     },
     session: HydrogenSession.init(request, [env.SESSION_SECRET]),
   });

3. Query the Storefront API

Hydrogen provides a storefront.query method with built-in caching policies.

   // app/routes/products.$handle.tsx
   import {useLoaderData} from '@remix-run/react';
   import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';

   export async function loader({params, context}: LoaderFunctionArgs) {
     const {storefront} = context;
     const {product} = await storefront.query(PRODUCT_QUERY, {
       variables: {handle: params.handle},
       cache: storefront.CacheLong(), // Cache at CDN for 24h
     });

     if (!product) throw new Response('Not Found', {status: 404});
     return json({product});
   }

   const PRODUCT_QUERY = `#graphql
     query Product($handle: String!) {
       product(handle: $handle) {
         id
         title
         descriptionHtml
         featuredImage { url altText width height }
         variants(first: 20) {
           nodes {
             id
             title
             price { amount currencyCode }
             availableForSale
             selectedOptions { name value }
           }
         }
       }
     }
   ` as const;

4. Implement cart with Hydrogen cart utilities

Hydrogen provides server-side cart actions via Remix action functions:

   // app/routes/cart.tsx
   import {CartForm} from '@shopify/hydrogen';
   import type {ActionFunctionArgs} from '@shopify/remix-oxygen';

   export async function action({request, context}: ActionFunctionArgs) {
     const {cart} = context;
     const formData = await request.formData();
     const {action, inputs} = CartForm.getFormInput(formData);

     let result;
     switch (action) {
       case CartForm.ACTIONS.LinesAdd:
         result = await cart.addLines(inputs.lines);
         break;
       case CartForm.ACTIONS.LinesUpdate:
         result = await cart.updateLines(inputs.lines);
         break;
       case CartForm.ACTIONS.LinesRemove:
         result = await cart.removeLines(inputs.lineIds);
         break;
       default:
         throw new Error(`Unhandled cart action: ${action}`);
     }

     const headers = cart.setCartId(result.cart.id);
     return json(result, {headers});
   }

   // Add to cart form component
   export function AddToCartButton({variantId}: {variantId: string}) {
     return (
       <CartForm
         route="/cart"
         action={CartForm.ACTIONS.LinesAdd}
         inputs={{lines: [{merchandiseId: variantId, quantity: 1}]}}
       >
         <button type="submit">Add to Cart</button>
       </CartForm>
     );
   }

5. Use Hydrogen caching strategies

Hydrogen exposes named caching strategies that map to CDN cache-control headers:

   // Long cache for static catalog data
   const {collections} = await storefront.query(COLLECTIONS_QUERY, {
     cache: storefront.CacheLong(), // s-maxage=3600, stale-while-revalidate=82800
   });

   // Short cache for inventory-sensitive data
   const {product} = await storefront.query(PRODUCT_WITH_INVENTORY, {
     cache: storefront.CacheShort(), // s-maxage=1, stale-while-revalidate=9
   });

   // No cache for personalized/cart data
   const {customer} = await storefront.query(CUSTOMER_QUERY, {
     cache: storefront.CacheNone(),
   });

   // Custom strategy
   const {data} = await storefront.query(QUERY, {
     cache: storefront.CacheCustom({
       mode: 'public',
       maxAge: 600,
       staleWhileRevalidate: 3000,
     }),
   });

6. Deploy to Oxygen

   npm install -g @shopify/cli
   shopify hydrogen deploy
   # Creates a deployment in your Shopify admin under Online Store → Themes → Headless

For CI/CD, use the GitHub Action:

   # .github/workflows/oxygen.yml
   - uses: Shopify/hydrogen-action@v1
     with:
       shop: ${{ secrets.SHOPIFY_SHOP_DOMAIN }}
       token: ${{ secrets.SHOPIFY_CLI_TOKEN }}

Examples

Collection page with filtering and sorting

// app/routes/collections.$handle.tsx
export async function loader({params, request, context}: LoaderFunctionArgs) {
  const {storefront} = context;
  const url = new URL(request.url);
  const sortKey = url.searchParams.get('sort') as ProductCollectionSortKeys | null;

  const {collection} = await storefront.query(COLLECTION_QUERY, {
    variables: {
      handle: params.handle,
      first: 24,
      sortKey: sortKey ?? 'BEST_SELLING',
      reverse: sortKey === 'PRICE' ? false : true,
    },
    cache: storefront.CacheShort(),
  });

  return json({collection});
}

const COLLECTION_QUERY = `#graphql
  query Collection(
    $handle: String!
    $first: Int
    $sortKey: ProductCollectionSortKeys
    $reverse: Boolean
  ) {
    collection(handle: $handle) {
      id
      title
      description
      image { url altText }
      products(first: $first, sortKey: $sortKey, reverse: $reverse) {
        nodes {
          id
          title
          handle
          priceRange { minVariantPrice { amount currencyCode } }
          featuredImage { url altText }
        }
        pageInfo { hasNextPage endCursor }
      }
    }
  }
` as const;

Customer authentication with new Customer Account API

// Hydrogen supports the new Customer Account API (OAuth-based)
// app/lib/customer-account.server.ts
export async function loader({context}: LoaderFunctionArgs) {
  const {customerAccount} = context;
  const isLoggedIn = await customerAccount.isLoggedIn();

  if (!isLoggedIn) {
    return redirect('/account/login');
  }

  const {data} = await customerAccount.query(`#graphql
    query Customer {
      customer {
        id
        firstName
        lastName
        emailAddress { emailAddress }
        orders(first: 10) {
          nodes {
            id
            number
            processedAt
            financialStatus
            totalPrice { amount currencyCode }
          }
        }
      }
    }
  `);

  return json({customer: data.customer});
}

Best Practices

  • Use `storefront.CacheLong()` for catalog data — product and collection data rarely changes; long cache TTLs dramatically improve TTFB on Oxygen's edge network
  • Colocate GraphQL queries with routes — define as const fragment strings in the same file as the loader; this keeps data requirements visible and enables TypeScript inference
  • Use Hydrogen's `<Image>` and `<Money>` components — they handle Shopify CDN image optimization URLs and currency formatting automatically
  • Leverage Remix defer + Suspense for non-critical data — render the product immediately and stream recommendations or reviews with defer()
  • Keep cart state server-side via cookies — Hydrogen's cart utilities store the cart ID in a signed cookie; avoid client-only cart state that breaks SSR
  • Use the Storefront API's `@inContext` directive — pass language and country context to get localized prices and translated content per request
  • Pin the Storefront API version in `.env` — Shopify deprecates old API versions; explicit pinning prevents surprise breakage on API updates

Common Pitfalls

ProblemSolution
"Storefront API token not authorized"Ensure the token has unauthenticated_read_* scopes; private tokens are only for server-side requests
Cart state lost between page navigationsStore cart ID in the session cookie using cart.setCartId(); never store cart ID in component state
Images not optimized on OxygenUse Hydrogen's <Image> component or the getImageData() helper to append Shopify CDN transform params
TypeScript errors on GraphQL queriesRun npm run codegen to regenerate types after changing queries; queries must be tagged as const
Deployment fails with "missing environment variables"Oxygen env vars must be added in the Shopify admin under the Hydrogen deployment settings, not just in .env

Related Skills

  • @saleor-development
  • @jamstack-storefront
  • @composable-commerce
  • @pwa-storefront
  • @commerce-api-gateway

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.