In this tutorial you will create a marketplace app for:
- buyers to view all listings or search for specific items, explore a seller’s shop and buy an item with 1 click using their credit cards
- sellers to create seller accounts and create new listings
- you, the marketplace owner, to earn a commission on all transactions
The marketplace is fully contained in one page. We’re using a fairly traditional design. This page has a header to navigate the app through a search bar or through menu options but the focus of the app is listings which takes up most of the page. Clicking a listing shows detailed views for products and sellers so customers can learn more about a product of their choice and then purchase.
Let’s jump right into the components of this marketplace:
🗄️ Header with a:
- 🔍 Searchbar to find items quickly
- 📍Floating menu that you can use to navigate the entire app and your account
- 🏡 Logo to find home
🛍️ A page with all uploaded listings
👟 Product detail with Buy Now button
👩💻 Seller detail with their listings
📦 Data Structure
The core of any marketplace app is its listings which requires creating, saving and modifying data in the database so that it can be displayed on the page to customers and sellers. To do this, we need to create the data structure of the marketplace app, which helps represent what users save and modify. In our case, we need three fundamental types: User, Seller and Product.
The database in Bubble can be accessed through the app editor.
- We will see a Data tab to define custom data types and fields within.
- A User data type is already set up as users are key for any app and Bubble gives smart account management functionality.
- In our marketplace app, we will define 2 custom data types:
Seller: the Seller is to create a branded store with fields to track seller branded assets, contact details and listings sold by them. Seller fields include:
- Full name - defined as text to track seller’s name
- Description - defined as text for seller bio
- Profile Image - defined as image for seller image
- Listings - defined as list of Products to track their listings
- Payment Processor account / Stripe account - to track seller id
- User Account - to tie Seller to their personal User account
Product: which is the listings themselves. Product fields include:
- Title - defined as text for listing title
- Description - defined as text for detailed information on listing
- Category - defined as text for quick searches and organizing
- Price - defined as number to track listing’s price
- Seller - defined as seller to track who owns the listing
- Likes - defined as List of Users to track who liked this listing
Here is how you can do this in the Bubble’s interface.
We will cover saving and pulling things from the database in detail but to begin with, let’s discuss the page layout for designing our app with a special focus on the header which is used to navigate the app.
The Design tab is the main workspace to design our app in Bubble. We’re going to make the page responsive: on the index page which is the landing page for new visitors to our app, uncheck ‘Make this page fixed width’. At the top of the index page is the header to navigate the app with a search bar and floating menu.
How do we do we design the header?
- We add a floating group to the page which will remain visible at the top of the page at all times.
- We are using a plugin called ‘Ionic’ for sleek open source icons. We can use the pre-built icons as well. Select icons from visual elements and drop a left arrow icon on the top left of the page and a hamburger menu icon on the top right of the page.
- We add an input in the center page to let users perform searches.
- We combine all 3 into a single group centered horizontally and vertically in the floating group.
Once we have completed the design of the header, we want to display a dropdown menu that appears on clicking the hamburger icon. This gives a better user experience on phones where screen sizes are smaller.
- Add another floating group for a dropdown menu that shows on clicking the hamburger icon.
- Draw groups within each
- Insert a text elements within each group containing options for the dropdown
This ends up looking like this.
We will go into what these dropdown options do in a bit, but let’s look into populating the stars of this app - listings.
📦 Repeating Groups & populating data
Listing different items to buy takes us to the key part of our marketplace app: the gallery. We do this with an element called called the Repeating Group. This element is what you would use for a list of posts on Facebook, Apartments on Airbnb, etc. (if you think about it, a lot of the internet is about displaying lists…) With a repeating groups you can set the logic for what needs to be displayed for 1 listing and then it will automatically populate it for all listings.
To do this,
- We draw a large repeating group on the page to support 3 x 3 listings.
- We first have to decide the Content Type which defines the kind of data or type of things an element will display. The Content Type for the repeating group here is Product which is the data type for our listings.
- We then define which list will be displayed in run mode. In this simple case, we want to display all products. To do this, we define the data source as a search. We pick ‘Do a search’ and choose data type Product. And that’s it. In runmode, the list will be automatically populated. Bubble takes care of making sure your searches will work at scale, with the data structure you’ve defined above. Each app is different!
In this video, you can see how we draw the repeating group and define the data source as a search.
Next step is to define how each cell should look starting with the first cell. This step is important as it shows how you can display dynamic information from the database, for instance the price, the image and the description of each product.
- We add a group within the first cell on the top left. This group will contain all the relevant and formatted information for each listing’s preview.
- We set its data source to current cell’s product to match our data type where each cell corresponds to 1 Product database entry
- We set the group’s background style to Image so that the entire space is taken up by an eye-catching image of the listing. Now the image for each product will be dynamic, since it’s dependent on what users will upload. To do this, we can set the dynamic image to current cell’s product’s image’s first item.
- Let’s start by adding a button showing product’s price and format it to our currency. As we can see, we can add database queries to the page using intuitive language. Building the expression click-by-click, it become ‘Parent group’s product’s price’.
- To add a quick view blurb about the product, let’s create another group occupying bottom third of parent group containing product’s title, description and seller thumbnail. The last field is from 2 linked data types and that’s one of the coolest features in Bubble that as long as data is connected, we can easily string together Product and Seller types to construct product’s seller’s profile image. The expressions become, as you can see in the video, ‘Parent group’s seller’s profile_img’.
In this video, you can see how we populate the first cell as described above.
Click Preview on the top right and we will be able to see all the listings. Now that a user can scan through all that’s being sold on the marketplace and an item catches their interest, they will want to click on it. How will we show them more about the product they want to buy?
📦 Product detail: sending data to group
Our goal is to guide customers from the gallery view to another area of the screen that shows more information about a listing that caught their attention. We separate these 2 areas of the screen as customers can continue shopping or quickly click on different items in the gallery for comparison. We accomplish this with a workflow that starts when a user clicks on a cell in the repeating group. This workflow will show product details in the detail area. In Bubble terms, this workflow sends data for that cell’s listing to another group and then scrolls the page to that group’s location to make sure the user can see it.
- We can do this by clicking start/edit workflow on the largest group within the repeating group cell. This will take us to the Workflow tab.
- On the Workflow tab, we can add an action from element actions > group > display data.
- We want to display data in the separate group outside the repeating group which has space for more images and text regarding 1 listing.
- The design for this group can be a more detailed variation of the individual cells in the repeating group that pulls in more images of the product and most importantly, the Buy Now button.
- When our marketplace app has hundreds of listings, we want a user friendly way to guide the user to the relevant part of the page without them having to scroll manually. We do this with ‘scroll to’ action after display data to take the user from the gallery to the product detail group.
Now that the user is ready to buy the product they are viewing, let’s make it such that clicking the Buy Now button charges the user’s card!
📦 Building the buying logic: Buy Now button & plugins & email
In order to charge the user’s credit card for a listing, we use a payment processor like Stripe. Stripe handles the financial aspect of it, and Bubble lets you access its functionality via a Plugin. Let’s start by creating a Stripe account and get credentials from Stripe account developers dashboard which gives us the permission to integrate the payment service into our app. Back in Bubble app editor, let’s add a workflow on clicking the Buy Now button from the product detail group.
- In the Workflow tab, for an action, see payments - this doesn’t have any actions yet. We can get useful payment related actions by installing a plugin.
- Click ‘install more payment actions’. This will take us to the plugin tab where we can search for Stripe, the payment processor used in our marketplace app example. Click Install.
- Now back in Workflow tab under payments, we can select the first option ‘charge the current user’.
In the charging action, we will achieve 3 goals - charge the buyer, pay the seller and take a commision for the marketplace. Let’s walkthrough the setup for this ‘charge’ action.
- We will set Amount to ‘parent group’s product’s price’ and currency to our currency (USD here). Description and caption can be customized with similar dynamic expressions.
- Then select ‘the payee of this transaction is another user’. When setting up a marketplace, check this box so payment will go to another user instead of our own Stripe account.
- For the above option to work, we must build a flow where users can register as a seller, connecting their Stripe account to get paid. In the case of a marketplace, the person getting paid is the seller. This user must register as a seller for the transaction to process. For more on this action, checkout the official documentation here.
- In app fee, specify current listing’s price times a percentage to calculate our marketplace’s commission on the sold listing.
- Next, let’s add a confirmation email by choosing actions > email > send email and defining fields and text where the To is the current user buying the product from the listing.
We now have a functional marketplace (and we can make money with the commission!) Now how do we keep track of who is buying and who is selling? We do this by ensuring sellers create an account in the app to sell and buyers have the option of logging in but can also guest checkout like most eCommerce apps.
📦 Account detail: login/signup/forgot & page permissions
This section will cover how you can add account management to your app. Users will be able to sign up, login and log out.
Specifically, to be an official member of the app usually has 3 entry points for users.
- They can signup for an account
- They can login to an account they already created
- If they forgot the details of the account they created, they can kickoff a forget password request.
We set these 3 entry points in the same popup displayed to the user using a Bubble concept called custom states. Custom states are a way to save information on the page to use somewhere else without going through the database. Custom states are typically used to set the view of the page to match the intent of the user and deliver instantaneous experiences. Think of this like a Snapchat filter where the same camera view of you can have different filters added on top to give a unique experience. Let’s build these states and user interactions on the popup.
We want to design different views for users based on whether they want to login, signup or reset their password. Each view will show some common and some unique visuals. Let’s plot all possible elements on the popup across views and lay the foundation for defining views.
- Draw a popup on the page
- On the popup, draw 1 email input, 1 password input and 1 button
- Add 3 text elements near the button for signup, login and password reset
- Click the ‘inspect’ button for the popup and click ‘add a new custom state’
- Let’s call this custom state ‘view’ and define as text type
- Type ‘login’ as default value of the state so that the popup will first display the login view to all users until they click one of the other options
Now that we know the different possible elements that can be shown to users, let’s set the logic for defining different views
- When a user clicks on login text element, let’s add a workflow action under element actions > set state > that sets value of popup’s view to login.
- Repeat for other 2 options with their respective values - ‘signup’ and ‘forgot’
We have defined 3 views that can be shown to users. Let’s make the rules, called Conditions in Bubble, for how elements look and workflows behave in each view. These conditions enable us to show/hide elements based on a dynamic expression, or skip steps in a workflow if a condition isn’t met.
- For our Password caption and input, we add a condition that makes them invisible when popup state is ‘forgot’
- In our button, we set conditions for text that shows either ‘Login’, ‘Signup’ or ‘Reset’ based on the view.
- We will add 3 conditions based on popup state to show ‘Login’ if user wants to login and so on.
- Add 3 workflows for button click with distinct ‘only when’ conditions based on the custom state value. For example, button click with ‘login’ state triggers ‘log the user’ in action.
Now that a seller can create an account, how do they add their listings to the marketplace?
📦 Seller listings upload: form & create new thing action
Sellers upload their listings to the marketplace with another popup containing relevant fields that we already defined at the start of the tutorial.
- We can draw another popup for uploading listings and add inputs
- One input should be a Searchbox that allows us to set already defined options for the top searches by typical users.
- Another important input is picture uploader elements to add images for the listing.
- Finally add a ‘Done’ button that runs a workflow to update the database with the information added by the seller regarding this new listing.
Let’s do a deeper dive into this ‘Done’ button workflow
- The ‘create a new thing’ action in this case refers to a product that sends all that information to the Product data type in the database.
- We can then add 2 ‘make change to thing’ actions
- First adding the newly created product to the seller’s listings field to keep track of all listings created by a seller.
- Change the newly created Product’s image fields with all the images we have uploaded. We can break these into multiple steps with ‘only when’ conditions for when the respective uploader contains an image.
We are ready for primetime. Let’s deploy it to live by so you have a clean version that is exposed to users while you can continue adding fun finishes and features based on customer demand. To deploy, click on ‘development’ at the top right menu > deployment & version control > deploy development to live.
We now have a fully functional marketplace!
(Here’s our demo app)
📦 Easter egg: mode
As a challenge for you that brings together all the concepts we discussed above, can you figure out how to change the colors on the page using custom states and actions? Checkout the video for hints :)