Here's a quick summary of everything we released in Q1 2024.

How to implement federated content in Hygraph and Svelte

We will explore a use case demonstrating content integration from Federate This using GraphQL.
Motunrayo Moronfolu

Motunrayo Moronfolu

Apr 02, 2024
How to implement federated content in Hygraph and Svelte

Hygraph is a headless content management system (CMS) that promotes composability within a content infrastructure. It offers native GraphQL integration that facilitates efficient data retrieval and enables Content Federation to create unified content experiences.

Svelte is a JavaScript framework known for its distinctive approach to user interface development. Svelte's focus on simplicity, performance, and developer experience has increased its popularity within the web development community.

This article will closely examine federated content management using Hygraph and Svelte. Specifically, we will explore a use case demonstrating content integration from Federate This using GraphQL and discuss the optimal method for establishing a GraphQL connection to Svelte.

#Prerequisites

To comfortably follow along, you’ll need the following:

  • Node.js installed
  • Basic knowledge of JavaScript and Svelte
  • A free-forever Hygraph account
  • Basic knowledge of GraphQL

#What is Content Federation?

Content Federation refers to the process of aggregating data and content from multiple sources and presenting it to users through a unified API endpoint as if sourced from a singular origin. This approach allows seamless access to information from various sources, facilitating efficient data management.

Hygraph, a prominent Content Federation player, offers a suite of mock data APIs via Federate This. These APIs used for demo purposes can be added alongside other APIs in a Hygraph project and queried via a single API.

Let’s explore Hygraph’s Content Federation support using the "Products routes" provided on Federate This and create a Hygraph model.

The “Products routes” showcase a list of dummy products. We will add this route as a remote source on Hygraph — but to do that, you’ll need an account with Hygraph. You can get a free-forever developer account if you don't have one.

#Setting up a Hygraph project

After creating an account on Hygraph, you’ll be prompted to go to create a new project.

creating a project in hygraph

By clicking “Add project,” we see the view below, where we add our project's name, description, and region.

View to set information for our project

After filling in the necessary fields, click "Add project" to finalize the process. This action leads us to the project statistics page, providing an overview of the newly created project.

The project’s statistics page view

#Adding a remote source

Hygraph facilitates Content Federation through its "remote source" feature. To import data from the "Products routes" into Hygraph, create a remote source within the Hygraph project. To do so, navigate to Schema > Remote Sources and click on the "+Add" button, as illustrated below:

View showing how to add a remote source to the Hygraph project

