# Creating a Frontend component with a data source **Prerequisites** - GitHub customer repository access - Studio access - CLI running - You've read the [creating a Frontend component article](/frontend-development/creating-a-frontend-component.md), the [creating a configurable Frontend component article](/frontend-development/creating-a-configurable-frontend-component.md), and the [developing a data source extension article](/frontend-development/developing-a-data-source-extension.md) As mentioned in the [creating a configurable Frontend component article](/frontend-development/creating-a-configurable-frontend-component.md), you can create a `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. You can create a Frontend component to utilize data from your API provider. To do this, you need to set this up within your `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](/frontend-development/developing-a-data-source-extension.md) 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: ```json title="Example schema.json file" { "customDataSourceType": "example/star-wars-character-search", "name": "Star wars character search", "category": "Content", "icon": "source", "schema": [] } ``` ```typescript title="Example index.ts file" 'data-sources': { 'example/star-wars-character-search': async ( config: DataSourceConfiguration, context: DataSourceContext, ): Promise => { 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; }); }, }, ``` To bring the data source into a Frontend component, it needs to have a field type of `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: ```json title="Example json.schema array with data source" { "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 } ] } ] } ``` In this example, the schema of the `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](/frontend-development/developing-a-data-source-extension.md) for more information. We're using our `example/star-wars-character-search` data source for this example. As we've set `required` to `true`, when we add the Frontend component to the page it's shown as red with a warning: ![Example warning with red background](https://docs.commercetools.com/frontend-development/images/migrated/eeee620-Frontastic_component_in_page_builder_with_warning.png) Creating this schema in the Studio and editing it on a page results in the following settings form: ![Form to add a data source filter](https://docs.commercetools.com/frontend-development/images/migrated/95eb93e-Star_wars_component_settings.png) We can now click **+ Add data source filter** to bring the data into the component. See the [using the data source filter editor article](/frontend-studio/using-the-data-source-filter-editor.md) for how to use the filter editor. Once you've configured your `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. Find out more about schemas and a complete list of field types and their possibilities in [schemas](/frontend-development/schemas.md). ## Component input in code In the React entry point of your Frontend component, you'll receive a `data` prop which contains the entire configuration from the Studio. ```typescript title="Example data prop in /star-wars-character/index.tsx" 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 (

Star Wars Characters

{totalCount} total characters found

{people.map((character) => (

{character.name}

{character.species !== null && (

Species: {character.species.name}

)}
))} {pageInfo.hasNextPage && (
Next Page
)}
); }; export default StarWarsCharacterSearchTastic; ``` The `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. Frontend component schema is only for visualization purposes. The `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: 1. Create a `schema.json` file 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. ```json title="Example schema with multiple data sources" { "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 } ] } ] } ``` 2. [Upload](/frontend-studio/using-components-in-the-studio.md#add-a-frontend-component-schema) the `schema.json` file to the Studio. 3. Add the component to a page and select the data sources using the [data source filter editor](/frontend-studio/using-the-data-source-filter-editor.md). 4. Add the data sources to the `index.tsx` component file, for example: ```javascript title="Example of using data sources in code" function ProductSliderWithBannersTastic({ data }) { const products = data.products.dataSource; //Products data const banners = data.banners.dataSource; //Banners data //Use data sources in your component return ; } ``` ## Related pages - [Area overview page with navigation](/frontend-development.md) - [Previous page: Creating a configurable Frontend component](/frontend-development/creating-a-configurable-frontend-component.md) - [Next page: Updating a Frontend component schema](/frontend-development/updating-a-frontend-component-schema.md)