Documentation
Feedback
Guides
API Reference

Guides
Guides

Getting started with Checkout extensions

Understand the structure of a Checkout extensions project and build your first extension.

This feature is only available for stores using B2B Buyer Portal, which is currently available to selected accounts.

After you have a Checkout extensions project in your monorepo, you can create your first extension. When you create the project, a sample extension is already set up for you. To understand how it works, this guide walks through the files inside the project folder and then builds a new extension.

Before starting, make sure you have set up Buyer Portal Checkout.

Understanding the project

Entry point

The src/index.tsx file, located at the root of your project, is the entry point for all extensions created for Checkout. Upon project creation, this file contains the following structure:


_10
// src/index.tsx
_10
import { defineExtensions } from '@vtex/checkout';
_10
import { HelloWorld } from './HelloWorld';
_10
_10
export default defineExtensions({
_10
'cart.cart-list.after': HelloWorld,
_10
});

Consider the following key aspects of this file:

ElementDescription
defineExtensions functionAssociates the extensions you create with their target extension points.
Extension filesExtensions may be defined in separate files and imported into index.tsx.
defineExtensions functionRequired for extensions to function correctly. It also provides type-checking and autocomplete, which help you identify the available extension points.
@vtex/checkout packageInstalled in your monorepo during the setup process, it provides the resources required to build extensions, including hooks, types, and functions.

For the full list of available extension points, see Checkout extension points.

The extension

Upon project creation, a sample extension is provided in the src/HelloWorld.tsx file. This sample extension consists of two files: a TypeScript file for the implementation and a CSS file for styling. Implementation and style files may be organized as preferred, either as multiple files or combined into a single file.

A stylesheet isn't required for every extension. This structure is provided only as an example.


_13
// src/HelloWorld.tsx
_13
import { useState } from 'react';
_13
import './hello-world.css';
_13
_13
export const HelloWorld = () => {
_13
const [count, setCount] = useState(0);
_13
_13
return (
_13
<button className="hello-world-btn" onClick={() => setCount(count + 1)}>
_13
Count: {count}
_13
</button>
_13
);
_13
};

Consider the following key aspects of this example:

  1. Extensions are React components and may use any React feature, such as the useEffect or useState hooks, as in any other React application.
  2. Extensions may import CSS files, making the defined classes globally accessible.

Creating your first extension

With an understanding of the essential parts of an extension and the project structure, you can create your first extension. This guide uses the example created in the Setting up Buyer Portal Checkout step, with the sample folders and accounts. Replace the account and folder names, such as store-a, with your own to ensure the extension works as expected.

1. Running the Checkout extensions project

Before starting the implementation, set up the development environment by running the dev command from the FastStore CLI:


_10
yarn fsp dev store-a


_10
npx fsp dev store-a

The store's URL is returned as output in your terminal, and Checkout becomes accessible at the /checkout/cart path.

2. Creating the component

Because extensions in FastStore are React components, one approach to creating an extension is to define its implementation in a TypeScript file. To create a custom footer for Checkout, add the following content to a new src/CustomFooter.tsx file:


_10
// src/CustomFooter.tsx
_10
export const CustomFooter = () => {
_10
return (
_10
<footer>
_10
<p>© 2024 Store A Inc. All Rights Reserved.</p>
_10
</footer>
_10
);
_10
};

Next, connect the extension to an extension point by modifying the src/index.tsx file:


_10
// src/index.tsx
_10
import { defineExtensions } from '@vtex/checkout';
_10
import { HelloWorld } from './HelloWorld';
_10
import { CustomFooter } from './CustomFooter';
_10
_10
export default defineExtensions({
_10
'cart.cart-list.after': HelloWorld,
_10
'layout.footer': CustomFooter,
_10
});

After saving the file, open the browser with the storefront running. The extension is rendered at the bottom of the cart page.

To add the Checkout logo to the footer component, use the useSettings hook provided by the @vtex/checkout package in the src/CustomFooter.tsx file:


_13
// src/CustomFooter.tsx
_13
import { useSettings } from '@vtex/checkout';
_13
_13
export const CustomFooter = () => {
_13
const { branding } = useSettings();
_13
_13
return (
_13
<footer>
_13
<img width={72} src={branding.logo} />
_13
<p>© 2024 Store A Inc. All Rights Reserved.</p>
_13
</footer>
_13
);
_13
};

The useSettings hook provides other Checkout configurations as well.

4. Styling with CSS

To style the CustomFooter component, create a .css file in the same folder as the component, src/:


_10
/* src/footer.css */
_10
.custom-footer {
_10
width: 100%;
_10
display: flex;
_10
justify-content: space-between;
_10
align-items: center;
_10
background: #000;
_10
padding: 16px;
_10
color: #fafafa;
_10
}

Apply the CSS class to the CustomFooter component:


_14
// src/CustomFooter.tsx
_14
import { useSettings } from '@vtex/checkout';
_14
import './footer.css';
_14
_14
export const CustomFooter = () => {
_14
const { branding } = useSettings();
_14
_14
return (
_14
<footer className="custom-footer">
_14
<img width={200} src={branding.logo} />
_14
<p>© 2024 Store A Inc. All Rights Reserved.</p>
_14
</footer>
_14
);
_14
};

With the application open in the browser, the result is your first Checkout extension.

For more ways to style your extensions, see Using CSS in Checkout extensions.

Contributors
1
Photo of the contributor
Was this helpful?
Yes
No
Suggest Edits (GitHub)
Contributors
1
Photo of the contributor
Was this helpful?
Suggest edits (GitHub)
On this page