Planning a holiday can be an arduous task. With a plethora of options between flights, accommodation, and tours, it’s hard to know where to even begin.
Building software, on the other hand, shouldn't have be a strenuous process. Yet often, makers without web development experience need to outsource to expensive dev teams and wait months before shipping anything tangible.
With the rise of no-code tools like Bubble, however, makers from all backgrounds can start building their own software, all without writing a single line of code. Bubble’s powerful platform has made it easier than ever to get started on your development journey. Our customers use Bubble to build websites, directories, and even social networks.
Throughout this post, we’ll walk through the process of using Bubble to build your own no-code travel booking site, similar to Expedia or Skyscanner. We’ll share a step-by-step guide to building the underlying logic for your no-code Expedia MVP in just a matter of minutes.
For the sake of our MVP, we’ll focus on building a product specifically for booking flights. If you’d like to add additional support for hotels, rental cars, and tours, you can easily replicate the core framework to cater to your specific needs.
Before getting started, you’ll need a Bubble account (sign up here - it’s free). We also recommend completing our introductory lessons, which will guide you through the step-by-step process of the most common Bubble features. This will help you get a running start when building your Expedia clone.
We also recommend understanding how to create and edit user accounts, which we've covered in more detail in our previous How To guides.
When kickstarting your project, you can choose to begin by wireframing your product design, or building the necessary fields within your database.
In this case, we’ll start by using Bubble’s visual design tool to shape the user-interface of our product. When building your own travel booking platform, some of the core pages you’ll want to include are:
A major feature within Bubble is the ability to send data between pages. This allows you to create one generic version of a page, then dynamically display the relevant content from your database when it’s required.
In the case of your Expedia clone, you’ll only need to create one page to host your individual flights. We can then write the necessary logic to display only the relevant flight details on each page (we’ll cover this in more detail soon).
Once you’ve mapped out the display of your product, you can focus on creating the necessary data fields to power your application. We’ll rely on these fields to connect the workflows behind your product.
Bubble’s pre-built database makes it easy to create different data types with unique fields. When building the MVP for a flight booking platform, we’ll need to create the following data types & fields:
Data type: Flights
Data type: User
Now that you’ve structured both the design and database for your application, it’s time to start stitching everything together - making your product functional.
In Bubble, the main way to do this is with “workflows”. Each workflow happens when an “event” occurs (e.g. a user clicks on a button), and then runs a series of “actions” in response (e.g. “sign the user up”, “make a change to the database”, etc.)
When adding new flights to your platform, it’s possible to manually add new entries within your database. If you’re managing the platform between multiple admins, we’d recommend creating a dedicated portal to easily facilitate this process.
On the create flights page, you can start building this process by using a combination of input fields, including; free-text fields, image uploaders, dropdown selections, or multiple selection fields.
Once an admin has added the relevant details within each input, they’ll click the create button to trigger a new entry in your database. This button click will be the necessary action to create your workflow.
Using the workflow editor, you can select to create a new thing within your database. In this instance, we’ll be creating a new event.
You’ll then need to start adding data into the relevant fields within your database. Map each input field you’d like to create against its corresponding data field.
Once you’ve started adding flights to your platform, it’s time to start building the rest of the product that your users will interact with.
One of the core features of Expedia or any travel booking site is the ability for users to search for flights based on their specific requirements. This can include their departure location, destination, preferred dates of travel, and more.
On the home page, we’ll use an aggregation of different elements to support these search functions.
In the case of our MVP, we’ll start using the search box and date/time picker elements to map out our page UI.
You’ll then need to configure your search elements to only display items from your database that are relevant to each field. Take the time to configure the datasource to the flights within your database, then update the specific search field to include either the departure location or destination location.
By structuring these search fields, the element will now index all of the existing entries within your database and even offer search suggestions as they’re typed.
Once a user enters their desired flight parameters, we’ll need to display a list of all the relevant flights within our database.
Using Bubble, there’s a myriad of ways to do this - including using pop-up elements, or even redirecting users to a new page and sending relevant data.
For our MVP, we’ll just be adding a repeating group element below the search bar.
Repeating groups integrate with your database to display a list of dynamic content.
When using a repeating group, you’ll need to first link the element to a data type within your database. We’ll be classifying our repeating group from the flight data source.
By adding additional constraints to our data source, we can filter the repeating groups content to fetch only the relevant results based on each of your users search parameters.
You can also add additional constraints with your search and date fields.
Under the current constraints, our repeating group will dynamically update each time an elements field is changed.
If you’d like the grid to only fetch the relevant results once a user finishes filling in all of the search fields, we can select to hide this element on our page load. You can achieve this by unchecking the display element on page load configuration.
As this element will be hidden by default, it will only become visible once we create a workflow to facilitate this function.
As you may have guessed, this workflow will be based on the search button we added below our search fields.
Start by selecting the search button, then selecting to create/edit workflow.
Within your workflow editor, you’ll choose from the element actions, then show an element when the search button is clicked.
The element we’ll need to show is, of course, your repeating group.
Now your repeating group will only display the relevant results once a user submits their full query.
The last thing you’ll need to do is structure the dynamic content that will display within each grid. Simply map out the top column with the relevant content you’d like to show, then this powerful element will populate the remaining columns based on your existing data.
Within a repeating group, it’s also possible to create events based on each individual row.
This feature will become useful when building navigational features across your platform. As our repeating group only displays a topline view of each flights details, we’ll need to display the full list of information on a separate page once a user clicks-through.
This additional content will need to be hosted on your flight page.
To achieve this event, start by creating a workflow that redirects a user to your flight page when one of the elements within your repeating group cell is clicked.
When creating this workflow, use a navigation event to send a user to another page. From here, select the destination page to be the flight page.
You’ll then need to send additional data to this page so the Bubble editor knows which specific flight to display. The data you’ll need to send is that of the current cell’s flight.
Sending data between pages makes it simple to display only the relevant content that’s needed.
When sending data to a page, it’s important to configure your destination page type to match the data property that you’re sending within the workflow. In this case, you’ll need to set the flight page to a flight property.
By classifying the type of content of a page, Bubble can easily match data from sent sources.
You can now start adding dynamic content on your page to display information from a particular flight.
Using Bubble, it’s possible to harness the power of several plugins to easily accept payments and process orders.
In this guide, we’ll be using the Stripe.js plugin to process credit card payments through Stripe.
Note: After integrating this plugin, you’ll need to first configure your API keys within the plugin settings.
When accepting payments, you’ll need to build a checkout interface, allowing users to add their credit card details. For the sake of our MVP, we’ll be adding these relevant fields below the purchase button.
You’ll also need to include a Stripe token element next to the payment form. This element won’t be visible to your end-users, but is essential to powering a new transaction in Stripe.
When the purchase button is clicked, we’ll then create a new workflow that triggers a Stripe payment.
You’ll begin by selecting the event ‘convert card into Stripetoken A’. Within this event, you’ll need to configure your credit card input fields to match Stripes payment structure.
Once a card has been converted into a Stripe token, you’ll then need to create an additional workflow that automatically processes this token from a user's bank account.
When a stripe token for a bank account has been created, you’ll use the ‘Stripe.js - charge - create’ event to verify this token, as well as the final amount that will be paid (including the currency).
If you’d like additional guidance when building your payment processing workflow, you can watch a full tutorial in the video below.