Skip to main content

Fetching API data on the storefront

You can build and customize GraphQL queries to display ecommerce data on your storefront, such as products and shopping cart information. In this guide, you will find the basic concepts and steps to implement this in your FastStore project.

caution

When building your storefront with FastStore, you must not send requests to APIs other than the FastStore API. If you need to access other data not available in the native FastStore API schema, you must do this by extending the GraphQL schema. Otherwise, site performance may be compromised and lead to 504 timeout errors.

Before you start

Before getting to work on your code, there are some concepts you should be familiar with when it comes to the FastStore API.

The FastStore API extends the data layer of your preferred static site generation framework (e.g., Next.js, Gatsby), including data from an ecommerce platform. Because of that, ecommerce information is queried for a given page only when that page is built.

This means that updating a given product's information on your ecommerce platform does not automatically update the information displayed on a previously built product page. Whenever you wish to update the information displayed on your website according to your ecommerce platform data, you should redeploy your website, which will trigger page re-generation.

We also recommend that you take the time to learn more about data fetching in the context of the framework you are using, by checking the corresponding article:

Best practices for fetching data

Site performance tends to get worse as more API requests are made by a page. Because of this, the best practices for fetching data on your storefront involve getting precisely the data you need with the minimum number possible of requests to the FastStore API. The sections below go over what you can do to minimize the API requests of your pages.

Fetch only the data you need

GraphQL allows you to customize your query to get precisely the data you need, which reduces the data returned from the requests. Double-check your queries to make sure they are not over-fetching.

This also means that you must be mindful of the data brought into your query by GraphQL fragments. Use them only when they do not include unnecessary data.

Do not send requests to other APIs

If you need data that is not available on the native FastStore GraphQL schema, check the root object.

The GraphQL root object represents the top-level object returned to a query. You can see what data is available in the root object by adding logs or using a GraphQL IDE.

If the root object also lacks the information you need, you must extend the FastStore GraphQL schema instead of adding other requests to your page.

Avoid custom API Routes

We do not recomend using Next.js API Routes other than the ones already built in the FastStore starters.

If you do use this type of function, you must be mindful to always check which ones are actually running and remove the ones that are not.

To see what API Routes are running in your project, you can run the command yarn build at the root of your project and check the log. Then, check the directory src/pages/api of your project and remove functions that are not running or are not included in the starter you used.

Fetching ecommerce data

There are three main steps to building your page code to fetch data from the FastStore API:

  1. Building a query.
  2. Importing the generated query.
  3. Using the data.

Below you can see more details about each step along with code examples.

1. Building a query

First, you need to know what API data you want to use on your page and how to structure a GraphQL query to get it. It is a good idea to check the FastStore API reference on queries. You can also use a GraphQL IDE to build and test queries to make sure it works as expected.

Once you have your query structure, you can pass that as a variable on your code by using the gql tag, like in the example below.

import { gql } from '@faststore/graphql-utils'
...
const query = gql`
query ProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {

seo {
title
description
canonical
}

brand {
name
}

sku
name
description
}
}
`

Queries must be declared in this way on each page on which you wish to use their data. To reuse query snippets across multiple files, you may use GraphQL fragments. In the example below you can see an SEO fragment being used to build the same query as the example above.

Declaring the fragment:

import { gql } from '@faststore/graphql-utils'
...
export const fragment = gql`
fragment ProductSeoFragment_product on StoreProduct {
seo {
title
description
canonical
}
}
`

Using the fragment, on the same file or a different one:

import { gql } from '@faststore/graphql-utils'
...
const query = gql`
query ProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {

...ProductSeoFragment_product

brand {
name
}

sku
name
description
}
}
`

Building queries on Gatsby

If you are building queries on a store that uses Gatsby, keep in mind that you must also use the graphql tag in some contexts. Using graphql causes the query to be processed by Gatsby, while gql does not. Because of that, as a general rule, use graphql for queries that should be run during the page build and gql for the rest.

Also, some queries may not run properly during the build. If you run into that issue, try using gql.

See in the following example how the queries in the Next.js base store product page and the corresponding page of the Gatsby base store compare to each other.

import { gql } from '@faststore/graphql-utils'
...
const query = gql`
query ServerProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {
id: productID

seo {
title
description
canonical
}

brand {
name
}

sku
gtin
name
description

breadcrumbList {
itemListElement {
item
name
position
}
}

image {
url
alternateName
}

offers {
lowPrice
highPrice
priceCurrency
offers {
availability
price
priceValidUntil
priceCurrency
itemCondition
seller {
identifier
}
}
}

isVariantOf {
productGroupID
}

...ProductDetailsFragment_product
}
}
`

2. Importing the generated query

Once you have declared your query on the page code, you can trigger the generation of your query types by running this command:

yarn generate
caution

Whenever you make changes to your declared queries you must regenerate the types with the command above. Otherwise, you will not be able to use the data.

Then you must import the types generated, like in this example:

import { gql } from '@faststore/graphql-utils'
import type { ProductPageQueryQuery } from '@generated/graphql'
...
const query = gql`
query ProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {
## Query fields
}
}
`
info

Note that, like in this example, the auto-generated query types names are formed by adding the word "Query" to the end of the query name you declared.

3. Using the data

Having built a query and imported the generated type, you can effectively destructure and use the API data in your page function, like in the example:

...
type Props = ProductPageQueryQuery

function Page({ product }: Props) {
const { seo } = product
const title = seo.title
const description = seo.description
...
}
...

Complete code example

After completing the steps described above, your code should look like the example below.

info

It is also a good idea to see how data fetching is implemented in pages from FastStore starters, such as:

import { gql } from '@faststore/graphql-utils'
import type { ProductPageQueryQuery } from '@generated/graphql'
...

type Props = ProductPageQueryQuery

function Page({ product }: Props) {
const { seo } = product
const title = seo.title
const description = seo.description
...
}
...

const query = gql`
query ProductPageQuery($slug: String!) {
product(locator: [{ key: "slug", value: $slug }]) {

seo {
title
description
canonical
}

brand {
name
}

sku
name
description
}
}
`

Didn't find your answers? Ask the Community. For documentation suggestions, submit your feedback.

JOIN THE COMMUNITY