- Introduction
- Best practices
- Data structure
- Error Log
- Uploaded_Image
- User
- Conversation (chat)
- Messages (chat)
- Notification
- Place
- Styles
- Pages
- Index (main app page)
- Elements
- Conditional and Backend Workflows (Workflows not triggered by element clicks)
- Manging the iOS status bar
- Use of fontawesome icons
- Managing different screen heights
- 1. Spacer groups
- 2. CSS
- Group level
- Page body
- Converting your bubble app to a hybrid iOS or Android app and submitting it to the app stores
- Backend workflows
- Contact
Introduction
Mobile UI Starter Pack is a building block template library for mobile-first development / native app development on Bubble. The template aims at being a starting point and provide all you need to develop your next native or hybrid mobile app.
This is a one-page template that uses custom states to show and hide elements.
Features
- Welcome screen, signup / login
- App navigation bar
- Onboarding flow
- Dark mode
- Swipe to delete workflows
- Native share (bubble plugin)
- Various components ('building blocks') incl. controls, inputs, groups, etc.
- Predefined styles
- Chat function
- Settings page
- and much more
Best practices
- Use the 'Elements tree' in the Bubble editor to access groups and elements(make sure the ‘Only show hideable’ is unchecked):
From there, you can select an element and then check the ‘Conditional’ tab to see when an element is visible:
- Use copy & past with workflows for copying predefined elements when ever possible
- Avoid setting the layout of individual elements when ever possible and use predefined styles instead. This makes adjusting an app much easier once it gets complex. You can either
- Use 'Edit style' and edit the style for all elements that use it:
- or apply conditions on the respective element (i.e. use a condition that is always true, e.g. when index is visible, then text alignment is center):
Data structure
Error Log
This data type is used to record workflow errors. The custom workflow 'When an unhandled error occurs' automatically creates a thing of this type if an unhandled error occurs anywhere on the page. This is especially useful if you are working with APIs.
Uploaded_Image
This is used for the image gallery
User
The data type user contains the following custom fields:
- active day (List of dates): Every time the page is loaded, the current date is added to the list. This can be used to track how active your users are. This is simply included as best practice - the template makes no use of this data field.
- Dark mode on (yes / no): This tracks whether the user the user views the page in normal or dark mode. The dark mode conditions are referring to this entry (not the toggles used to turn the dark mode on or off).
- auto darkmode detection: if yes, the app will detect if the device is on dark mode on page load and set the darkmode accordingly.
- favorite images (List of Uploaded_Images): An image is added to the list if the user selects it as a favorite by clicking the heart icon on an image in the image gallery.
- is_admin (yes / no): This can be used to manage user rights (e.g. only make certain elements visible to admins). This is simply included as best practice - the template makes no use of this data field.
- profile image: a users profile image
Conversation (chat)
This data type is used for the chat function. It has data fields for:
- the users associated with a chat conversation
- users that have unread messages in this conversation
Messages (chat)
This data type is used for the chat function. It has data fields for:
- the conversation the message belongs to
- the message itself
- a file, if a file was sent instead of a text
Notification
This data type is used to show notifications to the user
- notification text: the notification text
- unread by (user): add users here when you want to show them the 'new notification' indicator (small red dot)
- related user: Add if the notification relates to an other user
Place
This data type is used for displaying places (e.g. restaurants etc.) on a map (google pam
- Name, Description, Picture: Place specific data
- Address: The address, using the geo address format (https://stackoverflow.com/questions/7764244/correct-address-format-to-get-the-most-accurate-results-from-google-geocoding-ap#:~:text=The maps autocompletion API from,lead to one exact result.)
- The map controls are hidden using the CSS code in HTML map controls and adding a CSS class to the map {addClass: "dynamic-height"}
Styles
Most elements in the template use predefined styles. The number of different styles is intentionally kept as small as possible, so it is easier to manage (e.g. if you want to change the font types).
Please note: most 'text' styles are per default aligned to top and left. To avoid adding additional styles for center aligned texts, the template uses conditions on the respective text elements (i.e. use a condition that is always true, e.g. when this element is visible, then text alignment is center). Example:
Pages
The template consist of four main pages:
- index: This is the main page of the app that hosts all the building blocks
- terms: this is an empty placeholder page for your terms of use
- privacy: this is an empty placeholder page for your privacy policy
404 and reset_pw are additional system pages.
Index (main app page)
Elements
Main views
The template built on one page ('index'), using custom states to show and hide elements. The bottom bar ('FloatingGroup Buttons') is used to navigate through the different main views (i.e. the main groups) of the app. The main "views" are:
- View 2: Home: Once the page is loaded (and the user is logged in), this view is visible
- View 3: UX Components: This view contains three additional sub-views, controlled by 'Group tabs':
- Group Controls
- Group Typography
- Group RepeatingGroups
- View 4: chat: A fully functional chat (see below)
- View 5: Picture Gallery: This view provides two options for a picture gallery, incl. workflows for view an image in full size, adding and removing an image to the user's favorites and deleting an image.
- View 6: Settings: This view provided UI elements to build your settings page.
these subviews provide various UI elements you can use to build your application.
Sign-up, login and onboarding views
The login and sign-up workflows, and the onboarding flow are built around two additional views:
- View 0: Splash screen: can be shown during page load to present your logo
- View 1: Landing + Floating Group Login: The two groups together build the 'landing' page, i.e. the first view a users sees when the page is loaded (and the user is not logged in)
- Floating Group Login: This group contains two sub-groups:
- Group Login: Signup: Provides sign-up elements and workflows
- Group Login: Login: Provides login elements and workflows
- View 7 :Onboarding: This is a 5-step onboarding flow you can use to onboard your users
- View 8: Paywall: An exemplary paywall to offer in-app subscriptions in a native app, e.g. using the BDK plugin and service (or offering stripe subscriptions in a web app). Please note, this paywall does not offer any in-app subscription functionality as such, it is only a potential way implementing the UI.
View 4: chat
This is a simple implementation of a whatsapp like chat to send text or files between users. It uses various elements:
- Group chat - the main chat window
- FloatingGroup Navbar chat - used to navigate in the chat
- FloatingGroup chat input - used to type new messages
- Popup start a new chat - used to start new conversations with other users
View 10: maps and places (+ FloatingGroup places)
- An example of how you can display and search for places on a google map using geographic addresses.
- FloatingGroup places: Searches places and shows in repeating group. IF SearchBox places has a value, the data source (→ condition) is a search for places within 30km of the selected location
- if a marker is clicked on the map, the RG is scrolled to the respective entry
- if an entry is clicked in the RG, the map zooms in on the marker
View 9: Kanban board
This is a simple example for a drag&drop Kanban board (like Trello)
- The data types associated are:
- kanbanList: A list that holds cards. this could be for example 'open ToDos' or 'done ToDos'. A list only has one data field 'List name'
- KanbanCard: The KanbanCards can be dragged and dropped between the lists. These are Cards within lists with multiple data fields:
- Card Name
- Description text
- fa icon: An icon that is displayed on the card
- parent list: The list in which the card currently is (this changes when the card is dragged&dropped to another list)
- The Kanban board consists of two nested repeating groups:
- Parent: RepeatingGroup kanbanList: searches for all lists
- Child: RepeatingGroup kanbanCard: searches for all cards associated to current cell's list
- The drag&drop function is achieved using the 'Draggable Elements' plugin.
- DropArea kanbanList (a DropArea from the plugin) in the RepeatingGroup kanbanList
- Drag/dropGroup kanbanCard (a Drag/dropGroup from the plugin) in the RepeatingGroup kanbanCard (this is essentially the card that can be dragged and dropped between lists)
- associated workflow that is triggered when the dropGroup (in the RepeatingGroup kanbanCard) is dropped on the DropArea (in the )
Using the following elements:
Other elements are:
- FloatingGroup Buttons: The main app navigation bar on the bottom of the app
- FloatingGroup Notification banner: This mimics a native notification banner. The notification can be shown using the 'trigger custom workflow' function to trigger the custom workflow 'Show notification banner' and provide a text (message) as workflow thing.
- GroupFocus notifications: shows user notifications
- FloatingGroup image detail: This element is used to show an image in full size
- FloatingGroup image filter: Used to filter the image galleries
- FloatingGroup overlay is visible when the image filter is visible
- Popup Forgot Password: Contains elements and workflows to reset the user password
- Popup Loading Screen: A predefined popup that can be used while the application is loading (e.g. include workflow steps to show the popup in the beginning of a workflow and hide it at the end of a workflow. In case of a workflow error, the Loading Screen is hidden automatically)
- Popup Alert: A predefined popup to interact with the user
- Popup Delete Image: Uses a copy Popup Alert to ask the user to confirm before deleting an image
- Popup about, Popup contents: popups used to explain the template
- FloatingGroup Picture uploader: Is used to add picture to the picture gallery
- FloatingGroup add to homescreen: This is a visual element prompting the user to add the app to their home screen for a better experience
- FloatingGroup places: Visible when View 10: maps and places is visible. Shows an RG of places
- Group Plugins and HTML
- HTML A: is used for some CSS code to manage the height of the landing page and other groups. Also provides CSS syles for popups
- HTML B - Body Background for status bar: dynamically set the body color of the website. This is useful if the app is added to the users home screen as a PWA on iOS with a transparent status bar (see status bar settings below)
- HTML RG Horizontal: contains code to hide the scroll bar on the RepeatingGroup Places
- CSS tools A: Used to get screen height to hide and collapse spacer elements
- FloatingGroup add to homescreen: this can be used to prompt the user to add the app to their homescreen to behave like a PWA (progressive web app)
Element | State | Usage | Used options |
---|---|---|---|
index | active | Determines which main view is visible. This state is set by the 'FloatingGroup Buttons'. This state is of type text. | landing, home, components, chat, gallery, settings, onboarding |
index | prev_active | Can be used to store the current state 'active' before changing 'active' to be used for back buttons (i.e. to return to the previous view). This state is of type text. This is not used in the template. | - |
Group Login | active | This determines whether the login or signup dialog is visible in 'Group Login'. This state is of type text. | login, signup |
View 3: UX Components | option | This determines which sub-view of the Group 'Group Tab 2 - UX Components' is visible. This state is of type text. | option1, option 2, option 3 |
Group Onboarding | active | This determines which step of the onboarding flow is visible. This state is of type number. | 1, 2, 3 |
FloatingGroup Notification banner | Notification | The text to be displayed in the notification banner. This is set by the workflow 'Show notification banner'. This state is of type text. | - |
Group Paywall | selected_offer | This is used to determine which subscription offer is currently selected by the user. This state is of type text. | monthly, annual |
RepeatingGroup Images 1 | filter | This is used to filter the image gallery (RepeatingGroup Images 1). This is set in 'GroupFocus filter 1'. This state is of type text. | favorites |
RepeatingGroup Images 2 | filter | This is used to filter the image gallery (RepeatingGroup Images 2). This is set in 'GroupFocus filter 2'. This state is of type text. | favorites |
Group chat | conversation | holds the current conversation. if the conversation is empty, the conversation overview (a list of all conversations the user has) is visible. if it has a value, the, the conversation itself (in the chat window) is visible | - |
Conditional and Backend Workflows (Workflows not triggered by element clicks)
Most workflows in the template are triggered when a specific element is clicked. Exceptions are:
- Page is loaded: Prepare the view when page is loaded.
- An unhandled error occurs: Removes the loading screen and creates a thing of type 'Error log' when an unhandled workflow error occurs (e.g. an API call returns an error).
- Show notification banner: Custom workflow to animate (show and hide) the notification banner.
- PictureUploader's value is changed: Creates a new thing of type 'Uploaded_Image' when the value of the picture uploader is changed (i.e. when an image is selected and uploaded).
- Do when PictureUploader is loading: shows the loading screen when the upload is started.
- Do when PictureUploader's value is empty and PictureUploader is visible: hides the loading screen after the upload after 'PictureUploader's value is changed' is done.
- Do when IonicToggle is changed: ionic toggles are like inputs. there are conditional workflows 'do when ionic toggle xx is changed'
Manging the iOS status bar
- The app can be added to to an iOS homescreen as PWA. In this case, we need to control how the status bar looks like:
There are 3 options:
- default: standard white status bar black text
- black-translucent: transparent status bar with white text (no idea why it's called 'black-translucent'). In this case the body color of the website is visible at scroll position 0. in the template this is controlled in the element 'HTML B - Body Background for status bar', dynamically adjusting for various conditions
- black: black status bar with white text
The template uses black translucent per default. Further reading:
Use of fontawesome icons
- The template makes use of fontawesome icons in various places incl. FloatingGroup Buttons and View 3: UX Components). Unlike normal bubble icons, these are loaded via an html text in an html element. This is a bit more complicated, but offers much greater flexibility, e.g. for adding color gradients.
- to replace the icon:
- find a free icon on https://fontawesome.com/icons?d=gallery&p=2&q=home&m=free
- replace the icon name, e.g.: fa-bell → fa-home
- You can further adjust the colors and size etc. in the HTML text
You can find a full walk through of how this works here:
Managing different screen heights
Optimising bubble apps for mobile screens with various heights is currently very difficult on Bubble. I
Check out my videos on optimising Bubble page heights for mobile screens:
Main one / fundamentals:
Advanced topics:
In the template this is achieved by the following:
1. Spacer groups
Today mobile phones vary greatly in screen height. Most elements in bubble are positioned using absolute positions. Therefore what looks good on a large screen will likely not look good on a smaller screen. In the template, this problem is solved using groups that are hidden and collapsed based on screen height:
you will find such adjustments on the landing page, the onboarding, the paywall and some other pages. It's always recommended to test your app on various screen sizes. This can be done e.g. using the Responsive Viewer Plugin in Chrome
2. CSS
Group level
Some groups (Splash screen, landing, onboarding, image detail) are set to be 100% of the screen height (→ full screen) using CSS code.
1) A CSS class 'dynamic-height' is added to the element using the classify plugin
2) The CSS class is changed set to full screen (height and width = 100% of the screen size). This code is stored in 'Group Plugins and HTML → HTML A. THIS SHOULD NOT BE DELETED
Page body
We also need to adjust the size of the page itself, to avoid this (i.e. the page being larger than the displayed group):
→ so the user cannot scroll below a group. this is especially relevant for screens with heights < 812px. this is a rather difficult thing to do in Bubble. in the template it is solved as follows:
add a conditions on the index. This resizes the whole page to the size of the screen in case the onboarding or landing or splash screen is visible. so the user cannot scroll below the group anymore. The workflow then sets it back to automatic height in case these groups are not visible, so the user can scroll again
In the onboarding, a further condition is applied to large screens to move the content a bit further down (center a bit more vertically) by adding padding to the top of the 'Group Onboarding Content':
Converting your bubble app to a hybrid iOS or Android app and submitting it to the app stores
- As of today, Bubble does not offer a direct way to do this. There are a few workarounds, however. The two best options we are aware of are:
- Option 1: free, but requires a bit of work, using https://jasonelle.com/:
- Option 2: much more advanced functionalities and comes with less work, but will cost you around 200-400 USD
Backend workflows
- In some cases it makes sense to move 'heavy' workflows or API calls to the backend, so the user don't has to wait for the workflow to finish. A common example is e.g. using an API call to compress an image after saving it.
Contact
Happy to answer your questions here: https://forum.bubble.io/t/new-template-new-mobile-app-starter-pack/87797