Skip to content

Getting started

Now that you have a Sales App extensions project in your monorepo, let’s create your first extension. After creating the project, you’ll already have a sample extension set up. To better understand how it works, let’s go through the files inside the project folder step by step.

1. Entrypoint

The first file to take a look at is the src/index.tsx file located at the root of your project. This is the entry point for all extensions you’ll create for Sales App. When you create your project, it will look like this:

src/index.tsx
import { defineExtensions } from '@vtex/sales-app';
import { Example } from './components/Example';
export default defineExtensions({
'cart.cart-list.after': Example,
});

What we need to focus on here is:

  1. The defineExtensions function is responsible for linking the extensions you’ve created to the target extension point.
  2. You can create extensions in other files and import them into index.tsx.
  3. Using defineExtensions helps you understand which extension points are available through type-checking and autocomplete, but it’s also required for your extensions to work properly.
  4. The @vtex/sales-app package, installed in your monorepo during the setup process, provides everything you need to build your extension, including hooks, types, and functions.

2. The extension itself

When you create the project, you’ll find a sample extension in the src/components/Example.tsx file. This extension consists of two files: a TypeScript file for the implementation and a CSS file for styling. However, not every extension file requires a stylesheet—this is just an example of what’s possible. You can organize your style and implementation files however you prefer, creating multiple files or combining them into one.

src/components/Example.tsx
import React from "react";
import "./Example.css";
export const Example = () => {
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
alert("Discount applied!");
};
return (
<div className="container">
<h3>Rewards program</h3>
<form onSubmit={onSubmit} className="content">
<label htmlFor="phone">{"Enter the customer's phone number"}</label>
<input name="phone" placeholder="(99) 99999-9999" className="input" />
<button className="button" type="submit">
Apply
</button>
</form>
</div>
);
};

What we can take away from this example is:

  1. Extensions are simply React components, and they can use any React feature just like any other React application would, such as hooks like useEffect, useState, etc.
  2. Extensions can import CSS files, allowing you to include the created classes and make them globally accessible.

Creating your first extension

Now that you’re familiar with the essential parts of an extension and how the project structure works, let’s go ahead and create your first extension. For this, we’ll use the example created in the Setting Up step, with the sample folders and accounts. You’re probably using a different account name and folder name, so don’t forget to change these parameters to your specific names, like the folder name and store/account name, to ensure everything works as expected.

1. Running the Sales App extensions project

Before we start the implementation, let’s set up the development environment by running the dev command from the FastStore CLI:

Terminal window
yarn fsp dev store-a

With that, you should receive the store’s URL as output in your terminal, and the Sales App will be accessible at the /sales-app/checkout/cart path. When you open it, you should see the following screen:

Sales App UI with no customizations

2. Creating the component

As mentioned earlier, extensions in FastStore are simply React components. With that said, one way to create our first extension is by creating a TypeScript file with the implementation:

  • Directorystore-a/
    • Directorysales-app/
      • Directorysrc/
        • Directorycomponents/
          • Example.tsx
          • Example.css
          • CustomMessage.tsx
        • index.tsx
        • package.json

Let’s create a custom counter for Sales App. You can add the following content to CustomMessage.tsx:

src/components/CustomMessage.tsx
export const CustomMessage = () => {
return (
<p>
Extension example
</p>
)
}

Now, let’s connect this extension to an extension point by modifying our src/index.tsx file to the following:

src/index.tsx
import { defineExtensions } from '@vtex/sales-app';
import { Example } from './components/Example';
import { CustomMessage } from './components/CustomMessage';
export default defineExtensions({
'cart.cart-list.after': CustomMessage,
});

After that, save your file, open your browser with the Storefront running, and you should see the extension rendered at the bottom of the cart page:

Sales App UI with a simple custom message

3. Styling with CSS

Now, to style our CustomMessage, let’s create a .css file in the same folder where we placed our component, src/:

src/components/custom-message.css
.custom-message {
background: #000;
color: #fafafa;
padding: 16px;
}

Let’s apply our CSS class to the CustomMessage:

src/components/CustomMessage.tsx
import { useSettings } from "@vtex/sales-app"
import './custom-message.css'
export const CustomMessage = () => {
const { branding } = useSettings()
return (
<p className='custom-message'>
Extension example
</p>
)
}

Now, switch to your browser with the application open, and tada 🎉—you’ve done it! You just created your first extension for Sales App:

Sales App UI with a custom message