- GitHub customer repository access
- Studio access
- CLI running
- You've read the creating a Frontend component article, the creating a configurable Frontend component article, and the developing a data source extension article
schema that makes the Studio render a configuration interface for your Frontend component whenever it's used on a page. The resulting configuration is delivered to the mounted React component of the Frontend component as the prop data.index.tsx component file and within the schema.json file. To require a data source of a certain type you first need to upload a corresponding data source schema. See the developing a data source extension article for more information.In this example, we're using a data source with the below schema and the extension configuration to implement the data source code:
{
"customDataSourceType": "example/star-wars-character-search",
"name": "Star wars character search",
"category": "Content",
"icon": "source",
"schema": []
}
'data-sources': {
'example/star-wars-character-search': async (
config: DataSourceConfiguration,
context: DataSourceContext,
): Promise<DataSourceResult> => {
const pageSize = context.request.query.pageSize || 10;
const after = context.request.query.cursor || null;
return await axios
.post('https://swapi-graphql.netlify.app/.netlify/functions/index', {
query: `{
allPeople(first: ${pageSize}, after: ${JSON.stringify(after)}) {
totalCount
pageInfo {
hasNextPage
endCursor
}
people {
id
name
species {
name
}
}
}
}`,
})
.then(
(response): DataSourceResult => {
return {
dataSourcePayload: response.data?.data?.allPeople || {},
} as DataSourceResult;
},
)
.catch((reason) => {
return {
dataSourcePayload: {
ok: false,
error: reason.toString(),
},
} as DataSourceResult;
});
},
},
dataSource and it needs to have a dataSourceType within the schema.json file.Schema type and data sources
The schema array of the Frontend component schema allows you to group configuration fields into logical (and in the Studio visual) sections. Each section can contain any number of configuration fields:
{
"tasticType": "example/star-wars/character-search",
"name": "Star Wars character search",
"category": "Content",
"icon": "perm_identity",
"description": "A frontend component with a data source example",
"schema": [
{
"name": "Data source",
"fields": [
{
"label": "Characters",
"field": "data",
"type": "dataSource",
"dataSourceType": "example/star-wars-character-search",
"required": true
}
]
}
]
}
StarWarsCharacterSearchTastic received a section Data source which contains exactly 1 configuration field: data. The field is of type dataSource, and the dataSourceType must be something that's been created in the Studio (see the developing a data source extension article for more information. We're using our example/star-wars-character-search data source for this example.required to true, when we add the Frontend component to the page it's shown as red with a warning:
Creating this schema in the Studio and editing it on a page results in the following settings form:
schema.json for your Frontend component with a dataSourceType, you can then automatically access the data in your index.tsx file in the corresponding field name. You can then deal with that data as you wish, for example, display the data, send the information to another server, and so on.The API hub then does all the magic to display products to your customers as they navigate your site.
Component input in code
data prop which contains the entire configuration from the Studio.import React from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
const StarWarsCharacterSearchTastic = ({ data }) => {
const { totalCount, pageInfo, people } = data.data.dataSource;
const router = useRouter();
const { slug, ...queryWithoutSlug } = router.query;
return (
<div>
<h1 className="text-2xl mt-8 font-sans">Star Wars Characters</h1>
<p className="mt-2">{totalCount} total characters found</p>
{people.map((character) => (
<div key={character.id}>
<h2 className="text-lg mt-6 font-sans">{character.name}</h2>
{character.species !== null && (
<p className="mt-2">Species: {character.species.name}</p>
)}
</div>
))}
{pageInfo.hasNextPage && (
<div className="mt-6">
<Link
href={{
pathname: router.asPath.split('?')[0],
query: {
...queryWithoutSlug,
cursor: pageInfo.endCursor,
},
}}
>
<a className="bg-primary-500 px-4 py-2 text-white">Next Page</a>
</Link>
</div>
)}
</div>
);
};
export default StarWarsCharacterSearchTastic;
index.tsx defines a type for the data prop derived from the Frontend component schema. In the code, the provided data can then be directly accessed. It's the data.dataSource that takes the configuration from the Studio.field identifiers in different sections are all global. That means you can freely regroup fields into sections, but also that field identifiers must be unique across all sections!You can have multiple components on the same page using the same data source. But, data sources don't communicate with each other (unless you configure this yourself), so you could see the same thing in both components.
Use multiple data sources
You can use multiple data sources in a single component. To do this, follow these steps:
- Create a
schema.jsonfile with two data sources. The following example shows the creation of a product slider component with embedded banners that are sourced from a content management system (CMS), for example, Contentful.
{
"tasticType": "product-slider-with-embedded-banners",
"name": "Product slider with embedded banners",
"category": "My Category",
"schema": [
{
"name": "Configuration",
"fields": [
{
"label": "Products",
"field": "products",
"type": "dataSource",
"dataSourceType": "frontastic/product-list", //From Composable Commerce
"required": true
},
{
"label": "Banners",
"field": "banners",
"type": "dataSource",
"dataSourceType": "frontastic/content", //From Contenful CMS
"required": true
}
]
}
]
}
- Upload the
schema.jsonfile to the Studio. - Add the component to a page and select the data sources using the data source filter editor.
- Add the data sources to the
index.tsxcomponent file, for example:
function ProductSliderWithBannersTastic({ data }) {
const products = data.products.dataSource; //Products data
const banners = data.banners.dataSource; //Banners data
//Use data sources in your component
return <ProductSliderWithBanners products={products} banners={banners} />;
}