Skip to main content
Improved checkout, a new search overlay, enhanced shop experience, and more with our biggest upgrade yet: GraphCommerce 9.0

Improved checkout, a new search overlay, enhanced shop experience, and more with our biggest upgrade yet: GraphCommerce 9.0

Paul Hachmang
Paul Hachmang
January 17

We are very proud to present GraphCommerce 9.0.0. This is the biggest release yet, with 41 new features, 19 small improvements and 179 bugfixes. Stabilizing, enhancing and created beautiful new functionalities to enhance the user experience of shops and giving developers the tools to improve further. Full technical release notes on GitHub

Magento standalone

GraphCommerce can now be used fully independent from any external CMS and can be used as a pure Magento frontend. Although we are pretty happy with the Hygraph integration, we've heard the community loud and clear that an option without a reliance on an external CMS is a welcome sight. For more details, check out the Magento Open Source demo and Installation instructions. (Full PageBuilder integration coming soon, stay tuned).

Completely new Search overlay

One of the most used tools for finding the products you need got a significant upgrade, now featuring a new user-friendly overlay. With recent search inputs, category suggestions, and improved speed, this enhancement ensures a faster and more intuitive search experience.

The SearchOverlay package is compatible with Magento's default search and seamlessly integrates with other implementations like Algolia and Adobe Sensei.

Curious? Explore the demo and see it in action!

Full Algolia mesh implementation

The need for fast, relevant, and personalized search experiences has become paramount. This integration offers developers a robust solution to enhance search capabilities while maintaining the flexibility and performance that GraphCommerce is known for.

The Algolia integration in GraphCommerce is designed with a clear separation between the GraphQL layer and the frontend UI. Algolia is implemented through the GraphQL Mesh for the products query. Querying Algolia instead of Magento can by providing an engine parameter.

query AlgoliaProducts {
products(filter: { engine: { eq: "algolia" } }) {
items {
name
}
}
}

See docs for more detailed information

Algolia Search and Catalog

The Algolia implementation fully replaces the search engine and can replace the product listings with the external search engine. All without modifying frontend UI code, including server side rendering and personalization, caching etc.

Algolia Insights

All events handled by Algolia are tracked though our standardized datalayer package and does not rely on any Google Datalayer configuration and even when third party scripts are blocked insights are still collected.

Algolia Personalization

Allows for detailed personalization based on user behavior that Algolia offers. Results of searches /  search overlay and product listings can be automatically personalized based on previous purchases, frequently selected filters, etc.

Algolia Recommend

Looking Similar, Related Products and Frequently bought together products can now be queried for a product or can replace existing related_products, upsells or crosssells. 

query AlgoliaProducts {
products(filter: { engine: { eq: "algolia" } }) {
items {
name
algolia_looking_similar {
name
}
algolia_related_products {
name
}
algolia_frequently_bought_together {
name
}
}
}
}

Algolia Trending

Two additional queries are introduced to create lists of trendingProducts and trendingFacetValues which allow for creating lists of products that are trending.

query TrendingProducts($input: TrendingProductsInput!) {
trendingProducts(input: $input) {
...ProductListItem
}
}
query TrendingFacetValues($input: TrendingFacetValuesInput!) {
trendingFacetValues(input: $input) {
facetName
facetValue
}
}

Future work will provide UI examples how this feature can be leveraged most successfully.

Publish to Apple App Store and Playstore

With GraphCommerce, you can now launch your Adobe Commerce store as a native iOS and Android app, transforming your shop into a powerful mobile experience. Deliver an exceptional mobile experience and reduce development costs with a smarter strategy.

Get in touch with our team and learn how.

Preview mode toolbar and page revalidation

