Skip to content

Releases: Shopify/hydrogen

skeleton@2024.7.3

17 Jul 17:27
583d72f
Compare
Choose a tag to compare

Patch Changes

skeleton@2024.7.2

17 Jul 00:53
23f063d
Compare
Choose a tag to compare

Patch Changes

  • Changed the GraphQL config file format to be TS/JS instead of YAML. (#2311) by @frandiox

  • Updated dependencies [18ea233c, 8b2322d7]:

    • @shopify/cli-hydrogen@8.3.0

@shopify/hydrogen@2024.7.2

17 Jul 17:27
583d72f
Compare
Choose a tag to compare

Patch Changes

  • Fix subrequest profiler by removing the Layout export from virtual root. (#2344) by @michenly

@shopify/create-hydrogen@5.0.2

17 Jul 17:34
6bd1222
Compare
Choose a tag to compare

Patch Changes

  • Force create-hydrogen update due to skeleton changes (#2346) by @michenly

@shopify/create-hydrogen@5.0.1

17 Jul 00:53
23f063d
Compare
Choose a tag to compare

Patch Changes

@shopify/cli-hydrogen@8.3.0

17 Jul 00:53
23f063d
Compare
Choose a tag to compare

Minor Changes

  • The Hydrogen CLI can now read the Codegen configuration from the GraphQL config file (e.g. .graphqlrc.js or .graphqlrc.yml). (#2311) by @frandiox

Patch Changes

skeleton@2024.7.1

11 Jul 14:03
5aa0c18
Compare
Choose a tag to compare

Patch Changes

  • Update @shopify/oxygen-workers-types to fix issues on Windows. (#2252) by @michenly

  • Breaking change by @blittle

    Previously the VariantSelector component would filter out options that only had one value. This is undesireable for some apps. We've removed that filter, if you'd like to retain the existing functionality, simply filter the options prop before it is passed to the VariantSelector component:

     <VariantSelector
       handle={product.handle}
    +  options={product.options.filter((option) => option.values.length > 1)}
    -  options={product.options}
       variants={variants}>
     </VariantSelector>

    Fixes #1198

  • Update remix to v2.10.1 (#2290) by @michenly

  • Update root to use Remix's Layout Export pattern and eliminate the use of useLoaderData in root. (#2292) by @michenly

    The diff below showcase how you can make this refactor in existing application.

    import {
      Outlet,
    -  useLoaderData,
    +  useRouteLoaderData,
    } from '@remix-run/react';
    -import {Layout} from '~/components/Layout';
    +import {PageLayout} from '~/components/PageLayout';
    
    -export default function App() {
    +export function Layout({children}: {children?: React.ReactNode}) {
      const nonce = useNonce();
    -  const data = useLoaderData<typeof loader>();
    +  const data = useRouteLoaderData<typeof loader>('root');
    
      return (
        <html>
        ...
          <body>
    -        <Layout {...data}>
    -          <Outlet />
    -        </Layout>
    +        {data? (
    +          <PageLayout {...data}>{children}</PageLayout>
    +         ) : (
    +          children
    +        )}
          </body>
        </html>
      );
    }
    
    +export default function App() {
    +  return <Outlet />;
    +}
    
    export function ErrorBoundary() {
    - const rootData = useLoaderData<typeof loader>();
    
      return (
    -    <html>
    -    ...
    -      <body>
    -        <Layout {...rootData}>
    -          <div className="route-error">
    -            <h1>Error</h1>
    -            ...
    -          </div>
    -        </Layout>
    -      </body>
    -    </html>
    +    <div className="route-error">
    +      <h1>Error</h1>
    +      ...
    +    </div>
      );
    }
    
  • Refactor the cart and product form components (#2132) by @blittle

  • Remove manual setting of session in headers and recommend setting it in server after response is created. (#2137) by @michenly

    Step 1: Add isPending implementation in session

    // in app/lib/session.ts
    export class AppSession implements HydrogenSession {
    +  public isPending = false;
    
      get unset() {
    +    this.isPending = true;
        return this.#session.unset;
      }
    
      get set() {
    +    this.isPending = true;
        return this.#session.set;
      }
    
      commit() {
    +    this.isPending = false;
        return this.#sessionStorage.commitSession(this.#session);
      }
    }

    Step 2: update response header if session.isPending is true

    // in server.ts
    export default {
      async fetch(request: Request): Promise<Response> {
        try {
          const response = await handleRequest(request);
    
    +      if (session.isPending) {
    +        response.headers.set('Set-Cookie', await session.commit());
    +      }
    
          return response;
        } catch (error) {
          ...
        }
      },
    };

    Step 3: remove setting cookie with session.commit() in routes

    // in route files
    export async function loader({context}: LoaderFunctionArgs) {
      return json({},
    -    {
    -      headers: {
    -        'Set-Cookie': await context.session.commit(),
    -      },
        },
      );
    }
  • Moved @shopify/cli from dependencies to devDependencies. (#2312) by @frandiox

  • The @shopify/cli package now bundles the @shopify/cli-hydrogen plugin. Therefore, you can now remove the latter from your local dependencies: (#2306) by @frandiox

        "@shopify/cli": "3.64.0",
    -   "@shopify/cli-hydrogen": "^8.1.1",
        "@shopify/hydrogen": "2024.7.0",
  • Updated dependencies [a0e84d76, 426bb390, 4337200c, 710625c7, 8b9c726d, 10a419bf, 6a6278bb, 66236ca6, dcbd0bbf, a5e03e2a, c2690653, 54c2f7ad, 4337200c, e96b332b, f3065371, 6cd5554b, 9eb60d73, e432533e, de3f70be, 83cb96f4]:

@shopify/remix-oxygen@2.0.5

11 Jul 14:03
5aa0c18
Compare
Choose a tag to compare

Patch Changes

  • Update @shopify/oxygen-workers-types to fix issues on Windows. (#2252) by @michenly

@shopify/mini-oxygen@3.0.4

11 Jul 14:03
5aa0c18
Compare
Choose a tag to compare

Patch Changes

@shopify/hydrogen@2024.7.1

11 Jul 14:03
5aa0c18
Compare
Choose a tag to compare

Patch Changes

  • Breaking change by @michenly

    customerAccount no longer commit session automatically.

  • Breaking change by @blittle

    Previously the VariantSelector component would filter out options that only had one value. This is undesireable for some apps. We've removed that filter, if you'd like to retain the existing functionality, simply filter the options prop before it is passed to the VariantSelector component:

     <VariantSelector
       handle={product.handle}
    +  options={product.options.filter((option) => option.values.length > 1)}
    -  options={product.options}
       variants={variants}>
     </VariantSelector>

    Fixes #1198

  • Fix the types for optimistic cart (#2132) by @blittle

  • Improve the types for useOptimisticCart() (#2269) by @blittle

  • Fix a small rounding issue when checking stale-while-revalidate timing. (#2220) by @frandiox

  • Update virtual route to use Layout component in the root file. (#2292) by @michenly

  • Add sellingPlanId support to BuyNowButton. (#2254) by @dvisockas

  • Fix customData from Analytics.Provider not being passed to page view events (#2224) by @wizardlyhel

  • Auto cookie domain detection for customer privacy api and better error message for missing analytics fields (#2256) by @wizardlyhel

  • New Features by @blittle

    Add a useOptimisticVariant hook for optimistically rendering product variant changes. This makes switching product variants instantaneous. Example usage:

    function Product() {
      const {product, variants} = useLoaderData<typeof loader>();
    
      // The selectedVariant optimistically changes during page
      // transitions with one of the preloaded product variants
      const selectedVariant = useOptimisticVariant(
        product.selectedVariant,
        variants,
      );
    
      return <ProductMain selectedVariant={selectedVariant} />;
    }

    This also introduces a small breaking change to the VariantSelector component, which now immediately updates which variant is active. If you'd like to retain the current functionality, and have the VariantSelector wait for the page navigation to complete before updating, use the waitForNavigation prop:

    <VariantSelector
      handle={product.handle}
      options={product.options}
      waitForNavigation
    >
      ...
    </VariantSelector>
  • Return null instead of empty object from cart.get() when the cart id is invalid. (#2258) by @frandiox

  • Updated dependencies [54c2f7ad]:

    • @shopify/hydrogen-react@2024.7.1