Documentation
Feedback
Guides
Storefront Development

Storefront Development
FastStoreCustomizing sections and components
Creating a new section
In this guide, you will learn how to create a new section for your storefront and make it available in the Headless CMS. This solution is useful when your project requires a section not natively available in FastStore.
For this guide, we will create two sections:
  • Call to Action Gets a specific action from the user.
  • OurStores: Indicates the closest store for the user.
    Sections are page components that wrap up other components, enabling you to create cohesive and functional content for your store. For example, the Hero section is a native section that includes the following components: Hero, HeroImage, and HeroHeader.

Before you begin

1. Integrate the store with the Headless CMS

All sections must be available in the Headless CMS so they can be added and managed on your store's pages. To integrate your FastStore project, please refer to the Headless CMS integration track.

2. Knowledge of how sections and content types work on Headless CMS

During the creation of a new section, you will create files such as sections.json and content-types.json, which follow a structure established for the Headless CMS.

3. Install the FastStore CLI

Make sure to install the FastStore CLI to use its commands locally. Refer to the FastStore CLI guide for more information.

Call to Action

  1. In the FastStore root directory, create a folder named cms.
  2. Inside cms, create the faststore folder.
  3. Within the cms/faststore folder, create sections.json file.
  4. In the sections.json file, add the new section that you want to display in the Headless CMS. The schema below defines how the Headless CMS renders a section:
sections.json

_38
[
_38
{
_38
"name": "CallToAction",
_38
"schema": {
_38
"title": "Call To Action",
_38
"description": "Get your 20% off on the first purchase!",
_38
"type": "object",
_38
"required": [
_38
"title",
_38
"link"
_38
],
_38
"properties": {
_38
"title": {
_38
"title": "Title",
_38
"type": "string"
_38
},
_38
"link": {
_38
"title": "Link Path",
_38
"type": "object",
_38
"required": [
_38
"text",
_38
"url"
_38
],
_38
"properties": {
_38
"text": {
_38
"title": "Text",
_38
"type": "string"
_38
},
_38
"url": {
_38
"title": "URL",
_38
"type": "string"
_38
}
_38
}
_38
}
_38
}
_38
}
_38
}
_38
]

This new section receives a title and a link pointing to a specific location.

Step 2: Creating the new section

To render the CallToAction section you created in the previous step, you need to create this section component.
  1. If you don't already have it, create a folder named components inside the src directory.
  2. Inside the components folder, create a file named CallToAction.tsx and add the following code:
src/components/CallToAction.tsx

_18
import React from "react";
_18
_18
export interface CallToActionProps {
_18
title: string;
_18
link: {
_18
text: string;
_18
url: string;
_18
};
_18
}
_18
_18
export default function CallToAction(props: CallToActionProps) {
_18
return (
_18
<section>
_18
<h2>{props.title}</h2>
_18
<a href={props.link.url}>{props.link.text}</a>
_18
</section>
_18
);
_18
}

This section will receive the link and title defined previously in the sections.json file.
  1. Create a file named index.tsx inside the components folder.
The index.tsx file provides an entry point for importing and using the CallToAction component. It acts as a container for all the components within the components folder and allows for easier organization and reusability of code.
Open the index.tsx file and add the following code:
src/components/index.tsx

_10
import CallToAction from './CallToAction'
_10
_10
export default { CallToAction }

