Tutorial | Set Up an App With the CLI
This tutorial demonstrates how to use the Wix CLI to build an app named Business Buddy. The app creates a chatbot connected to an AI that appears on a site owner’s dashboard. The AI answers questions about products in the site's store.
The app is built from:
- A front end consisting of two dashboard pages:
- Products: A page that allows the site owner to select a product from the site's store and chat with the AI about it.
- Settings: A page that allows the site owner to give instructions as to how the AI behaves.
- A backend consisting of the following:
- Server: An Express/Node.js server that responds to product chat requests by calling the OpenAI API and to settings requests by calling the mock database.
- Database: A mock database that holds the AI behavior settings for users.
The app demonstrates how to:
- Build dashboard pages using the Wix Design System, the Wix Dashboard React SDK, and CSS.
- Work with apps built by Wix such as Stores using the Wix Javascript SDK.
- Work with external services, such as OpenAI.
- Work with CORS on a server.
- Authenticate and handle requests sent from the Wix dashboard to a server.
Project steps
We'll use the following steps to build the Business Buddy app:
- Initialize the app.
- Create the dashboard pages.
- Run a local development server.
- Install dependencies.
- Design the Products page.
- Set up calls to Wix React SDKs.
- Set up communication with the backend.
- Design the Settings page.
- Prepare to receive backend requests.
- Build and deploy the app.
The end result will look like this:
You can see the finished app code in this GitHub repo.
If you want to run the app code from the repo you'll need to do some setup first.
Setup instructions
- Create an App ID
- Create a new app in the Wix Dev Center.
- Go to the app's dashboard and copy its App ID.
- Replace the value of the
appId
property in the wix.config.json file with the App ID from your new app. - Replace the value of the
wix.run
URL in the server.ts whitelist to use the App ID from your new app.
- Request permissions
- Go to your app's page in the Dev Center.
- Click Permissions in the left sidebar.
- Click Add Permissions.
- Enter Read Products in the Search by name or ID field.
- Check the permission scope's checkbox under Choose Permission Scopes.
- Click Save.
- Configure your OpenAI API key
- Create an OpenAI platform account.
- Create an OpenAI API key.
- In the backend project, create an environment variable named
OPENAI_API_KEY
and set its value to your API key.
- Configure your app secret
- Go the My Apps page in the Dev Center.
- Select your app from the list of apps.
- Click OAuth in the sidebar.
- Find, show, and copy your app's secret key.
- In the backend project, create an environment variable named
WIX_APP_SECRET
and set its value to your app secret.
- Optionally configure a port for your server (defaults to 8090)
- In the backend project, create an environment variable named
PORT
and set its value to your desired port number.
- In the backend project, create an environment variable named
Before you begin
Before getting started, make sure that:
- You install Node.js (v18.16.0 or higher).
- You’re logged into your Wix Developer account. If you don’t already have one, sign up for a Wix Developer account.
Step 1 | Initialize the app
We use the Wix CLI to initialize our app. In the process of initializing our app, the Wix CLI automatically:
- Creates a new app in the Wix Dev Center.
- Sets up a new folder for your app in your local file system. The folder includes:
- A
src
folder containing initial boilerplate code for an app with a dashboard page. - A
package.json
file containing your app dependencies.
- A
- Creates a local git repository for your app.
- Prompts you to set up a development site for testing your app.
To initialize the app:
-
Open a terminal and navigate to the folder where you want to create your app.
-
Run the following command:
Copy1If prompted, press y to install the package.
-
Select A new Wix App.
-
Enter a name for your app. Let’s name our app Business Buddy.
-
The CLI prompts you to choose a development site (test site), which you’ll use throughout this tutorial to run and test your app. You can choose an existing Wix site as your development site, or create a new one. Let’s Create a new Development Site. The newly created development site is automatically named something like Dev Site 5x2043, and can be found in your Wix account’s list of sites.
-
Follow the prompt to open the development site on your default browser. If the browser doesn’t open, install your app on your test site manually and skip the next step.
-
Click Agree & Add to install your app on your development site.
-
Back in the terminal, press Enter to select the default folder name (
business-buddy
) for your app in your local file system.
You now have a new app in the Dev Center, a new folder in your local file system, and a local git repository for developing and testing your app.
Step 2 | Create the dashboard pages
In the app, we want the dashboard pages to appear in the dashboard like this:
To create this structure, we use the CLI's generate
command to generate dashboard page extensions. This places dashboard page files in subfolders of the dashboard/pages folder.
Create dashboard page files
-
Run the following command and follow the prompts to create a dashboard page extension:
Copy1 -
When prompted for a page route, type product. The route is the path that is appended to the dashboard base URL to access the dashboard page. Learn more about page routes.
-
When prompted for a page name, enter Products.
Upon completion, the extension files will be created in your local app files under the chosen route with the following structure:
Copy1For more information about these files, see Dashboard Page Extension Files and Code.
Each dashboard page is defined by a page.json file and a page.tsx file. The page.json file defines the page metadata and the page.tsx file defines the page UI and functionality.
Each file pair exists in a folder that determines the route to a page.
-
Repeat the above steps but create a page with route settings, and page name Settings.
Step 3 | Run a local development server
Now that you’ve initialized the app, you can run a local development server to see the app in action, and view local changes as you develop it. The local development environment runs the app and its initial boilerplate code on the development site that you chose during app creation.
To run a local development server:
-
Run the following command:
Copy1 -
Press 1 to open the local environment in your browser. Your development site’s dashboard opens, and you can see your newly created app’s dashboard pages in the left sidebar. We add the content of our app’s dashboard pages in step 5.
Your app is now running on your development site. As you develop your app, any changes made to your app’s code are reflected in real time on your development site.
If your changes don’t show up, try refreshing the page, or closing and reopening the development site.
Step 4 | Install dependencies
Before we start coding our app, we need to install some npm packages. In your terminal, run the following commands:
1
The purpose of each of these packages will become clear as we progress.
Step 5 | Design the Products page
In our app, we want the Products page to look like this:
This design is consistent with the rest of the pages in the dashboard. To create it, we’ll use the React components provided by the Wix Design System.
The Products page is built from:
- Two main React components.
- One wrapper component for initializing React context providers.
- CSS styling.
The Products page UI is defined in several files in the dashboard folder as follows:
- /pages/products/page.tsx: The header and the top cell that it used for selecting the product to chat about.
- /pages/products/ProductChat.tsx: The bottom cell that displays the selected product and the chat.
- /pages/products/ProductChat.module.css: CSS for the ProductChat component.
- /withProviders.tsx: A
QueryClientProvider
andWixStyleReactProvider
wrapper.QueryClientProvider
allows fetching, caching, synchronizing, and updating server state.WixStyleReactProvider
provides styling according to Wix's design system.
Let's take a look at the code used to build the page's UI. We'll take a look at the code for the page's functionality a bit later.
page.tsx
Notice how the code uses components from the Wix Design System to build the page. Other than that, it's a standard React component. For more information about each component, see AutoComplete, Card, TableActionCell, Divider, Layout, and Page.
Note: At this point, we're showing the code with a hardcoded, dummy product object just to demonstrate how the page will look once a product is selected. We'll add real products to the page later in the tutorial.
1
ProductChat.tsx
Here again, the code uses Wix Design System components to build the component UI. For more information about each component, see Text, Box, Card, Input, and Loader.
1
ProductChat.module.css
We’ll use the following CSS to define the width of the input element for the ProducChat component:
1
withProviders.tsx
Finally, here is the code for the QueryClientProvider
wrapper. We use the withDashboard()
higher-order component from the Wix Dashboard React SDK to wrap this component. This will allow us to make Wix SDK calls from inside the component's code.
1
Step 6 | Set up calls to Wix React SDKs
In our app, on the Products page, users can choose a product from the site's Store.
To work with the Stores app on a user's site, we use the Wix Dashboard React SDK and the Wix React SDK. We already showed how to set up your dashboard page extensions with the Dashboard React SDK in the previous section. In this section, we'll use the React SDK to retrieve site data to display in the app.
Permissions
Before getting started making calls with the SDK, you need to request the proper permissions.
You can find out which permissions your app needs by checking the API reference for the functions you call. Our app queries store products, so it needs the Read Products permission.
You can add permissions to your app in the Dev Center by selecting your app and then selecting Permissions from the sidebar.
Get products
After setting up permissions, our app can retrieve a list of products from the site's store.
In your Products page code add the following imports:
1
These imports give us access to the Wix SDK overall and the particular functionality we need for retrieving products.
Once we import everything, we'll add the following hooks to our ProductsPage component:
-
We’ll use the
useWixModules()
hook to create an initialized copy of theproducts
module that we can use directly in our page extension code. We retrieve theproducts
module'squeryProducts()
function that we can use to access store products.Copy1 -
Next, we use the React
useQuery()
hook to query for products whose names start with a query string. This string will be set based on the product selected in ourAutoComplete
component. We also make sure to handle any errors.Copy1 -
Finally, let’s replace our dummy current product with the proper type now that we have it.
Copy1
Populate products
Now that we have access to a list of the site’s products, we can use them to populate the AutoComplete
component and define what happens when a user selects a product.
-
First, we set the
AutoComplete
component'sstatus
.Copy1 -
Then, we set the
AutoComplete
component'soptions
to the products we got from the query by mapping them to a list of options objects withid
andvalue
properties.Copy1 -
Next, we set up the
AutoComplete
component'sonSelect
function to set the component's current product.Copy1While we're at it, we also set the
AutoComplete
component'sonChange
function to set the search query and clear the current product.Copy1 -
Finally, we set the
AutoComplete
component'svalue
to the current product if there is one.Copy1
Step 7 | Set up communication with the backend
In our app, the Products and Settings dashboard pages will need to communicate with an app backend to work with the OpenAI API and to store user settings.
In general, you communicate with a backend server from a Wix App the same way you would in any other type of app.
You do, however, need to pay special attention to:
- Authenticate that requests to your server are coming from your app and not a malicious user.
- Differentiate between requests from the various instances of your app installed on different sites.
Later, we'll see how to do all that on the server. For now, let's focus on what we need to do on the front end.
Instance ID
Each time an app is installed on a site a unique instance ID is assigned. You can use the instance ID to authenticate requests sent from an app and to know which instance of the app is sending the request. The instance ID is added as a query param to your app’s dashboard pages.
Let's see how we add code to send requests to the server using the instance ID. In our app, we've placed this code in a file named utils.ts in the dashboard folder.
-
First, we create a function to get the instance ID from the page's URL.
Copy1 -
Next, we create a function to fetch data from the server using the instance ID to authorize the request. Notice how we call the
getAppInstance()
function described above to create the authorization header.Copy1import.meta.env.VITE_API_BASE_URL
accesses the environment variableVITE_API_BASE_URL
provided by Vite. So,${import.meta.env.VITE_API_BASE_URL}/${relativePath}
dynamically constructs a full URL by combining the base URL defined inVITE_API_BASE_URL
with therelativePath
passed to the function.
Fetching data
Now that we've set up the infrastructure to make secure requests to the server, we can use the ProductChat
component to send and receive chat messages.
To add backend requests to ProductChat, we do the following:
-
First, in ProductChat.tsx we import the utility function described above.
Copy1 -
Then, we add a function to submit messages, send them to the server, and update the state with the response. Notice how this function calls
fetchWithWixInstance()
to post a new message to the server.Copy1 -
Finally, we call
submitMessage()
when the send icon is clicked.Copy1And we call
submitMessage()
again when enter is pressed in theInput
component.Copy1
You can see the complete code for the Products page in our GitHub repo.
Step 8 | Design the Settings page
In our app, the Settings page is defined in the dashboard/pages/settings/page.tsx as follows:
1
As usual, the code uses Wix Design System components to build the component UI. For more information about each component, see Button, Card, FormField, InputArea, Loader, and Page.
react-query
In this code, we import useMutation
and useQuery
from react-query
:
-
useQuery
is used to fetch data from the server and handle caching. In the code below,useQuery
fetches the currentbehaviorDirective
from the server and stores it in data.Copy1 -
useMutation
is used to update data on the server. In the code below,useMutation
sends a newbehaviorDirective
to the server via a POST request:Copy1
Page component
This component renders a page where we can configure a behavior directive. It includes the following elements:
- Page Header: Displays the title "Behavior Settings".
- Card Component: Encapsulates the settings form.
- Card Header: Displays the title "Behavior Directive" and a "Save" button.
- Save Button: When clicked,
useMutation
sends the new directive to the server by callingmutation.mutate
. It shows a loader instead while the mutation is in progress.
- Save Button: When clicked,
- Card Subheader: Adds the subtitle "Give Business Buddy directives on how to answer your questions".
- Card Content: Contains a form field with the label "Directive".
- InputArea: A text area where users can input the behavior directive. It has a placeholder text, a character counter, and is resizable. The input value is managed by the
behaviorDirective
state.
- InputArea: A text area where users can input the behavior directive. It has a placeholder text, a character counter, and is resizable. The input value is managed by the
- Card Header: Displays the title "Behavior Directive" and a "Save" button.
Adding a toast
When a user changes the behavior setting on the Settings page, we want to show a toast at the top of the dashboard page.
To show toasts, update dashboard components based on state changes, and open and close dashboard modals, we use the Wix Dashboard React SDK.
-
First, we need to import the
useDashboard()
hook from the Dashboard React SDK.Copy1 -
Then, we need to call the
useDashboard()
hook in the code for the React component where we want to display the toast. We need to add the following to our Settings page component code:Copy1 -
Finally, we call the
showToast()
function and provide a message and type. In our app, we want to show the toast when a behavior setting has been successfully changed, so we callshowToast()
in theonSuccess
of the mutation used by the Save button.Copy1
Step 9 | Prepare to receive backend requests
In our app, the backend server must receive requests for chat messages, and for storing and retrieving settings values. Each of these operations must be performed by calling an endpoint exposed on the server.
In this implementation, we use a simple Express server. You're free to use any type of server for your app's backend.
When an app server receives a request to an endpoint, it needs to:
- Authenticate that the request is from your app and not a malicious user.
- Know which instance of your app has sent the request.
You'll also need to set up CORS to make sure your server allows the requests from your app.
CORS
To set up CORS properly, we need to add headers that allow access from certain origins and with certain HTTP methods.
In our case, we whitelist localhost for testing purposes and the URL for our app frontend on the Wix App CDN.
The URL of an app on the CDN is in the following format:
1
You can find your app's App ID on your app's dashboard in the Wix Dev Center.
This is how we whitelist the URLs on our server using Express:
1
Authentication
Now that we've dealt with CORS issues, the next thing to do is to authenticate the requests coming into our server.
To authenticate requests, we first need our app's secret key from the Dev Center. We get the key from the OAuth page in our app's dashboard. Then we add the key to an environment variable named WIX_APP_SECRET
.
Now that we have the key, we can write code to authorize the request. In our case, we write this code in a file on our server named utils.ts.
To add authentication logic, we do the following:
-
First, we create the
authorizeWixRequest()
function. This function reads the authorization header sent from our app frontend and checks it using theparseInstance()
function described below.Copy1 -
Next, we create the
parseInstance()
function to parse the received app instance and check it against our app's secret key using thevalidateInstance()
function described below.Copy1 -
Then we create the
validateInstance()
function to authenticate the instance against our app secret.Copy1 -
To use this authentication code, we call the
authorizeWixRequest()
function and pass it an incoming request. For example, when we receive a request for a product chat we authorize the request before continuing.Copy1
Multiple instances
In our app, the backend server must store settings data for each app instance. We use the instance ID to associate a particular setting value with a particular instance of our app. We can do this by storing the instance ID alongside each setting value in a simple key-value store.
The authorizeWixRequest()
function we created in the previous section returns the parsed instance information, including an instanceId
. We can pass that information to the key-value store when we process a request, such as a /settings
POST, as you can see here.
1
Then, in the key-value store, we can store the value of the instanceId
as the key and the setting text as the value.
1
Step 10 | Build and deploy the app
After testing your app and seeing that it works as expected, you can create a public preview of your app, build your app, create and manage app versions, and deploy your app. For more information on these tasks, see Build and Deploy an App with the CLI
Summary
After completing this tutorial, you have created a dashboard AI chatbot that integrates with a custom backend and Wix site data. At this point, you have all you need to know to develop an app. Feel free to play around with the example app some more, or get started on writing your own app.