By pressing Alt+Backtick (`) on your keyboard the Preview mode toolbar is shown. By entering the preview mode secret the preview mode is enabled. Try it out on the demo environment (Secret is UzI1NiIsI)

When activating Preview mode all caches are disabled on the frontend, making it easy to see how content should look without waiting for the page to revalidate automatically. Additionally, from this toolbar you can manually revalidate the currenly viewed page, so you are able to force the frontend to show a fresh version of the page. This lessens the need to fully redeploy the frontend.

Hygraph's Content stages are integrated in the Preview mode toolbar, allowing you to directly view the DRAFT stage from withing GraphCommerce (or any additional stage). Preview mode should also allow you to see newly created pages.

Shop improvements

Numerous small adjustments were made to the frontend, aligning it more closely with common use cases across various shops. These widely used features will save time in future development, eliminating the need for extra coding on your part.

Category sibling navigation and breadcrumbs

To improve navigation within large catalogs, we've added customizable breadcrumbs that work seamlessly on mobile, making it clearer which subcategory you're on. In addition, we've introduced sibling category navigation. When a user is in the deepest category, sibling categories will be displayed, enabling easy navigation.

Pagination variant

We've added a commonly used pagination variant for large catalogs that displays the first few pages, along with the first and last pages, allowing for more intuitive navigation between pages.

Small
Large

Sorting ascending / descending

A small change, but not to be underestimated, users can now sort items in ascending or descending order.

Constrained width

GraphCommerce can now be globally configured to constrain the width of the frontend. We've added two new configuration options: containerSizingShell and containerSizingContent. Actual sizing can be configured in theme.ts. No need to edit or set a max-width on every component. See the demo (visible on desktop only, of course).

Magento improvements

A range of Magento-focused enhancements to streamline store management and improve the user experience. From reordering and order cancellation, options to easy account deletion and guest order tracking, these updates simplify common workflows for both customers and store owners.

Reorder items

Added the reorderItems mutation and a reorder button to the order detail page in the account, making it convenient for customers to directly reorder.

Cancel an order

Implemented the cancelOrder mutation and added a cancel order option to the account section, enabling this option to save time for customer support. (2.4.7+)

Easy account deletion

Implemented the deleteCustomer mutation in the account section. Disabled by default, it can be enabled through the config. This option is a great way to ensure full GDPR compliance, allowing customers to delete their accounts easily and securely. (2.4.7+)

View order as guest

The guestOrder functionality allows customers to track orders made with a guest account, providing an easy way to view the status of their orders without the need for an account.

Confirm email mutation

The confirmEmail mutation (2.4.7+) is now fully supported.

Custom attributes V2 implementation

Use custom_attributesV2 for product specs. This update ensures that the specs table in the frontend is fully configurable and will display all relevant data (2.4.7+).

gc-9-attributes-before.png
gc9-attributes-after.png

Checkout improvements

A smooth checkout is crucial for a seamless experience. We've added a ‘Save in address book’ option, allowing customers to choose one-time addresses, and optimized business fields and customer notes for a cleaner, more flexible flow.

Cart item edit functionality

The product page and the cart edit page use the same <AddProductsToCartView/> component, which makes it easy to quickly edit your product directly from the cart. Changes made on the product page will automatically work on the edit page as well.

Business fields and customer note

Show the Company and VAT fields in the checkout and when creating a new account. To enable this feature, set customerCompanyFieldsEnable in the config. This also allows you to further optimize the fields to suit both customers and businesses.

We also show a customer note during the checkout process by enabling customerAddressNoteEnable in the config.

Save in address book

We’ve added a ‘Save in address book’ checkbox to the checkout. Previously, new addresses were automatically saved, but now customers can choose to ship to a one-time address. This is especially useful for businesses with white label shipping.

gc9-blog-Save-in-address-book.png

INP performance enhancements

We’ve greatly improved the INP performance by leveraging the React Profiler. Rerenders are usually the problem when running into INP problems. We’ve methodically analysed the whole GraphCommerce frontend to reduce any rerenders whenever possible. We’ve seen INP measurements go from 250ms to 54ms.

Permission system

Add permissions configuration to disable functionalities.

Cart permissions

Allows us to restrict functionality of the cart, this can be configured globally or for each storefront. We offer these options:

  • Enabled: Everybody is able to access and use the cart
  • Customer Only: The customer is prompted to sign in whenever a cart related action is made. If the customer signs in successfully the original action is executed, allowing for a transparent integration.
  • Disabled: Users will not be able to add products to their cart and is useful when a shop is running in ‘catalog mode’.

Checkout permissions

Allows us to restrict functionality of the cart, this can be configured globally or for each storefront. We offer these options:

  • Enabled: Everybody is able to access and use the checkout
  • Customer only: A user is prompted to sign in whenever a customer tries to access the checkout pages.
  • Disabled: Users will not be able to check out. Is useful when a shop is running in ‘catalog mode’.

Customer Account Permissions

Allows us to restrict the customer account functionality of the shop. This can be configured globally or for each storefront. We offer these three options:

  • Enabled: Users can create accounts and sign in to access their account.
  • Disable registration: Users can not create an account on the shop and can only log in. Useful for B2B applications.
  • Disabled: Only guests are allowed in the shop and no account can be created.

Sitemap and robots.txt generation

Fully replaced the sitemap and robots.txt generation. We previously relied on next-sitemap to generate the sitemap based on static generated pages, but now have a custom implementation that is much more flexible and doesn’t rely on static generation to support multi domain setups and doesn't rely on the Static Site Generation (SSG) to have all the pages rendered.

For example we have this Global Domain: https://graphcommerce-os.vercel.app/robots.txt

And we have a separate domain for the NL store: https://graphcommerce-os-nl.vercel.app/robots.txt

Developer improvements

Migrated to next.config.ts: Instead of the next.config.js, we’re now using next.config.ts for better type safety (graphcommerce.config.ts is not supported (yet)).

Created a cssFlags functionality which allows showing content based on a value in the local storage. This allows hiding/showing small things (is logged in / light or darkmode).

Moved to serwist for service workers.

Big improvements to the plugin system

Typescript validated, deeper resolution, new configuration object, replace plugins, and more ifConfig options.

1. Plugins now use TypeScript's "moduleSuffixes": [".interceptor", ""] functionality which means that plugins now correctly resolve via TypeScript. So if you go to reference in VSCode (or any other editor), you go to the interceptor directly and see which plugins are applied there. This also means that plugins are automatically checked during build (and will fail if there are errors).

2. The exported type of an intercepted component now has the types of all plugins applied. This means that plugins can modify the props of components (and is still validated with TypeScript). To make this work a plugin must always forward props to the <Prev> to ensure that values are correctly passed on.

3. Plugins will now always be applied to deepest resolved path. This means that a plugin automatically applies to internal usages as well. This thus means that plugins do not need to be written with an internal path, but can keep the parent path. Instead of writing @graphcommerce/magento-cart-items/components/RemoveItemFromCart/RemoveItemFromCartFab you can now write @graphcommerce/magento-cart-items.

4. A new configuration object for plugins is created instead of separate exports (the legacy format is still supported though). This also means that the name of the export dictates the name of the component/function the plugin is applied.

export const config: PluginConfig = {
type: 'component'
module: '@graphcommerce/magento-product',
ifConfig: 'demoMode',
}

5. We now support replace plugins (type: 'replace'), which allow you to replace the original component/function/const completely (and type checked of course).

import { ProductPageNameProps } from '@graphcommerce/magento-product'
import { PluginConfig } from '@graphcommerce/next-config'
export const config: PluginConfig = {
type: 'replace',
module: '@graphcommerce/magento-product',
}
export function ProductPageName(props: ProductPageNameProps) {
const { product } = props
return <div>REPLACEMENT {product.url_key}</div>
}

Plugin files can now have multiple exports for the same configuration. So next to the ProductPageName you can also have a ProductPagePrice export for example in the same file.

6. We now support ifConfig tuple which allows you to apply a plugin only if a certain configuration is set.

export const config: PluginConfig = {
type: 'replace',
module: '@graphcommerce/magento-product',
ifConfig: ['theme', 'my-theme'],
}

This allows you to support multiple builds with different plugins applied. For example one build with GC_THEME=my-theme and another with GC_THEME=my-other-theme. 

New <MediaQuery/> component

Also see our new Web vitals documentation. The MediaQuery component allos us to render (and hydrate) a Component based on a media query given.

<MediaQuery query={(theme) => theme.breakpoints.up('md')}>
<MyExpensiveDesktopComponent>
Only visisble on desktop
</MyExpensiveDesktopComponent>
</MediaQuery>

Media query is a replacement for two commonly used situations:

1. useMediaQuery: When you are now using useMediaQuery to conditionally render content for mobile or desktop. ⁠ a. Is very slow as it has to wait for the JS to initialize on pageload. ⁠ b. Can cause CLS problems if the useMediaQuery is used to render elements in the viewport. ⁠ c. Can cause LCP issues if useMediaQuery is used to render the LCP element. ⁠ d. Causes TBT problems as a component always needs to be rerendered. (And bad TBT can cause INP problems) e. HTML isn't present in the DOM, which can cause SEO issues.

2. CSS Media query: When you are using CSS to show or hide content based on media queries. a. Causes TBT problems as both code paths need to be rendered. (And bad TBT can cause INP problems)

3. It wraps the component in a div that has display: contents; when shown and display: none; when hidden so it should not interfere with other styling. It conditionally hydrates the component if the query matches. If it doesn't match, it will NOT hydrate the component (and thus not execute the JS).

GraphQL Improvements

1. Added support X-Magento-Cache-Id to allow Varnish to cache requests that are made in the browser while users are logged in. For example the products query can now be cached for logged in users. Functionality can be disabled by setting customerXMagentoCacheIdDisable: true in your configuration.

2. Created a GraphQL query field for products: custom_attribute(attribute_code: "attribute_code") to retrieve attribute option value labels. This is different from the custom_attributes endpoint (note the plural) and allows for retrieving singular attribute values, like brand or any other select or multiselect attribute.

3. Added a magentoVersion configuration value to be able to differentiate features based on the Magento version. GraphCommerce will automatically load any schema's that are defined in later version of Magento, allowing GraphCommerce to be forward compatible. See schema-246 and schema-247 directories for the changes made to the schema. This is only for compatibility and doesn't make the functionality work.

4. Created a new @graphcommerce/magento-graphql-rest package to integrate with Magento's REST API. By default allows you to retrieve the customer with m2rest_GetV1CustomersMe and only provides the group_id additionally on the customer (which is required for Algolia customer group pricing)

5. All fragments are now @injectable by default and the @injectable directive isn't required anymore. Always accept @inject directives.

React components

Added new Intl components to be able to handle dates, currencies etc. in a better way.

  • <DisplayNames /> and useIntlDisplayNames
  • <DateTimeFormat /><DateFormat/><TimeFormat /> and useIntlDateTimeFormat
  • <ListFormat /> and useIntlListFormat
  • <CurrencyFormat /><NumberFormat /><UnitFormat /><PercentFormat/> and useIntlNumberFormat

And many more changes

There are many more small changes:

  • Created a new <EmailElement/> component to make re-use easier.
  • Created a new <TelephoneElement /> component to make re-use easier.
  • Replace deprecated updateCustomer mutations with updateCustomerV2
  • Magento 2.4.7: To make the custom_attribute field more valueable, we've added an attribute-field to the AttributeValueInterface to be able to retrieve attribute metadata from the value of an attribute.
  • Allow Lingui to use linguiLocale with country identifiers like en-us, it would always load en in this case. Introduced a new useLocale hook to use the correct locale string to use in Intl methods.
  • When generating the mesh the configuration is passed through @graphcommerce/graphql-mesh/meshConfig allowing plugins to modify the mesh configuration without having to change the .meshrc.yaml itself.
  • Add props to <DarkLightModeThemeProvider /> to disable dark/light mode or to change the default ssr mode. Save user chosen mode in localStorage.
  • Added a new <OverlayHeader /> component to be used in combination with the <Overlay /> component.
  • The <LazyHydrate /> component now accepts a height prop that allows deferring of rendering of the child component when initially rendered on the client. This improves performance when used.
  • Added <RelativeTimeFormat/> and <RelativeToTimeFormat/> and useIntlRelativeTimeFormat to display relative dates in all locales
  • Added new plugin insertion points: <DocumentHeadStart/>, <DocumentHeadEnd/>, <DocumentBodyEnd/>, <DocumentBodyStart/> for the _document.app to allow creating plugins for those locations to insert scripts etc.
  • Added a functionality to copy directories from packages to the project and keep them managed by the package. This allows for injecting additional routes etc.
  • Added PRIVATE_ADDITIONAL_DEPENDENCIES env variable support to enable packages that we do not want to have in the examples directory but we do want to be able to demo.
  • Added PRIVATE_PACKAGE_NAMESPACES env variable to have additional namespaces to be considered to be a graphcommerce package.

Upgrading

Upgrading is crucial to stay up to date and receive the latest fixes. We’ve fixed 359 issues in this update. Please read the full release notes on GitHub: https://github.com/graphcommerce-org/graphcommerce/releases/tag/9.0.0

Upgrade instructions: https://www.graphcommerce.org/docs/upgrading/graphcommerce-8-to-9