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:
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:
- The
defineExtensions
function is responsible for linking the extensions you’ve created to the target extension point. - You can create extensions in other files and import them into
index.tsx
. - 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. - 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.
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:
- 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. - 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:
yarn fsp dev store-a
npx 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:
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
:
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:
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:
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/
:
.custom-message { background: #000; color: #fafafa; padding: 16px;}
Let’s apply our CSS class to the CustomMessage
:
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: