v0.10.0
Hydrogen v0.10 includes a new server components strategy, a new local preview command, and several important breaking changes. Please read the changes carefully to learn how to upgrade. Thank you for helping us improve Hydrogen during the developer preview!
What's Changed
✨ New Hydrogen apps will includes a yarn preview
command! This runs a local version of a sandboxed v8 runtime that mimics production runtimes like Oxygen and Cloudflare Workers. To test it in a new project, run yarn build && yarn preview
. For existing apps, run yarn build && npx @shopify/hydrogen-cli preview
. This requires Node >= v16.
Breaking Changes:
- Hydrogen now uses Meta's experimental version of React Server Components. Make sure to upgrade
react
andreact-dom
to the latest experimental version:yarn add @shopify/hydrogen [email protected] [email protected]
- We've removed react-router on the server. Instead of relying on
useParams()
to get URL parameters, params are passed directly to page server components:
export default function Product() {
const { handle } = useParams();
...
}
// changes to
export default function Product({ params }) {
const { handle } = params;
...
}
- Shopify configuration should no longer be imported and passed inside
App.server.jsx
, but instead inentry-client.jsx
andentry-server.jsx
:
// /App.server.jsx
import {DefaultRoutes} from '@shopify/hydrogen';
import {Suspense} from 'react';
import DefaultSeo from './components/DefaultSeo.server';
import NotFound from './components/NotFound.server';
import AppClient from './App.client';
import LoadingFallback from './components/LoadingFallback';
export default function App({log, pages, ...serverState}) {
return (
<Suspense fallback={<LoadingFallback />}>
<AppClient helmetContext={serverState.helmetContext}>
<DefaultSeo />
<DefaultRoutes
pages={pages}
serverState={serverState}
log={log}
fallback={<NotFound />}
/>
</AppClient>
</Suspense>
);
}
// /entry-server.jsx
import renderHydrogen from '@shopify/hydrogen/entry-server';
import shopifyConfig from '../shopify.config';
import App from './App.server';
const pages = import.meta.globEager('./pages/**/*.server.[jt](s|sx)');
export default renderHydrogen(App, {shopifyConfig, pages});
// /entry-client.jsx
import renderHydrogen from '@shopify/hydrogen/entry-client';
import shopifyConfig from '../shopify.config';
function ClientApp({children}) {
return children;
}
export default renderHydrogen(ClientApp, {shopifyConfig});
- There's a new
App.client.jsx
component:
// /App.client.jsx
import {HelmetProvider} from '@shopify/hydrogen/client';
import CartProvider from './components/CartProvider.client';
/**
* Setup client context, though the children are most likely server components
*/
export default function ClientApp({helmetContext, children}) {
return (
<HelmetProvider context={helmetContext}>
<CartProvider>{children}</CartProvider>
</HelmetProvider>
);
}
locale
is nowdefaultLocale
inshopify.config.js
graqhqlApiVersion
is nowstorefrontApiVersion
inshopify.config.js
- If you’re using the starter template layout component, remove the useCartUI hook:
// /src/components/Layout.server.jsx
import {
Image,
useShopQuery,
flattenConnection,
LocalizationProvider,
} from '@shopify/hydrogen';
import gql from 'graphql-tag';
import Header from './Header.client';
import Footer from './Footer.server';
import Cart from './Cart.client';
import {Suspense} from 'react';
/**
* A server component that defines a structure and organization of a page that can be used in different parts of the Hydrogen app
*/
export default function Layout({children, hero}) {
const {data} = useShopQuery({
query: QUERY,
variables: {
numCollections: 3,
},
cache: {
maxAge: 60,
staleWhileRevalidate: 60 * 10,
},
});
const collections = data ? flattenConnection(data.collections) : null;
const products = data ? flattenConnection(data.products) : null;
const storeName = data ? data.shop.name : '';
return (
<LocalizationProvider>
<div className="absolute top-0 left-0">
<a
href="#mainContent"
className="p-4 focus:block sr-only focus:not-sr-only"
>
Skip to content
</a>
</div>
<div className="min-h-screen max-w-screen text-gray-700 font-sans">
{/* TODO: Find out why Suspense needs to be here to prevent hydration errors. */}
<Suspense fallback={null}>
<Header collections={collections} storeName={storeName} />
<Cart />
</Suspense>
<main role="main" id="mainContent" className="relative bg-gray-50">
{hero}
<div className="mx-auto max-w-7xl p-4 md:py-5 md:px-8">
{children}
</div>
</main>
<Footer collection={collections[0]} product={products[0]} />
</div>
</LocalizationProvider>
);
}
const QUERY = gql`
query indexContent($numCollections: Int!) {
shop {
name
}
collections(first: $numCollections) {
edges {
node {
description
handle
id
title
image {
...ImageFragment
}
}
}
}
products(first: 1) {
edges {
node {
handle
}
}
}
}
${Image.Fragment}
`;
All changes:
- fix: warn instead of error on new or malformed page server components by @jplhomer in Shopify/hydrogen#495
- feat: implement upstream version of server components by @jplhomer in Shopify/hydrogen#498
- feat: add mini-oxygen preview script (alt) by @jplhomer in Shopify/hydrogen#493
- chore: remove dev by @jplhomer in Shopify/hydrogen#499
- Renamed 'locale' to 'defaultLocale' in shopify.config.js by @michenly in Shopify/hydrogen#496
- Add experimental publish pipeline by @jplhomer in Shopify/hydrogen#500
- fix: ensure runtime deps for CLI are included in deps, not devDeps by @jplhomer in https://github.com/Shopify/hydrogen/pull/501
- chore: try to fix CI issues on Windows by @jplhomer in Shopify/hydrogen#516
- chore(deps): bump nanoid from 3.1.30 to 3.2.0 by @dependabot in Shopify/hydrogen#508
- fix: do not mutate project upon running any CLI command by @jplhomer in Shopify/hydrogen#505
- fix: use MemoryStorage and Cache plugin for cache support in preview by @jplhomer in Shopify/hydrogen#504
- Update Node 14 -> 16 by @rafaelstz in Shopify/hydrogen#518
- fix: do not add CLI as a dep in the starter due to Node 16 requirements by @jplhomer in Shopify/hydrogen#517
- fix: bump to latest React experimental to include SSR Context bugfix by @jplhomer in Shopify/hydrogen#521
- dx: rename graphqlApiVersion to storefrontApiVersion by @frehner in Shopify/hydrogen#470
- [Hydrogen reference]: Regenerate docs by @mcvinci in Shopify/hydrogen#507
- Fix API Routes hot reloading and improvements to API route responses by @blittle in Shopify/hydrogen#524
- fix: use web streams polyfill in Node middleware so we can support Node v14 by @jplhomer in Shopify/hydrogen#527
- docs: update routing docs to remove react-router by @blittle in Shopify/hydrogen#525
- feat: add
dev
command to CLI by @cartogram in Shopify/hydrogen#530 - [Hydrogen docs]: Using
Context
in React Server Components by @mcvinci in Shopify/hydrogen#487 - [Hydrogen docs]: Remove references to React Router by @mcvinci in Shopify/hydrogen#489
New Contributors
- @michenly made their first contribution in Shopify/hydrogen#496
Full Changelog: Shopify/hydrogen@v0.9.1...v0.10.0