Easily restore your project to a previous version with our new Instant One-click Backup Recovery

SKNCRE, a Hygraph cosmetics brand e-commerce demo

A composable commerce demo with Hygraph, NuxtJS, and an external API for product data.

Cover image for SKNCRE, a Hygraph cosmetics brand e-commerce demo

SKNCRE is a fictitious cosmetics brand selling costly snail slime skin care products: face serum, face cream, eye contour, and the SKNCRE bundle. What you often see in composable e-commerce is that the product information lives in a specialized management system (a PIM), the content of the website in a CMS, and commerce features such as a cart, checkout, account, and payments in yet another system (a commerce engine).

In this example, all pages, content, and media are stored in Hygraph, but the products come from an external system – in this case, a mock API called Federate This. We expose the data in Hygraph via Content Federation. Developers query the CMS for product data, while editors can use the data inside the CMS while they combine editing native and federated content as if it were the same. The beauty is that developers and content editors do not need to understand the external product API as they use it directly through Hygraph.

This demo’s architecture is highly composable, and it would be relatively easy to add a system like Commerce Layer to facilitate shopping cart and checkout functionality.

Clone the repository, install the dependencies with yarn install, create and fill out the .env file with your API endpoint (or grab the one from the .env.example file), and run the app with yarn dev. If you dislike Yarn, use npm, pnpm, or bun instead.

The tech

The data side of things

As mentioned in the introduction, we are using the Federate This mock data API for the product information in this demo. We use Content Federation to fetch the API response of Federate This into Hygraph so we can use it as native data in the GraphQL API.

For the content model, we use a wide array of features in the CMS, from models that represent pages (page, pdp) to a productHighlight model to component schemas attached to page models for easy page building. Learn more about Hygraph’s components in our documentation.

The pdp page and the productHighlight models have been connected to external Federate This product data. This way, Hygraph doesn’t own the product data but merely serves it, leaving the external system completely autonomous. If the external API data changes, it also changes in Hygraph. Hygraph serves the data from the CDN edge, and you can set a TTL for the cached data.

The schema for a product page with a remote GraphQL API field for selecting a Product from the Federate This endpoint.

The schema for a product page with a remote GraphQL API field for selecting a Product from the Federate This endpoint.

The front end

I chose to use NuxtJS for this example as it is one of the fastest ways for me to create high-quality code. Consider NuxtJS the Next.js of the Vue world (it has even more advanced features in certain areas!)

For this project, we use the nuxt-graphql-client module. This helps with codegen for GraphQL functionality and types, and it is an all-around easy way to use GraphQL API’s in NuxtJS.

Nuxt features to make your life easier

There are a few things added to this project to make developers happy.

  1. A Hygraph @nuxt/image provider so developers can render lazy loaded, responsive images with custom quality and image format using the Nuxt Image module.
<NuxtImg
provider="hygraph"
src="<hygraph_image_url>"
width="500"
height="500"
quality="90"
sizes="sm:100vw lg:50vw"
alt="Alt text for image"
loading="lazy"
/>
  1. Draft preview with Nuxt preview mode. If you add ?preview=true to any URL, the app will query Hygraph APIs in draft mode. It also turns on Nuxt’s excellent preview mode, allowing you to update the data on the page without reloading it.

  2. Dynamically render Hygraph page components with Vue. The dynamic nature of Hygraph’s components approach ensures developers can’t just set up a structure and expect the data to be the same continuously. Instead, you loop over the data, see what you are dealing with, and dynamically render each bit as a Vue component. This is how the demo project solves this problem for you.

import type { Component } from 'vue'
import NoComponent from "./NoComponent.vue";
import Hero from "./Hero.vue";
import ProductDetail from "./ProductDetail.vue";
type Mapping = {
[name: string]: Component
}
export const mapping: Mapping = {
Hero,
ProductDetail,
};
export function getComponentForName(name: string) {
return mapping[name] ?? NoComponent
}
<script setup lang="ts">
import { getComponentForName } from "./componentMapper";
const props = defineProps(['data']);
const page = ref();
page.value = props.data;
</script>
<template>
<component
v-for="component in page?.components"
:is="getComponentForName(component?.__typename)"
:key="(component?.id as string)"
v-bind="component"
/>
</template>

Concluding

If you want a nice-looking demo that dips its toes into composable commerce with Hygraph and an external data source, this demo is for you. It’s been designed to be intuitive and highly composable, so adding a shopping cart and checkout would be relatively simple.

Do you have any questions, feedback, or comments? Please join our community!

Build your own app

Build your own app using our SDK and extend Hygraph functionalities according to your unique requirements.