Clicking on the "+Add" button opens a form, where we’ll fill in the following details:

  1. Display name: Enter "Product Source"
  2. Type: Select "GraphQL"
  3. Base URL: Enter the endpoint for our "Product routes" (https://federatethis.com/api/graphql/products), which we will use for queries

For a visual guide, please watch the video below:

Once these details are filled in, the view should look like the below:

Remote source view after filling the fields

To make queries or request data from a remote source, we can use different methods such as:

  1. Remote content: This allows us to add data from external systems directly in Hygraph models, and it can be achieved via remote fields and top level remote fields.

  2. Custom types: Uses GraphQL types that work together with Hygraph’s autogenerated types to create a unified schema for the Hygraph content and the remote data.

  3. Custom input type: Defines input parameters using GraphQL types when making queries to a remote source.

Remote fields enable external data retrieval, and in this implementation, we will use the “remote fields” method due to its tight integration with Hygraph models, which will give us more granular control over data fetching. To do this, we will create a model and add the “products” fields as part of its fields.

#Setting up a model

In Hygraph, a model serves as a content blueprint. Within a model, we can define fields that outline the content's schema and illustrate how various content pieces are interconnected.

To create a model, navigate to Schema > Models and click on “+Add” as seen below:

Guide on adding a model

This opens up the modal below, which we fill with the appropriate information. In our case, we want to add a “Store” model.

The model modal

By selecting "Add Model," we create a Store model. Next, we will define fields for this model. Specifically, we’ll create three fields: "name", "city" and “products” - where “products” will be a remote field from the products “remote source” we added earlier.

To add these fields, navigate to the right sidebar under the "Add Fields" header and choose the appropriate data type for each field.

Both "name" and "city" are string fields for this model. Therefore, we will select "Single line Text" and provide the required information. Repeat this step for the "city" field.

The field modal

To add the “products” field, select “GraphQL” as the type of field. In the “Remote Source” we can already see the “Product Source” selected, so we will leave it as it is. We will add the display name as “products” and select the query as “Products” query. We will not add any “input argument” as we want to get all the products.

At this point, we should have our view looking like this:

the field modal 2

The “Store” model should also look like the below:

store model

#Adding content to the Store model

With the "Store" model created, we will now add content to it. To do this, navigate to Content > Default views, where you’ll find the Store model we created. To add content, click the "+Add entry" button located at the top right corner of the page, as depicted in the image below:

An empty content page

Clicking on the button brings up the view below, where we will input the provided information and save it.

View to add content

Upon completion, the view should look like the one depicted below:

Content view

Now that we have the content set up let’s query this data from the API playground. Copy the query below into the playground.

query MyQuery {
stores {
city
name
}
}

Running this query returns the response below:

Query response for the store content

In the image above, the response displays the content of the fields defined in the "Store" model.

Now, let’s enhance the query by including a request to fetch the "Product routes" we previously imported via a Hygraph remote source. Copy the provided query into the API playground and execute it.

query MyQuery {
stores {
city
name
products {
id
image
name
price
description
}
}
}

response data

In the image above, we can view the response tab, which shows data for both the products and the store’s content.

With this configuration in place and the response successfully displayed, let’s explore how we can query and present this data in a Svelte app.

#Setting up a Svelte app

We‘ll create a new Svelte app using the npm create svelte@latest command. This will also provide a list of options for selecting the appropriate fit for the project.

Which Svelte app template?
Select > Skeleton project
Add type checking with TypeScript?
Select > No //You can select a different option for this
Select additional options (use arrow keys/space bar)
Select > Add ESLint for code linting, Add Prettier for code formatting

Styling a Svelte app with Tailwind CSS The CSS framework we will use in this project is Tailwind CSS, which you’ll need to configure by following the installation steps here.

#Making GraphQL connection with a Svelte application

Connecting a GraphQL endpoint with a Svelte application happens in various ways. One such way is through the use of “graphql-request”.

graphql-request is a lightweight and intuitive API that makes integrating Svelte applications with GraphQL APIs easy without introducing unnecessary complexity. With graphql-request, we can quickly fetch data from GraphQL APIs using asynchronous programming techniques such as async/await, aligning well with Svelte's reactive programming model.

Now, let’s connect our Hygraph project with our Svelte applications and make queries.

Connecting Svelte with the Hygraph’s project GraphQL API We will first need to obtain our access URL to establish a connection between our application and the Hygraph GraphQL endpoint. To accomplish this, we will navigate to our Hygraph project and access Project Settings > ACCESS > API Access > Public Content API to configure our API permissions as illustrated below:

enable access to the content api

Following this, proceed to Project Settings > ACCESS > API Access > Endpoints, where you’ll obtain the Content API. Copy the “high-performance content API” and incorporate it as an environmental variable in your Svelte application for future use in GraphQL requests.

To achieve this, we will create a file named .env and insert the following into it:

VITE_HYGRAPH_URL=add your url

Next, we will install graphql-request into our Svelte application like so:

npm i graphql-request

Now, let‘s navigate to the routes>+page.svelte and add the code below into our <script> tag. This code fetches the product, store data from the Content API endpoint, populates the products, and stores variable.

<script>
import "../app.css";
import { onMount } from 'svelte';
import { gql, GraphQLClient } from 'graphql-request';
import ProductCard from '../components/ProductCard.svelte';
export let products = [];
export let stores = [];
onMount(async () => {
const hygraphURL = import.meta.env.VITE_HYGRAPH_URL;
const client = new GraphQLClient(hygraphURL);
const query = gql`
query products {
stores {
city
name
products {
id
image
name
price
description
}
}
}
`;
try {
const data = await client.request(query);
stores = data.stores;
} catch (error) {
console.error('Error fetching data:', error);
}
});
</script>

Now, let us break down what we achieved in the code block above:

  1. Imports: The script imports necessary modules and dependencies. These include a CSS file (app.css), the onMount function from Svelte, and the gql and GraphQLClient objects from the graphql-request library. Additionally, it imports the ProductCard component from the specified location.

  2. Exported variables: Two variables, products and stores, were exported from the script. These variables will hold the fetched data.

  3. onMount hook: The onMount function is a Svelte lifecycle function that runs when the component is mounted to the DOM. Inside this hook, an asynchronous function is defined to fetch data from the GraphQL API.

  4. GraphQL client initialization: Within the asynchronous function, the script obtains the GraphQL API endpoint URL from the .env file using import.meta.env.VITE_HYGRAPH_URL. It then initializes a new GraphQL client (client) using this URL.

  5. GraphQL query: The script constructs a GraphQL query using the gql template literal. The query requests data for products and stores, specifying the fields to retrieve for each.

  6. Data fetching: The script requests the GraphQL API using the initialized client (client.request(query)). Upon receiving a response, the data for products and stores is extracted from the response.

  7. Data assignment: The fetched data is assigned to the products and stores variables. This updates the variables with the retrieved data, making it available for use in the Svelte component.

  8. Error handling: If an error occurs during the data fetching process, it is caught and logged to the console using console.error.

Creating a card component

Next we’ll create a reusable Svelte component that displays the product details from the GraphQL request. To do that, we will create a file in src > components named “ProductCard.svelte” and add the code below:

<script>
export let product;
</script>
<div class="bg-white rounded-lg overflow-hidden shadow-lg p-6 m-4">
<img src={product.image} alt={product.name} class="w-full h-48 object-cover mb-4">
<h2 class="text-xl font-semibold">{product.name}</h2>
<p class="text-gray-800">${product.price}</p>
<p class="text-sm text-gray-500">{product.description}</p>
</div>

Now, we will import this component for use into the src > routes > [+page.svelte] like so:

import ProductCard from '../components/ProductCard.svelte';

To render each product, we will use the <ProductCard> component by adding this just below the <script> tag, like so:

<h1 class="text-3xl font-semibold mb-8">Product List</h1>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{#each stores as store}
{#each store.products as product}
<ProductCard {product} key={product.id} />
{/each}
{/each}
</div>

Displaying the store

To display the data from the “stores” array as a table, we will add the code below:

<h1 class="text-3xl font-semibold mb-8">Stores</h1>
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">City</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{#each stores as store}
<tr>
<td class="px-6 py-4 whitespace-nowrap">{store.name}</td>
<td class="px-6 py-4 whitespace-nowrap">{store.city}</td>
</tr>
{/each}
</tbody>
</table>

In the code above, we used the {#each stores as store} Svelte syntax to iterate over the "stores" array and created a table row for each store. In the browser, we can see our Svelte application looking like this:

The Svelte app showing the results from the query

The complete code for the application above can be found here.

#Conclusion

This article explored Content Federation and its significance in modern application development. We walked through setting up a Hygraph project, leveraged the power of Hygraph's Content Federation capabilities to combine data from multiple sources seamlessly, and integrated a Svelte app with GraphQL for efficient data fetching.

There’s still a lot more to try out with Hygraph. By creating a free-forever account on Hygraph and exploring more instances of Federate This, you’ll gain a better understanding and hands-on experience of the Content Federation. The Hygraph Slack community is also a great place to share any challenge you may encounter while using Hygraph or chat with the Hygraph team.

Blog Author

Motunrayo Moronfolu

Motunrayo Moronfolu

Senior Frontend Engineer and Technical writer passionate about building and writing about great user experiences.

Share with others

Sign up for our newsletter!

Be the first to know about releases and industry news and insights.