Step 3: Synchronizing the new section with the Headless CMS

  1. In the terminal, run faststore cms-sync. This command will synchronize the new section you created with the CMS.
  2. Go to the VTEX Admin and access Storefront > Headless CMS.
  3. Click on the Page content type.
{"base64":"  ","img":{"width":3824,"height":1360,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":321106,"url":"https://vtexhelp.vtexassets.com/assets/docs/src/create-new-section-cms___51aed56fb1be8d73c2fee14e54151c3d.png"}}
  1. In the Sections tab, click the +, search for the new Call to Action section, and add it to your page.
{"base64":"  ","img":{"width":1898,"height":736,"type":"gif","mime":"image/gif","wUnits":"px","hUnits":"px","length":928366,"url":"https://vtexhelp.vtexassets.com/assets/docs/src/create-new-section-cms-component___994587c4fa77d99a04fda72524266d4d.gif"}}

OurStore

  1. After creating the files and folders, In the sections.json file, add the new section that you want to display in the Headless CMS. The schema below defines how the Headless CMS renders the OurStores section that we will use in the example:
sections.json

_23
[
_23
{
_23
"name": "OurStores",
_23
"schema": {
_23
"title": "Our Stores",
_23
"description": "Search stores near to the users",
_23
"type": "object",
_23
"required": ["title", "description"],
_23
"properties": {
_23
"title": {
_23
"title": "Title",
_23
"type": "string",
_23
"default": "Explore Nearby Stores"
_23
},
_23
"description": {
_23
"title": "Link Path",
_23
"type": "string",
_23
"default": "Discover the closest store to you and pay us a visit."
_23
}
_23
}
_23
}
_23
}
_23
]

  1. Inside the components folder, create a file named OurStores.tsx and add the following code:
src/components/OurStores.tsx

_45
import React from 'react'
_45
import { Button, Icon, SelectField } from '@faststore/ui'
_45
_45
export interface OurStoresProps {
_45
title: string
_45
description: string
_45
}
_45
_45
export default function OurStores(props: OurStoresProps) {
_45
return (
_45
<section>
_45
<h2>{props.title}</h2>
_45
<p>{props.description}</p>
_45
<div>
_45
<SelectField
_45
id="select-state-store"
_45
label="State:"
_45
options={{
_45
newYork: 'New York',
_45
arizona: 'Arizona',
_45
massachusetts: 'Massachusetts',
_45
hawaii: 'Hawaii',
_45
}}
_45
/>
_45
<SelectField
_45
id="select-city-store"
_45
label="City:"
_45
options={{
_45
newYorkCity: 'New York City',
_45
phoenix: 'Phoenix',
_45
boston: 'Boston',
_45
honolulu: 'Honolulu',
_45
}}
_45
/>
_45
<Button
_45
variant="secondary"
_45
icon={<Icon name="ArrowRight" />}
_45
iconPosition="right"
_45
>
_45
Find Store
_45
</Button>
_45
</div>
_45
</section>
_45
)
_45
}

For this section, we will use the following components from the Faststore UI: Button, Icon and SelectField.
  1. Create a file named index.tsx inside the components folder, and add the following code:
src/components/index.tsx

_10
import OurStores from './OurStores'
_10
_10
export default { OurStores }

  1. Repeat the steps in Step 3: Synchronizing the new section with the Headless CMS, and you should see the new section but without styles as in the example below:
{"base64":"  ","img":{"width":1144,"height":175,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":24240,"url":"https://vtexhelp.vtexassets.com/assets/docs/src/section-structure-without-styles___7be40088d6137bdd63cbb4940c2fa599.png"}}
To add styles to OurStore, refer to the following section Importing styles when creating a new section.

Adding styles to a new section

After creating a new section, you can style it to match your store's branding. Follow the steps below using the OurStores section as an example.

Instructions

  1. In your store code, open the components folder and create a .module.scss file for your component. For example, if your component is OurStores, name the file ourStores.module.scss. This file will contain the styles specific to this section.
  2. Import the necessary FastStore UI styles into your .module.scss file. For example, to style the OurStores component, we imported the styles for the Button and SelectField components. The Select styles are also imported since SelectField inherits them.

_10
.ourStores {
_10
@import '@faststore/ui/src/components/atoms/Button/styles.scss';
_10
@import '@faststore/ui/src/components/atoms/Select/styles.scss';
_10
@import '@faststore/ui/src/components/molecules/SelectField/styles.scss';
_10
}

  1. Open the component's .tsx file. For example, OurStores.tsx.
  2. Import the newly created stylesheet into the component:

_54
import React from 'react'
_54
import { Button, Icon, SelectField } from '@faststore/ui'
_54
_54
import styles from './ourStores.module.scss' ```
_54
_54
5. Apply the styles to your components using `className={styles.<className>}`. Replace `<className>` with the appropriate class name defined in your stylesheet. For example:
_54
```tsx mark=13
_54
import React from 'react'
_54
import { Button, Icon, SelectField } from '@faststore/ui'
_54
_54
import styles from './ourStores.module.scss'
_54
_54
export interface OurStoresProps {
_54
title: string
_54
description: string
_54
}
_54
_54
export default function OurStores(props: OurStoresProps) {
_54
return (
_54
<section className={styles.ourStores}>
_54
<h2>{props.title}</h2>
_54
<p>{props.description}</p>
_54
<div>
_54
<SelectField
_54
id="select-state-store"
_54
label="State:"
_54
options={{
_54
newYork: 'New York',
_54
arizona: 'Arizona',
_54
massachusetts: 'Massachusetts',
_54
hawaii: 'Hawaii',
_54
}}
_54
/>
_54
<SelectField
_54
id="select-city-store"
_54
label="City:"
_54
options={{
_54
newYorkCity: 'New York City',
_54
phoenix: 'Phoenix',
_54
boston: 'Boston',
_54
honolulu: 'Honolulu',
_54
}}
_54
/>
_54
<Button
_54
variant="secondary"
_54
icon={<Icon name="ArrowRight" />}
_54
iconPosition="right"
_54
>
_54
Find Store
_54
</Button>
_54
</div>
_54
</section>
_54
)
_54
}

  1. Open the terminal and run yarn dev to see your changes.
{"base64":"  ","img":{"width":2552,"height":946,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":135138,"url":"https://vtexhelp.vtexassets.com/assets/docs/src/without-styles___4680d2a9a67e4175f3b73eff036ca8ac.png"}}
  1. Add more styles to the section by using design tokens and component-specific data attributes to the .module.scss file:

_42
.ourStores {
_42
@import '@faststore/ui/src/components/atoms/Button/styles.scss';
_42
@import '@faststore/ui/src/components/atoms/Select/styles.scss';
_42
@import '@faststore/ui/src/components/molecules/SelectField/styles.scss';
_42
_42
width: 100%;
_42
display: flex;
_42
flex-direction: column;
_42
justify-content: center;
_42
align-items: center;
_42
padding: var(--fs-spacing-5);
_42
margin: auto;
_42
background-color: var(--fs-color-neutral-bkg);
_42
_42
[data-fs-select-field] {
_42
flex-direction: column;
_42
align-items: flex-start;
_42
_42
[data-fs-select] {
_42
border: var(--fs-border-width) solid var(--fs-border-color);
_42
margin-top: var(--fs-spacing-0);
_42
width: 10rem;
_42
height: var(--fs-control-min-height);
_42
_42
select {
_42
width: 100%;
_42
}
_42
}
_42
}
_42
}
_42
_42
.ourStores__title {
_42
font-size: var(--fs-text-size-title-section);
_42
margin-bottom: var(--fs-spacing-1);
_42
}
_42
_42
.ourStores__content {
_42
display: flex;
_42
align-items: flex-end;
_42
column-gap: var(--fs-spacing-5);
_42
margin: var(--fs-spacing-5);
_42
}

  1. Update the component's file by adding the appropriate CSS classes to elements, ensuring they align with the newly defined styles in your stylesheet. For example:

_47
import React from 'react'
_47
import { Button, Icon, SelectField } from '@faststore/ui'
_47
_47
import styles from './ourStores.module.scss'
_47
_47
export interface OurStoresProps {
_47
title: string
_47
description: string
_47
}
_47
_47
export default function OurStores(props: OurStoresProps) {
_47
return (
_47
<section className={styles.ourStores}>
_47
<h2 className={styles.ourStores__title}>{props.title}</h2>
_47
<p>{props.description}</p>
_47
<div className={styles.ourStores__content}>
_47
<SelectField
_47
id="select-state-store"
_47
label="State:"
_47
options={{
_47
newYork: 'New York',
_47
arizona: 'Arizona',
_47
massachusetts: 'Massachusetts',
_47
hawaii: 'Hawaii',
_47
}}
_47
/>
_47
<SelectField
_47
id="select-city-store"
_47
label="City:"
_47
options={{
_47
newYorkCity: 'New York City',
_47
phoenix: 'Phoenix',
_47
boston: 'Boston',
_47
honolulu: 'Honolulu',
_47
}}
_47
/>
_47
<Button
_47
variant="secondary"
_47
icon={<Icon name="ArrowRight" />}
_47
iconPosition="right"
_47
>
_47
Find Store
_47
</Button>
_47
</div>
_47
</section>
_47
)
_47
}

  1. Navigate to http://localhost:3000 in your browser to see the updated component with the applied styles.
{"base64":"  ","img":{"width":2552,"height":946,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":129326,"url":"https://vtexhelp.vtexassets.com/assets/docs/src/with-styles___4b1cd40d4dcbbba544fd051b1f2dcb36.png"}}
Contributors
2
Photo of the contributor
Photo of the contributor
+ 2 contributors
Was this helpful?
Yes
No
Suggest Edits (GitHub)
Contributors
2
Photo of the contributor
Photo of the contributor
+ 2 contributors
On this page