Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
You can create a Thunkable account with a Google account or with any other email address.
You can sign up with a Google account or an Apple account and sign in immediately, or you can enter your email address and to be sent a magic sign-in link.
We recommend using a Google or Apple account, as it will make testing your app a little easier.
If you choose to sign up with email, you will be sent an email like the image below.
Pressing the Click to Sign In button will open your new Thunkable account and keep you signed in for 30 days, unless you choose to sign out sooner.
You can Sign in with Google, Sign in with Apple or Sign in with email.
This button will sign you in automatically with your Google account.
This button will sign you in automatically with your Apple account.
If you click Sign in with email you will be invited to type your email address in a text input.
When you click Email me the link we will send you a link that will sign you back into your account.
To get started with Thunkable, visit our page.
Returning users can go directly to our page to sign back into their Thunkable account.
Preview and test your Thunkable project with the Thunkable Live app or Web Preview.
There are two ways to test and preview your Thunkable app: Web Preview in your computer's browser or on your mobile device with the Thunkable Live app. These tools aren't designed to check for errors, but to allow you to preview your app's design and test its functionality in real time.
You can test and preview your project directly within your browser. This is a great option when designing your app's user interface and building out the app's functionality with blocks.
You can also preview any public app, directly from the app's Project Detail Page.
The Thunkable Live app connects the projects in your web browser to your mobile device. It allows you to preview and test your projects directly on your device. Any changes you make in your browser are displayed on your device immediately. You can also take your project on the go and show it off with the Thunkable Live app.
Open your project in your web browser.
Click the Live Test on Device icon.
If you're signed in to Thunkable with Google:
Open the Thunkable Live app on your device.
Sign in with the same Google account.
If you're signed in to Thunkable with email:
Click Enter my code.
Open the Thunkable Live app on your device.
Click Email sign in - Generate test code.
A test code is displayed on your device screen. Enter it into the provided field on your web browser.
Click Connect.
Select the app you want to open from your list of Thunkable projects.
If you have added a navigator to your app, ensure screens are nested underneath it in the component tree. If your screens are not nested, drag and drop to nest them within the navigator.
Ensure your blocks are connected without errors.
Ensure you're logged into the same account on your web browser and the Thunkable Live app.
You have an event triggered by a Screen.Start which may be causing the screen to crash
Close the app and reopen it.
You may have the image's height or width set to Fit contents
. Try changing this and try again.
It is important to note, however, that Web Preview does not support some app features. This is because some app features require functionality only available on a mobile device, such as push notifications, accelerometer, and Bluetooth low energy. For a full list of features that cannot be tested with Web Preview, please see here: .
Links to download Thunkable Live on your mobile device are available here:
Links to download Thunkable Live for Android and iOS are available here:
If you don't have an iOS or Android device, you can also on your computer that mimics what you would see on an actual device.
The first thing you need to know as we welcome you to our Thunkable Docs is that we have two libraries of documents. One for each of the interfaces we currently offer:
Drag and Drop is our new platform interface that took our Creator's favorite features and functions from the previous interface (Snap to Place) and improved on them.
You'll know if you're looking for support with the Drag and Drog interface if your screen looks like this:
You're in the right place if you're looking for the Thunkable Docs supporting our Drag and Drop interface.
Snap to Place was our first foray into cross-platform app development. It is our old platform interface.
You'll know if you're looking for support with the Snap to Place interface if your screen looks like this:
In addition to our Thunkable Docs, we are also proud to offer you the following resources:
Contact our Support Team Creators on our Pro, Business, and Team plans can click the chat icon in the upper right of a Thunkable Project page to connect with our team.
You can get started building with Thunkable today for free. As you progress as a developer with Thunkable, we offer different membership tiers that allow you to build more and do more. This includes:
🖥️ Publishing web apps 💰 Showing AdMob ads in your app 🙈 Making private apps ⚡ Expedited publishing 📢 Adding push notifications to your app 📱 Creating a personalized splash screen and more!
The Thunkable Docs to support users of the Snap to Place interface are available here:
You can toggle between the Drag and Drop and Snap to Place docs in the upper left corner.
Not sure where to get started? Check out the Thunkable Academy!
Want to connect with other Thunkable Creators? Ask a question and join the conversation in the Community!
Enjoy instructional videos? Check out our library of tutorials available on YouTube.
Thunkable offers plans to suit individual and business needs.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
There are several different types of projects in Thunkable.
A project is where your designs, files, and blocks combine to create Android, iOS, and web apps.
Public projects are included in the Thunkable Public Gallery for anyone to preview, download or remix. If you create a public project, please know that it can be viewed by anyone in the Thunkable community.
Private projects are available to Creators on Pro+ plans. These projects are private, meaning they can only be seen by their app creator. They are not displayed in the Thunkable Public Gallery.
For Creators on Pro+ plans, you can decide whether a project is public or private when you create it.
You can only preview Read-Only. Once a project has been switched to public, you cannot switch it back to Read-Only.
Please note that your layout will not automatically respond when you change your Default App Layout. Your existing components will not change size, and the distance between components will not change. We recommend setting your Default App Layout before you start adding components to your app.
Learn more about our plans here:
You can also change the privacy setting of an existing app. Click the gear icon in the upper left to access your app's and use the switch to change the app's privacy settings.
Private projects become Read-Only projects when a Creator's expires. Read-Only projects remain private and are not included in the Thunkable Gallery.
By default, a Thunkable project is the size of a mobile phone in portrait mode. If you want to change this, you can do this by adjusting the default app layout in the Settings panel of your project. .
Follow these steps to build your first app!
You can sign up for Thunkable with Google, Apple, or email.
Check out our Signing In docs for more info:
Once you have followed a tutorial, test your project on the web to see it live.
View the homepage for all of your Thunkable creations. Choose how you want your projects to be laid out. Search and filter your projects.
Continue your journey by creating more projects.
You can drop custom components and third-party integrations directly into your projects. These components will allow you to build more advanced features.
The language of blocks is a visible programming language. By dragging and dropping blocks together, you can program your app.
Thunkable recommends and actively supports using a mobile OS that is actively receiving security updates.
This includes iOS 15+ and Android 10+.
Thunkable apps are often compatible with older OS, but this is not guaranteed.
Thunkable supports developing with the following browsers:
Mozilla Firefox
Google Chrome
Apple Safari
We recommend updating your browser regularly for the best experience.
Components to interact with
UI Components make up the visual aspect of your User Interface. Combine, style and customize Thunkable UI components to give your app personality and style that best suits your brand.
Every UI component has unique properties that you can use to customize it. You can find this at the top of the Properties panel. All UI components have a section called Layout and Style.
In the example above, a Label has been selected. Note its unique properties such as its text, font, alignment etc.
Once you’ve perfected a UI component on the Design tab of a drag and drop project, you can duplicate it using copy-and-paste keyboard shortcuts.
To copy and paste a component:
Click on a component name in the component tree (A) or the component within a screen in your workspace (B).
Type ctrl+c or command+c on Mac, and ctrl+c on PC, to copy the component.
Type ctrl+v or command+v on Mac, and ctrl+v on PC, to paste a duplicate of the component.
Click and drag the new component to position it as you desire.
Learn more about individual components below.
Once you have designed the UI you want, you can start adding functionality to your app with blocks and app features!
Note: Project versioning is currently being beta-tested.
Thunkable’s versioning functionality allows you to preserve a version of your drag and drop project at a point in time. Project versioning provides a better way to organize and manage multiple versions of your projects, allowing you to easily find past iterations and revert back to previous versions if you make changes to the original version that you end up disliking.
There are two forms of versioning available, auto-versioning and manual versioning, both of which are available to our Pro, Business, and Team Creators.
Never worry about losing your app progress with auto versioning. Thunkable automatically backs up your projects every few hours.
To access the two most recent auto versions of your project:
Access the Design tab of your project.
Each auto version’s name reflects the date and time the version was created.
Click the version’s vertical ellipsis to access its version actions.
The Restore option reverts your current project to this version.
To save a version of your project:
Access the Design tab of your project.
Click Create Version. A new version of the project is created with the default version name reflecting the date and time the version was created.
To change the name of a version, click in the version name field and type your preferred version name.
Click the version’s vertical ellipsis to access its version actions.
The Restore option reverts your current project to this version.
The Save As option saves that version as a new project. Select a name for your new project and then click Create. The newly created project is now available on your Projects Page, and the version will remain within the existing project.
The Delete option will permanently delete the selected version. This action can’t be undone.
If you downgrade your subscription plan, you will lose your oldest versions up to your new limit.
Creating a new version of a project makes a full copy of the project, including project settings such as name, project privacy, data, etc. Restoring a version will also restore those settings.
Check out our courses in to familiarize yourself with the platform and build your first app.
The Thunkable Live app lets you preview your apps directly on your personal devices. Links to download for Android and iOS are here:
If you don't have an iOS or Android device, you can on your computer that will display your apps.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
While the have their own section in these docs, they are visible components as you can view them on the screen. You can access the Data Viewer docs below:
Pro plans allow for 10 manual versions per project, and Business and Team plans allow for 50 versions per project. Overall storage limits remain the same and each saved version counts towards the account’s limit, meaning if a creator makes one version of a 50MB project they will be using 100MB of account storage. For more on plan limits please see here: .
Click the Version History clock icon in the upper right.
Click the Version History clock icon in the upper right.
To view or change your app settings, click on the Settings gear icon in the menu on the left.
Your app name is the name you choose for your app. It differs from the project name, which displays at the top of your project. While the project name is internal and may include details specific to your team, the app name is user-facing.
We recommend a short one or two word app name.
Avoid using the character "&" in your app name: at the moment, it prevents your app from being installed on your device
This is where you can change the default designer layout for your app. Use this dropdown to set the default size of your project, choosing from the following options:
Phone + Portrait
Phone + Landscape
Tablet + Portrait
Tablet + Landscape
We recommend setting your Default App Layout before you start adding components to your app. Your layout will not automatically respond when you change your Default App Layout. Your existing components will not change size, and the distance between components will not change.
We recommend choosing a Default App Layout before you start adding components to your screen(s).
Your app icon is the picture that represents your app on your mobile device. This icon will also appear on your listing in the Google Play Store or App Store, and as your project icon on Thunkable. Users on our personal plans will see the default "Made with Thunkable" icon appear when their apps load.
Please ensure the file you upload does not have the same name as another asset you use in your app. This will cause an error.
Size
192 x 192 px (minimum)
Shape
Square (equal height and width)
File Type
Preferably .png (vs. jpg or other file types)
To access your app's splash screen image settings:
Navigate to the project’s Design tab.
Click the Settings icon in the left menu.
Click the three dots icon at the bottom of the Project Settings section to access the advanced settings.
To customize your app’s splash screen picture:
Click in the Picture field.
Click Upload files and select an image from your computer, or select an image from your app’s current assets.
The picture must be square. Rectangle pictures will not render correctly.
The ideal dimensions for your splash screen picture are 1152x1152 pixels.
If you want a transparent background, a PNG file is recommended.
To customize the background color of your app’s splash screen:
Click in the Background Color field.
Use the color picker or input the HEX or RBGA codes to select your preferred color.
This should follow a pattern like com.domain.creatorname.appname
Make sure none of the segments of this package name begins with a number. Ensure none of the letters in this package name has an accent (e vs ë).
This property enables you to remove the Safe Area View which Thunkable adds to the app automatically. If you set this property to be true
, the screen background color will extend to full screen and there won’t be any white area. However, you need to manually take care of the notch in your app design, like adding extra space, in order to avoid the app element being blocked by the notch.
This property enables you to set the safe area view color. With this, you can customize the background color of the white area. Please note, this is an app level setting and you won’t be able to customize the color at the screen level.
When you add components that require permissions to your app, like the camera or map, you will need to add purpose strings to your app if you want to publish it to the App Store.
You must add purpose strings for any component that explicitly requires a purpose string.
This is a description of your app and how you intend it to be used. It is not necessary to fill this out in Thunkable. If you your app you will need to enter this information, whether on Thunkable or the App Store or Play Store.
The app name is the name that is displayed on the Google Play Store or Apple App Store, and that users see when they install your app on their device. This name is also used to set the page title when you publish as a .
Building an app in Tablet View is a Pro feature.
For publishing to the iOS , you will also need an app icon that does not have any transparency, or it may cause an error.
For publishing your app to the Play and App stores, you will need to create a separate icon with a higher resolution. For , the current requirement is 500 x 500 px. For the , it's 1024 x 1024 px.
A unique identifier for your app on the or .
PRO Thunkable users have the option to set their app to Private. A private app will not be displayed in the Thunkable Public Gallery.
When you publish to the or the , you will need to increment (increase) your version number each time. If this switch is set to true,
Thunkable will automatically increment your project's version number each time you publish your app (iOS) or download your app (Android).
Set a for this version of your Android app.
Set a for this version of your Android app.
Set a for this version of your iOS app.
If your app or any external service your app interacts with are gathering any kind of identifiable information, this must be explicitly disclosed to the end user of your app using an in-app prompt. If you do not include this and your app engages in tracking, Apple will reject your submission and ask you to resubmit while including an appropriate tracking string. To learn more about when to include a tracking string,
If your app uses , , , or requires users to , you can enter your personal API keys for these integrations in the app settings.
To learn more about the Firebase integration, please see here: .
To learn more about the Google Map integration, please see here: .
Enter the AdMob app ID for your iOS and/or Android app. To learn more, see here: .
Import and export an Android Keystore to/from your app. Learn more about the Android Keystore here: .
To learn more about the Cloudinary integration, please see here: .
Navigate and filter your projects
Thunkable lets you choose between viewing your projects in List View or Grid View.
You can decide whether to view your projects in List View or Grid View in the upper right corner of the page.
You can use the search bar to filter your projects by name.
When you click on the 3 dots on a project card (Grid View) or list item (List View), you can see some project options.
You can delete your project, duplicate your project, or see your Project detail page.
You can also view information about the project, such as its name, creator, project size, and how many times it has been remixed or favorited.
If the project is a remix of another project, the name and creator of the original project will be displayed on the left.
Creators with our Pro and Business subscriptions can set their app's default layout to tablet view.
The best practice is to set your project's default app layout before you add components to your app screens. If you add components to your app screens and then change your project's default app layout, your designs will not automatically respond to the new size and layout, meaning that neither the size of your existing components nor the distance between components will change.
To change your app's default app layout:
On the Design tab of your project, click the gear icon in the upper left corner to access your project settings.
Select the preferred default layout for your app. Your options are: - Phone + Portrait - Phone + Landscape - Tablet + Portrait - Tablet + Landscape
You can import a Figma file into your Thunkable project.
Click on the Assets tab and click the + icon next to the text Figma Files.
You will be asked to Authenticate with your Figma account. You will only need to do this once.
Paste in the URL of your Figma Project and select a Page in the dropdown menu.
The Figma importer will add all Artboards in a single page, so we recommend creating a designated Page in Figma with the Artboards you intend on importing.
Thunkable imports your Figma files in a way that best preserves your original designs.
The following Figma objects are supported by the integration:
Canvas
Component
Ellipse
Frame
Group
Instance
Line
Rectangle
Text
Vector
As you change and update your original designs, keep Thunkable up to date by re-syncing a Screen.
Find your imported Screen name in the Design tab and click the 🔄 icon.
All imported Figma items will have some standard blocks.
You can use these imported components as a button by adding a Click
block. You can also choose to change its background color, or add text or a picture, among other actions.
Upload and manage your files from the Assets pane
Each plan has a limited storage capacity.
You can view your total account storage size in your account settings.
Assets can be uploaded from multiple parts of Thunkable, however, with limited storage capacity, it's best to delete assets that aren't being used. To access your assets, click the Assets button on the left panel.
We recommend that each of your asset files not exceed 50KB -100KB. Using smaller file sizes in your project will result in faster loading times for your users.
We recommend using a consistent naming method for your assets. This will make it easier to manage them if you use many asset files in your project.
Here are two naming methods we recommend:
example_one.png
here_is_another_example.html
exampleOne.png
hereIsAnotherExample.html
Use only alphanumeric characters and underscores in your asset names. Avoid other special characters and whitespace characters (" ") in your file names as these can cause problems with your project.
You can manage your files directly in the Assets panel on the left, or click the plus icon next to the Media Files header to open the Media Files modal and manage them there.
Check the size of an individual project by visiting the project details page.
You can find your projects page at . This is the first page you see when you sign in.
are able to create . You can use the Public and Private checkboxes to filter your projects, showing only public projects or only private projects.
On the Project Detail page, you can test out your app, similar to when it has been published as a .
Your project will be shown in your chosen .
Building an app in tablet view is available for creators with our Pro and Business subscriptions. .
Shapes such as rectangle or a circle will be imported as a shape. You can continue to edit its style within Thunkable. Images and text will be imported as a png and saved like a normal that has been uploaded to Thunkable. We have done this intentionally to preserve the original font styles. If you want text to be editable, we recommend you replace that image with a Thunkable .
Use the Assets Panel to upload, rename and manage all of the assets you've uploaded to your project. You can also manage Figma files within this panel. To learn more about how to use the Figma upload feature, check it out .
- each space is replaced by an (_) character, and the first letter of each word written in lowercase.
- writing phrases without spaces or punctuation, indicating the separation of words with a single letter, and the first word starting with either case.
To check how much space you're using for all of your projects and assets, go to your .
200MB
500MB
1GB
Unlimited
App size
50 MB for Free and accounts.
The Simple List component allows you to add, view and click on items in a list.
You can customize the Simple List with the following properties:
Text Items
Set text items of Simple List
List of text items
Color
Set font color of Text Items
Color
Background Color (text items)
Set background color for the items in the Simple List
Color
Font Size
Set font size of Text Items
Number
Show Arrow
Toggle whether arrow is shown beside text items
True/False
Writing Direction (iOS and web app only)
Set writing direction of text items
Select from list [auto, ltr, rtl]
Background Color (container)
Set the background color of the Simple List container.
Color
X
Set the location of your Simple List on the X-axis in pixels
Number
Y
Set the location of your Simple List on the Y-axis in pixels
Number
Height
Set the Height of your Simple List in pixels
Number
Width
Set the Width of your Simple List in pixels
Number
Resize Mode
Define dimensions of the Simple List component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Simple List
True/False
Border Style
Set style of Simple List's border
Select from list [solid, dotted, dashed]
Border Color
Set color of Simple List's border
Color
Border Width
Set width of Simple List's border in pixels
Number
Border Radius
Set radius of corners for Simple List's border in pixels
Number
Shadow Color
Color of Simple List's shadow
Color
Shadow Opacity
Opacity of Simple List's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Simple List's shadow in pixels
Number
Shadow Offset
How far Simple List's shadow should be offset, in Height and Width, in pixels
Number
Note: The blocks in your project are titled "Simple_List." The blocks in the images below are titled "List_Viewer." The component was recently renamed and these images will be updated soon. Thank you for your patience.
Performs an action when the user clicks on an item of the Simple List.
Outputs
Item
Text of selected item
String
Index
Position of item in Simple List (starting with 1)
Number
Choosing Airtable or Google Sheets allows you to create a dynamic Simple List. This is where the information displayed to the user changes whenever you change your cloud-based data in Airtable or Google Sheets. Either of these options are ideal for when you need to store thousands of items, or you need to work with items that change frequently.
Performs an action when the user clicks on any one of the list items.
Set and get font color of the Simple List's text items.
Set and get background color of the Simple List's text items.
Set and get font size of the Simple List's text items.
Choose whether or not the arrow is displayed next to every item in the Simple List.
The Computed Height
block returns the height of the Simple Listin pixels after it has been rendered on-screen.
The Computed Width
block returns the width of the Simple List in pixels after it has been rendered on-screen.
Set and get the visibility of the Simple List.
Set and get of the Simple List.
Set the text items displayed in your Simple List. Works with blocks:
This block also works with blocks to retrieve columns from :
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
The text input allows the person using your app to type in anything that they want such as words, passwords or numbers.
Hint
The prompt text the user sees when the Text Input is empty (eg. Type Here
)
Text
Text
Text value of the Text Input
Text
Keyboard
Set a keyboard to sppear when your end user clicks the Text Input
Select from list [default, email address, numeric, phone pad]
Secure Text Entry
Toggle whether text is obscured as your end user types (suitable for entering passwords and other sensitive information)
True/False
Font
Text
Font Italic (web app only)
Select whether hint and text are shown in italics.
True/False
Underline (web app only)
Select whether the hint and text are underlined.
True/False
Strikethrough (web app only)
Apply strikethrough formatting to the hint and text.
True/False
Writing Direction (iOS and web app only)
Set whether text should be written left-to-right or right-to-left.
Select from icons.
Font Size
Height of hint and text in pixels.
Number
Letter Spacing
Spacing between letters in pixels.
Number
Editable
Toggle whether your end user can edit the text
True/False
Multiline
Toggle whether your end user can enter multiple lines of text
True/False
Auto Focus
Toggle whether Text Input is automatically in focus when the Screen opens
True/False
Max Length (Android and iOS only)
Set maximum number of lines of text your end user can enter
Number
Clear Button Mode (iOS only)
Toggle when your iOS end users have the option to clear the Text Input's text
Select from list [never, while-editing, unless-editing, always]
Input Color
Color of Text Input's Text
Color
Background Color
Color of Text Input's background
Color
Hint Text Color
Color of Text Input's hint
Color
Selection Color (Android and iOS only)
Set the color to highlight text when your end user selects text
Color
X
Set the location of your Text Input the X-axis in pixels
Number
Y
Set the location of your Text Input on the Y-axis in pixels
Number
Height
Set the Height of your Text Input in pixels
Number
Width
Set the Width of your Text Input in pixels
Number
Resize Mode
Define dimensions of the text input component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Text Input
True/False
Border Style
Style of Text Input's border
Select from list [solid, dotted, dashed]
Border Color
Color of Text Input's border
Color
Border Width
Width of Text Input's border in pixels
Number
Border Radius
Radius of corners of Text Input's border in pixels
Number
Shadow Color
Color of Text Input's shadow
Color
Shadow Opacity
Opacity of Text Input's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Text Input's shadow in pixels
Number
Shadow Offset
How far Text Input's shadow should be offset, in Height and Width, in pixels
Number
This event fires when the user clicks on the Text Input component.
This event fires when the component looses focus, i.e the user clicks on another component.
This event fires when the enter or submit button is pressed on the device keyboard.
This event fires every time a character is added or removed to the Text Input.
Returns the height of the Text Input component in pixels after it has been rendered on-screen.
Returns the width of the Text Input component in pixels after it has been rendered on-screen.
User interface (UI) components define your app’s look, while app features allow you to tap into a mobile device’s unique functionalities.
UI components are visual elements users can see or interact with. They include buttons, images, text inputs, etc. Thunkable offers more than 20 UI components to add to your app screens. Each of these components is fully customizable and controllable with blocks.
Each UI component you add to your app has an associated properties panel unique to that component. Using the various settings in the properties panel, you can style and customize your Thunkable UI components to give your app personality and style that best suits your brand.
A Label's properties panel is displayed on the right in the example below. Note its unique properties such as font, color, alignment, etc.
The component tree can be found at the top left corner of your project's Designer. The component tree contains a list of the UI components in your app. The expand and collapse arrows show or hide the nested UI components.
Once you’ve perfected a UI component on the Design tab of a drag and drop project, you can duplicate it using copy-and-paste keyboard shortcuts.
To copy and paste a component:
Click on a component name in the component tree (A) or the component within a screen in your workspace (B).
Type ctrl+c or command+c on Mac, and ctrl+c on PC, to copy the component.
Type ctrl+v or command+v on Mac, and ctrl+v on PC, to paste a duplicate of the component.
Click and drag the new component to position it as you desire.
Thunkable’s app features are easy-to-integrate and drastically expand your app’s native mobile functionality. They often relate to your app's functionality and quietly run in the background.
App features are accessed from your project's Blocks tab.
The image component lets you display pictures in your app.
With the Resize Mode property, you can do the following:
Center: Positions the picture in the middle of the image component
Cover: Resizes the picture to its max height or width regardless without changing the image quality.
Contain: Resizes the picture to fit the area without changing its quality
Repeat: Repeats the picture at its original quality within the image component area
Stretch: The picture’s height will change to fill the image component length-wise
This event handler is fired when the user clicks on the image.
Set and get the Image component's Picture.
Returns the height of the Image component in pixels after it has been rendered on-screen.
Returns the width of the Image component in pixels after it has been rendered on-screen.
Set and get whether the Image component is visible on the screen.
When you tap on the play icon to hear your favourite music, you are using a button.
A button is just something you can click on to perform an action. This action can be anything from navigating to a different screen, saving information to a database, or playing a sound.
You can use the following blocks to listen for when a specific event occurs
Performs an action when the user taps the button.
Performs an action when the user holds down the button.
Performs an action when a user pressed down on the button
Performs an action after the user releases the button
The set and get resize mode blocks work with how the background picture is scaled within the button component. Acceptable values are:
Cover
Contain
Stretch
Repeat
Center
The disabled property is used to set whether or not the button is "clickable". Expected values for this property are:
True
False
The font style properties of the button text can be "Bold", "Italic", or Raised. Expected values for each property are:
True
False
The get and set font size blocks are used to work with the size of the text that is displayed in the button. This value must be a number.
The set and get height blocks work with the Height property of the button component. Acceptable input values are.
Number of Pixels
Percentage Height
"Fit Contents"
"Fill Container"
The Computed Height
block returns the on-screen dimensions of the button, after it has been rendered on-screen. The value returned is an integer, representing the size of the button in pixels.
This property corresponds to the text that is displayed in the button component.
The set and get visible blocks are used to show or hide the entire button component. Acceptable values are:
True
False
The set and get width blocks work with the Width property of the button component. Acceptable input values are.
Number of Pixels
Percentage Width
"Fit Contents"
"Fill Container"
The Computed Width
block returns the on-screen dimensions of the button, after it has been rendered on-screen. The value returned is an integer, representing the size of the button in pixels.
Set the font for the Hint and Text properties. Options can be found here: .
Set and get the Text Input's
Set and get the Text Input's .
Set and get the Text Input's .
Set and get the Text Input's .
Set and get the Text Input's .
The Image component lets you display pictures in your app and pairs nicely with image-based components like the , , and .
Set and get the Image component's
Uploading a custom font is available on Thunkable's Business and Enterprise plans.
The get and set background color properties work with the color of the button itself i.e. the region behind the button text. Best practice is to use one of the built to set this value, but you can use HEX and RGB values too.
The get and set text color properties can be used to work with the color of the text displayed on the button. Best practice is to use one of the to set this value but you can use HEX and RGB values too.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
X
Position of top left corner of Image on X-axis, where the left hand side is X=0
Number
Y
Position of top left corner of Image on Y-axis, where the top is Y=0
Number
Height
Height of Image in pixels
Number
Width
Width of Image in pixels
Number
Resize Mode
Define dimensions of the image component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Image
True/False
Border Style
Style of Image's border
Select from list [solid, dotted, dashed]
Border Color
Color of Image's border
Color
Border Width
Width of Image's border in pixels
Number
Border Radius
Radius of corners of Image's border in pixels
Number
Shadow Color
Color of Image's shadow
Color
Shadow Opacity
Opacity of Image's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Image's shadow in pixels
Number
Shadow Offset
How far Image's shadow should be offset, in Height and Width, in pixels
Number
Text
Text of the Button
Text
Font
Font used to display Button's text
Select from menu
Custom Font (mobile only)*
Font used to display Button's text
Upload TTF or OTF file
Text Color
Color of Button's text
Color
Font Bold
Toggle whether Button's text is bold
True/False
Font Italic
Toggle whether Button's text is italic
True/False
Raised
Toggle whether Button has shadow
True/False
Font Size
Size of Button's text
Number
Disabled
Toggle whether Button is disabled for end user
True/False
X
Position of top left corner of Button on X-axis, where the left hand side is X=0
Number
Y
Position of top left corner of Button on Y-axis, where the top hand side is X=0
Number
Height
Height of Button in pixels
Number
Width
Width of Button in pixels
Number
Resize Mode
Stretch the button to fit the device screen or render it the same as the design, regardless of the device (float in place).
Select from menu (Stretch or Float in place)
Visible
Toggle whether your end users can see the Button
True/False
Background (Color or Image)
Button's background color or the image displayed on the button
Color or uploaded image file
Border Style
Style of Button's border
Select from list [solid, dotted, dashed]
Border Color
Color of Button's border
Color
Border Width
Width of Button's border in pixels
Number
Border Radius
Radius of corners of Button's border in pixels
Number
Shadow Color
Color of Button's shadow
Color
Shadow Opacity
Opacity of Button's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Button's shadow in pixels
Number
Shadow Offset
How far the Button's shadow is offset, in Height and Width, in pixels
Number
Picture
The image file to be shown in the Image component
Picture Resize Mode
Set how picture is shown if the file and the Image component have different dimensions/aspect ratio
Select from list [cover, contain, stretch, repeat, center]
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
A Checkbox is a component that has two settings, true and false. You can get your app to do specific tasks based on the value of the Checkbox.
Value
Initial value of Checkbox
True/False
Disabled
Toggle whether value Switch can be changed by user
True/False
Color
Color of background when Checkbox is checked
Color
X
Location of top left corner of Checkbox on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Checkbox on Y-axis, where the top side is Y=0
Number
Height
Height of Checkbox in pixels
Number
Width
Width of Checkbox in pixels
Number
Resize Mode
Define dimensions of the Checkbox component/container
Select from list [Stretch, Float in Place]
This event fires every time the value of the Checkbox is changed.
Returns newValue
output block, which returns the new value of the Checkbox (true
or false
).
Note: Organizations is currently being beta-tested.
Thunkable Organizations is a set of administration and collaboration capabilities that allow multiple team members to work on a single project. Creators can jointly design and develop a single, shared project asynchronously.
A single Creator can edit the project at a time, and their changes are available for other members to view when they refresh their page.
Thunkable Creators have:
roles with the organization (admin or member)
permissions within a project (project owner, editor, or viewer)
modes when actively within a project (editing or viewing)
Add/Remove members
Yes
No
No
No
Publish
-
Yes
Yes
No
Share
-
Yes
No
No
Download
-
Yes
Yes
No
Access project settings
-
Yes
Yes
No
Grant Edit Access
-
Yes
No
No
Remix project
-
Yes
Yes
No
Duplicate project
-
Yes
No
No
Delete project
-
Yes
No
No
Figma import
-
Yes
No
No
Versioning
-
Yes
No
No
The Organizations Admin Dashboard is available for an Organization’s admins. This is where they can add, remove, and modify members' roles.
Click your profile image in the upper right.
Select Organizations.
The Organizations page lists the Organizations for which you hold admin status.
Click an Organization name.
The Members tab lists the Organization’s members.
The Projects tab lists the Organization’s projects.
Click Add Member.
Input the invitee’s email address.
Indicate their role (Admin or Member).
Click Add.
Navigate to the Members tab of the Organization’s page.
Click the role dropdown associated with the member.
Select the appropriate role (Admin or Member).
Navigate to the Members tab of the Organization’s page.
Click the role dropdown associated with the member.
Select Remove.
Confirm the removal.
When creating a new project, Organization members can assign it to their own personal projects or the Organization.
Projects assigned to the Organization can be collaborated on by members of the Organization.
Once a project is assigned to an Organization, it cannot be converted to a personal project. It remains part of the Organization and cannot be moved to any one Creator’s personal projects, including the Admin of the Organization.
Projects created within an organization cannot be shared with users outside of the Organization.
The owner of a personal project can make a copy of the project in an organization in which they are a member. To do this, as the project's owner:
On the project's Design tab, click the Project Actions icon.
Select Duplicate into...
In the modal provided, give the project a name.
Use the dropdown menu to indicate which Organization you want to copy the project into.
Click Duplicate into Organization.
You are the owner of the newly created project in the selected Organization. There are no other members with permissions on this project yet.
When accessing Organization projects, members are in one of two modes: Editing or Viewing. There can only be one project member in Editing mode at any given time – all other members of the Organization remain in Viewing mode.
Members accessing the project in Viewing mode cannot make active changes to the shared project.
Only one project member can be in Editing mode at a time.
To request editing access, a member in Viewing mode must click the chevron next to VIEWING.
Click Request Edit.
The member currently in Editing mode is notified that another member has requested editing access.
When the member currently in Editing mode switches to View mode, the member requesting Editing access is switched to Editing mode and can make changes to the project.
If the member currently in Editing mode is offline, no other member can edit the project. The member currently in Editing mode must return online and grant access to a different member.
To share a project with a user in your Organization:
Select Project Sharing.
Enter the email address of the user you want to add to the project
Assign the user a permission level: Editor or Viewer.
Click Add.
To update the permissions of a user in your Organization:
Click the user's existing permission level (EDITOR or VIEWER) and select Editor, Viewer, or Remove.
Organization members can collaborate on projects by adding comments to UI components.
To add a comment to a UI component:
Access the project’s Design tab.
Ensure you’re in Editing mode.
Click the Comment icon to open the comment panel on the right.
Click to select a UI component on a screen or in the component tree.
Type your comment in the provided text input field in the comment panel.
Click the send button.
To add comments to other UI components, repeat steps 4-6.
Click the Comment icon to close the comment panel.
To view comments on a UI component:
Access the project’s Design tab.
Click the Comment icon to open the comment panel on the right.
Comments are grouped with the UI component they were added to.
Comments are displayed in the order they were added, with the most recent comment appearing at the bottom of the UI component's comments.
UI components with the most recent comments appear at the top of the comment panel, making it easier to find the most recent discussions.
Click the Comment icon to close the comment panel.
You can delete your own comments. To delete a comment:
Access the project’s Design tab.
Ensure you’re in Editing mode.
Click the Comment icon to open the comment panel on the right.
Locate the comment you want to delete.
Click the vertical ellipsis icon within the comment’s box.
Click Delete.
This cannot be undone. Click Delete to confirm the deletion of the comment.
Click the Comment icon to close the comment panel.
To get started with Thunkable Organizations, please contact the Thunkable team here: . The Thunkable team will take care of setting up and managing your organization.
Click the Share icon.
Click the Share icon.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
The Layout component is currently being beta-tested.
Thunkable’s Layout component allows for more precise positioning of UI components on an app screen, by allowing you to position UI components dependent on other UI components on the screen. For example, in a typical sign-in screen, if a user inputs an incorrect email address or password, a screen built with a Layout component allows you to shift the UI components on the screen to display the error messaging to the user.
To add a Layout to a screen:
Drag and drop the Layout UI component onto a screen. You’ll notice it is composed of two Containers, one on top of the other.
Click and drag the sizing handles in the corners to resize the Layout UI component.
Click and drag to reposition it.
By default, a newly added Layout has two horizontal Containers arranged vertically, one on top of the other. To insert additional Containers to a Layout:
Click to select the Layout UI component in the component tree or within the screen.
At the top of the Layout’s properties panel, select whether you want to insert a Horizontal or Vertical Container. ∙ Horizontal Container - UI components within the Container are aligned horizontally, side by side ∙ Vertical Container - UI components within the Container are aligned vertically, on top of each other
Identify into which Layout or Container you want to insert the new Container.
Click Add.
To add UI components to a Layout:
Drag and drop UI components into a Container on a screen.
Once UI components are in a Container, rearrange their order by dragging and dropping their component names in the component tree.
The following properties are configured on the right in the Layout's properties panel.
Direction
vertical
The elements directly within the Layout (could be a UI component or a Container) are aligned vertically, on top of each other.
Direction
horizontal
The elements directly within the Layout (could be a UI component or a Container) are aligned horizontally, side by side.
Vertical / Horizontal Alignment
top
The elements directly within the Layout (could be a UI component or a Container) are positioned at the top of the Layout.
Vertical / Horizontal Alignment
bottom
The elements directly within the Layout (could be a UI component or a Container) are positioned at the bottom of the Layout.
Vertical / Horizontal Alignment
left
The elements directly within the Layout (could be a UI component or a Container) are positioned at the left of the Layout.
Vertical / Horizontal Alignment
right
The elements directly within the Layout (could be a UI component or a Container) are positioned at the right of the Layout.
Vertical / Horizontal Alignment
center
The elements directly within the Layout (could be a UI component or a Container) are positioned in the center of the Layout (either top to bottom or left to right, depending on the selected direction).
Vertical / Horizontal Alignment
space-between
The elements directly within the Layout (could be a UI component or a Container) are positioned with an equal amount of space between them.
Vertical / Horizontal Alignment
space-around
The elements directly within the Layout (could be a UI component or a Container) are positioned with an equal amount of space between them, including at the top and bottom for a vertical direction Layout or left and right for a horizontal direction Layout.
Scrollable
true/on
The user can scroll within the Layout.
Scrollable
false/off
The user cannot scroll within the Layout.
Scroll Bar Visible
true/on
The scroll bar is visible to the user.
Scroll Bar Visible
false/off
The scroll bar is not visible to the user.
Horizontal Alignment Examples
Vertical Alignment Examples
X
coordinate value
Position of the upper left corner of the Layout on the X-axis, where the left side of the screen is X=0.
Y
coordinate value
Position of the upper left corner of the Layout on the Y-axis, where the top of the screen is Y=0.
Height
number in pixels
The Layout’s height is defined by a custom number of pixels.
Width
number in pixels
The Layout’s width is defined by a custom number of pixels.
Resize Mode
Stretch
Stretches the Layout to fit the dimensions of the device's screen.
Resize Mode
Float in Place
Renders the Layout in the same aspect ratio as the design, regardless of the device size.
Background Picture
Upload files
Click to upload an image file.
Background Picture
Type in URL
Type in an image URL.
Background Picture Resize Mode
cover
Fills the entire Layout without changing the height and width ratio of the image.
Background Picture Resize Mode
contain
The entire image is scaled down to fit inside the Layout, without changing the height and width ratio of the image.
Background Picture Resize Mode
stretch
The image's height will change to fill the Layout length-wise.
Background Picture Resize Mode
repeat
The image repeats to cover the Layout. The image's height and width ratio do not change.
Background Picture Resize Mode
center
The image is positioned in the middle of the Layout.
Visible
visible
Users can see the Layout.
Visible
invisible
Users cannot see the Layout.
Background Color
color
The background color of the Layout.
Border: Style
solid
The Layout’s border is a solid line.
Border: Style
dotted
The Layout’s border is a dotted line.
Border: Style
dashed
The Layout’s border is a dashed line.
Border: Color
color
The Layout’s border is the color selected.
Border: Width
number in pixels
The width of the Layout’s border is defined by a custom number of pixels.
Border: Radius
number in pixels
The radius of the Layout border’s corners is defined by a custom number of pixels.
Shadow: Color
color
The Layout’s shadow is the color selected.
Shadow: Opacity
number between 0 and 100
The opacity of the Layout’s shadow.
Shadow: Radius
number in pixels
The radius of the Layout shadow’s corners is defined by a custom number of pixels.
Shadow: Offset
number in pixels
How far the Layout’s shadow should be offset, in height and width, is defined by a custom number of pixels.
Margin
top
The margin between the Layout’s top border and the next UI component as defined by a custom number of pixels.
Margin
bottom
The margin between the Layout’s bottom border and the next UI component as defined by a custom number of pixels.
Margin
left
The margin between the Layout’s left border and the next UI component as defined by a custom number of pixels.
Margin
right
The margin between the Layout’s right border and the next UI component as defined by a custom number of pixels.
Padding
top
The padding between the Layout and its top border as defined by a custom number of pixels.
Padding
bottom
The padding between the Layout and its bottom border as defined by a custom number of pixels.
Padding
left
The padding between the Layout and its left border as defined by a custom number of pixels.
Padding
right
The padding between the Layout and its right border as defined by a custom number of pixels.
The following properties are configured on the right in the Container's properties panel.
Direction
vertical
UI components within the Container are aligned vertically, on top of each other.
Direction
horizontal
UI components within the Container are aligned horizontally, side by side.
Vertical / Horizontal Alignment
top
UI components are positioned at the top of the Container
Vertical / Horizontal Alignment
bottom
UI components are positioned at the bottom of the Container
Vertical / Horizontal Alignment
left
UI components are positioned at the left of the Container
Vertical / Horizontal Alignment
right
UI components are positioned at the right of the Container
Vertical / Horizontal Alignment
center
UI components are positioned in the center of the Container (either top to bottom or left to right depending on the selected direction)
Vertical / Horizontal Alignment
space-between
UI components are positioned with an equal amount of space between them
Vertical / Horizontal Alignment
space-around
UI components are positioned with an equal amount of space between them, including at the top and bottom for vertical direction Containers or left and right for horizontal direction Containers
Scrollable
true/on
The user can scroll within the Container.
Note: When setting a Container as scrollable, we recommend the size of the UI components within it are set to an absolute pixel value or Fit Contents.
Scrollable
false/off
The user cannot scroll within the Container.
Scroll Bar Visible
true/on
The scroll bar is visible to the user.
Scroll Bar Visible
false/off
The scroll bar is not visible to the user.
Horizontal Alignment Examples
Vertical Alignment Examples
Height
Fit contents
The Container’s height is the same as the tallest UI component or Container within it (horizontal direction) or the stacked UI components or Containers within it (vertical direction).
Height
Fill container
The elements directly within the Container (could be a UI component or another Container) fill the Container vertically.
Height
Size (e.g. 50px or 50%)
The Container’s height is defined by a custom number of pixels or percentage of the screen.
Width
Fit contents
The Container’s width is the same as the widest UI component or Container within it (vertical direction) or the side-by-side UI components or Containers within it (horizontal direction).
Width
Fill container
The elements directly within the Container (could be a UI component or another Container) fill the Container horizontally.
Width
Size (e.g. 50px or 50%)
The Container’s width is defined by a custom number of pixels or percentage of the screen.
Background Picture
Upload files
Click to upload an image file.
Background Picture
Type in URL
Type in an image URL.
Background Picture Resize Mode
cover
Fills the entire screen without changing the height and width ratio of the image.
Background Picture Resize Mode
contain
The entire image is scaled down to fit inside the screen, without changing the height and width ratio of the image.
Background Picture Resize Mode
stretch
The image's height will change to fill the screen length-wise.
Background Picture Resize Mode
repeat
The image repeats to cover the screen. The image's height and width ratio do not change.
Background Picture Resize Mode
center
The image is positioned in the middle of the frame.
Visible
visible
Users can see the Container.
Visible
invisible
Users cannot see the Container.
Background Color
color
The background color of the Container.
Visible
solid
The Container’s border is a solid line.
Visible
dotted
The Container’s border is a dotted line.
Visible
dashed
The Container’s border is a dashed line.
Border: Color
color
The Container’s border is the color selected.
Border: Width
number in pixels
The width of the Container’s border is defined by a custom number of pixels.
Border: Radius
number in pixels
The radius of the Container border’s corners is defined by a custom number of pixels.
Shadow: Color
color
The Container’s shadow is the color selected.
Shadow: Opacity
number between 0 and 100
The opacity of the Container’s shadow.
Shadow: Radius
number in pixels
The radius of the Container shadow’s corners is defined by a custom number of pixels.
Shadow: Offset
number in pixels
How far the Container’s shadow should be offset, in height and width, is defined by a custom number of pixels.
Margin
top
The margin between the Container’s top border and the next Container as defined by a custom number of pixels.
Margin
bottom
The margin between the Container’s bottom border and the next Container as defined by a custom number of pixels.
Margin
left
The margin between the Container’s left border and the next Container as defined by a custom number of pixels.
Margin
right
The margin between the Container’s right border and the next Container as defined by a custom number of pixels.
Padding
top
The padding between the Container and its top border as defined by a custom number of pixels.
Padding
bottom
The padding between the Container and its bottom border as defined by a custom number of pixels.
Padding
left
The padding between the Container and its left border as defined by a custom number of pixels.
Padding
right
The padding between the Container and its right border as defined by a custom number of pixels.
To access the blocks specific to the Layout component:
Navigate to the Blocks tab.
In the component tree on the left, click the Layout component.
A drawer of Layout-specific blocks opens.
If the Layout is scrollable, you can use this block to scroll the user to the end of the Layout. For example, a user clicks a button in a chat app, and the Layout scrolls to the end of the chat history to see the most recent messages.
If the Layout is scrollable, you can use this block to scroll the user to the start of the Layout.
Sets the Layout’s height to a custom number of pixels.
Gets the Layout’s height in pixels.
Gets the Layout’s computed height, the on-screen dimensions of the Layout, after it has been rendered on-screen. The value returned is an integer, representing the height of the Layout in pixels.
Sets the Layout’s width to a custom number of pixels.
Gets the Layout’s width in pixels.
Gets the Layout’s computed width, the on-screen dimensions of the Layout, after it has been rendered on-screen. The value returned is an integer, representing the width of the Layout in pixels.
When set to true, sets the Layout to visible, meaning the Layout is visible to users.
When set to false, sets the Layout to invisible, meaning the Layout is not visible to users.
Gets the Layout’s visibility status. Returns true (visible) or false (invisible).
Set the position of the upper left corner of the Layout on the X-axis, where the left side of the screen is X=0.
Get the position of the upper left corner of the Layout on the X-axis, where the left side of the screen is X=0.
Set the position of the upper left corner of the Layout on the Y-axis, where the top of the screen is Y=0.
Get the position of the upper left corner of the Layout on the Y-axis, where the top of the screen is Y=0.
Set the Layout’s background color.
Get the Layout’s background color.
Set the Layout's background picture. Click the dropdown menu to select an image from your computer.
Get the Layout's background picture.
Set the Layout’s background picture resize mode. See the Layout Properties section for definitions of the acceptable values.
Get the Layout’s background picture resize mode.
When set to true, sets the Layout to scrollable for users.
When set to false, sets the Layout to scrollable for users.
Gets the Layout’s scrollable status. Returns true (scrollable) or false (not scrollable).
When set to true, sets the Layout’s scroll bar to visible for users.
When set to false, sets the Layout’s scroll bar to invisible for users.
Gets the Layout’s scroll bar visibility status. Returns true (visible) or false (invisible).
To access the blocks specific to the Container component:
Navigate to the Blocks tab.
In the component tree on the left, click the Container component that is nested under the Layout component.
A drawer of Container-specific blocks opens.
When you're happy with the Layout you have customized, ensure it is selected in the component tree.
Click the vertical ellipsis next to the Layout's name in the properties panel.
Select Save as Data Viewer Layout.
Give your Data Viewer Layout a detailed name.
Select the Layout Type you want to create. - List for a Data Viewer List - Grid for a Data Viewer List.
Click OK.
Click the Create New Screen icon at the top of the component tree in the Designer.
Drag a Data Viewer List or Data Viewer Grid onto your screen.
Reposition and resize as necessary.
Click the sample template to access the Data Viewer templates available to you.
Click to select the Layout you saved as a Data Viewer from the bottom of the template library.
Map your data source columns to components within your custom Data Viewer Layout.
A Group is a container component.
To add components to a Group, simply drag and drop the components inside the Group.
You will see the components you added to the Group are now nestled inside the Group in the component tree.
When a group that contains UI Component(s) is moved, its content are moved with it as a unit.
This makes it easier to design complex layouts.
Position
Set whether the Group is positioned Relative to the Screen or Relative to Device ¹
Select from menu: [Relative to Screen, Relative to Device]
Touch Opacity
Set opacity of Group when user clicks on Group
Number between 0-100
¹ Relative to Screen: Group moves as end user scrolls Relative to Device: Group stays in place as end user scrolls (suitable for creating a Floating Action Button)
² Stretch: Resize Group in proportion with wider Screen Float in Place: Keep same dimensions for Group on larger screens
X
Position of top left corner of Group on X-axis
Number
Y
Position of top left corner of Group on Y-axis
Number
Height
Height of Group in pixels
Number
Width
Width of Group in pixels
Number
Resize Mode
Set how Group is resized on wider screens - Stretch or Float in Place ²
Select from menu: [Resize, Float in Place]
Visible
Set whether Group is shown on screen
True/False
Background Fill
Color of Group's background
Color
Background Image
The image file to be shown in the Group's background
Background Image Resize Mode
Set how picture is shown if the file and the Image component have different dimensions/aspect ratio
Select from list [cover, contain, stretch, repeat, center]
Border Style
Style of Group's border
Select from list [solid, dotted, dashed]
Border Color
Color of Group's border
Color
Border Width
Width of Group's border in pixels
Number
Border Radius
Radius of corners of Group's border in pixels
Number
Shadow Color
Color of Group's shadow
Color
Shadow Opacity
Opacity of Group's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Group's shadow in pixels
Number
Shadow Offset
How far Group's shadow should be offset, in Height and Width, in pixels
Number
You can use the following blocks to listen for when a specific event occurs
Performs an action when the user taps the Group.
Set and get the Background Color of the Group.
Set and get the Background Picture of the Group.
Set and get the Background Picture Resize Mode of the Group.
Get the height of the of the Group as it appears in-screen in pixels.
Set and get the Visible property of the Group.
Get the width of the of the Group as it appears in-screen in pixels.
A switch is a component that has two settings, true and false. You can get your app to do specific tasks based on the value of the switch.
Value
Initial value of Switch
True/False
Tint Color
Color of background when Switch is false
Color
On Tint Color
Color of background when Switch is true
Color
Thumb Tint Color
Color of the Switch's slider
Color
Disabled
Toggle whether value Switch can be changed by user
True/False
X
Location of top left corner of Switch on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Switch on Y-axis, where the top side is Y=0
Number
Height
Height of Switch in pixels
Number
Width
Width of Switch in pixels
Number
Resize Mode
Define dimensions of the Switch's component/container
Select from list [Stretch, Float in Place]
This event fires every time the switch is clicked.
Returns newValue
output block, which returns the new value of the Switch (true
or false
).
The Slider is a great UI element to enable users easily select a value from a fixed range of values.
Value
Initial value of the Slider
Number
Step
Step between values on the Slider
Number
Minimum Value Range
Minimum value the user can select. Must be less than Maximum Value.
Number
Maximum Value Range
Maximum value the user can select. Must be greater than Minimum Value.
Number
Min Track
Color of Slider track between minimum value and current value
Color
Max Track
Color of Slider track between current value and maximum value
Color
Thumb Color
Color of the Slider thumb widget
Color
Disabled
Toggle whether value Switch can be changed by user
True/False
X
Location of top left corner of Slider on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Slider on Y-axis, where the top side is Y=0
Number
Height
Height of Slider in pixels
Number
Width
Width of Slider in pixels
Number
Resize Mode
Define dimensions of the Slider component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Slider
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Slider in pixels
Number
Border Radius
Radius of corners of border on Slider in degrees
Number
Shadow Color
Color of Slider's shadow
Color
Shadow Opacity
Opacity of Slider's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Slider's shadow in pixels
Number
Shadow Offset
How far Slider's shadow should be offset, in Height and Width, in pixels
Number
Fires as the value of the slider changes. Returns the current value of the Slider.
Fires when the user takes their thumb off the Slider. Returns the current value of the Slider.
Returns Height of the Slider in pixels as it appears on the screen.
Returns Width of the Slider in pixels as it appears on the screen.
You can live-test your app without adding your unique Google Maps API keys, but you need to add them if you want to download or publish your app.
To generate your personal Google Maps API key, you need to:
Create a Google Cloud project for your app.
Create a billing account or enable billing for the project.
Click Enable to enable the Maps SDK for Android or Maps SDK for iOS.
Copy the provided API key.
The map has several events. You can trigger actions to happen when these events occur.
This event happens when the Map has loaded in your app.
This is a good time to add any markers, polylines or polygons to your app that you want the user to see as soon as your app opens.
GeoJSON is a format for encoding geographical data structures that is based on the JSON (JavaScript Object Notation) format. It is a lightweight and versatile format that is widely used for storing and exchanging spatial data. GeoJSON provides you with a simple and flexible way to add geographic data to your Google Maps app, making it easy to create engaging and informative map-based applications.
Incorporating GeoJSON in your Thunkable Map component allows you to draw lines, shapes (rectangles, triangles, squares, and custom shapes), and markers on the map.
We do not currently support adding GeoJSON tooltips or callouts.
To use the Add GeoJSON block:
On the Design tab of your Thunkable project, add a map component to a screen.
On the Blocks tab, within the component tree, click the Map component.
Drag and drop the Add GeoJSON block into your workspace.
Click Text.
Drag the empty text block and connect it to the Add GeoJSON block.
Drag and drop the Add GeoJSON block into an event block. For example, the onMapReady block to render the GeoJSON when the map loads, or the when button click block to render the GeoJSON when the user clicks a button.
The coordinate object has the following properties:
{ target: Numeric ID for your app coordinate:{ latitude: latitude of point selected longitude: longitude of point selected } position:{ x: x-position of selected point on the Map component y: x-position of selected point on the Map component } }
This event happens when the user taps on the Map.
This event happens when the user presses on the map for a longer period of time.
This event happens when the user clicks on a Marker that is on the Map.
The event object has the following properties:
{ latitude: latitude of the selected Marker longitude: longitude of the selected Marker }
Adds a generic map marker to your map at the specified latitude/longitude.
This block takes the following inputs:
Adds a marker of a selected image to your map at the specified latitude/longitude
This block takes the following inputs:
Add a polyline to your map. This is an outline that connects several points on your map.
This block takes the following inputs:
These blocks:
Will produce this polyline:
Note that polylines won't automatically create a closed shape. You would need to add a forth object with the properties latitude: 37
and longitude: -122
to the coordinate
input of the addPolyline
block above to close this triangular polyline.
Add a polygon to your map. This is a solid shape that connects several points on your map.
This block takes the following inputs:
These blocks:
Will produce this polygon:
Note that the polygon outline will automatically connect the first and last points in the list of coordinates.
Returns the height of the Map on the device screen in pixels.
Returns the width of the Map on the device screen in pixels.
These blocks will set the map's latitude and longitude to show the user's location once the map is ready:
The blocks are the same as the ones above in the , but specific to the Container instead of the Layout.
Thunkable provides a variety of default and templates, but saving a customized Layout component as a Data Viewer allows you to display your data in a way that reflects your brand design and preferences.
Connect you project to a data source. See here for instructions on connecting a data source: .
See here for more on working with Data Viewers and Data Sources: .
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
You can place components inside a Group to make changing the appearance of your app easier.
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
Set and get the of the Group.
Use these blocks to set and get the named of the Switch.
Set and get the of the Slider.
The Map component lets you show an area of a Google map to the user. You can add , , and to this map.
Select Enable all Google Maps APIs for this project.
For more detailed instructions, please see here: .
Once you've generated your Google Maps API keys, you can add them to your Thunkable project. Click the gear icon on the left of your project's designer tab to access your . Scroll to the Google Map Settings section and paste your Android and iOS API keys into the corresponding fields.
Paste your GeoJSON data into the empty text block. This can be retrieved from a website such as .
This event happens when the location of the user changes. It returns the coordinate object. You can use to get the properties of the coordinate object.
The On Marker Press block returns an event object. This is an object which can be used with
You can use the deleteAllMarkers block to delete all from your app.
You can use the deleteAllPolylines block to delete all from your app.
You can use the deleteAllPolygons block to delete all from your app.
Set and get of the Map component.
You can pair the Map component with a . This helps you show content relevant to the user's location.
Latitude
Co-ordinate of the map's center on the north-south axis
Number
Longitude
Co-ordinate of the map's center on the east-west axis
Number
Zoom
Zoom level between -15 (most zoomed out) and 15 (most zoomed in)
Number
Provider
Map provider (ex. Google).
Text
Map Type
Style of map.
Select from list (standard, satellite, hybrid, terrain, none)
User location
Show the user where they are on the map.
True/False
My location button
Show button that allows the user to re-center the map on their location.
True/False
Compass
Show compass.
True/False
Scroll
Allow user to scroll on the map.
True/False
Zoom
Allow user to zoom in and out on the map.
True/False
Traffic
Show traffic data.
True/False
X
Location of top left corner of Map on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Map on Y-axis, where the top side is Y=0
Number
Height
Height of Map in pixels
Number
Width
Width of Map in pixels
Number
Resize Mode
Define dimensions of the map component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Map
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Map in pixels
Number
Border Radius
Radius of corners of border on Map in degrees
Number
Shadow Color
Color of map's shadow
Color
Shadow Opacity
Opacity of map's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of map's shadow in pixels
Number
Shadow Offset
How far map's shadow should be offset, in Height and Width, in pixels
Number
Output name
Output value
Data Type
Latitude
Latitude of selected position
Number
Longitude
Longitude of selected position
Number
position X
X Co-ordinate of selected position on map component
Number
position Y
Y Co-ordinate of selected position on map component
Number
Output name
Output value
Data Type
Latitude
Latitude of selected position
Number
Longitude
Longitude of selected position
Number
position X
X Co-ordinate of selected position on map component
Number
position Y
Y Co-ordinate of selected position on map component
Number
Latitude
Latitude of marker's position
Number between -90 and 90
Longitude
Longitude of marker's position
Number between -90 and 90
Title
Title of marker (displayed when marker is clicked)
Text
Description
Description of marker (displayed when marker is clicked)
Text
Pin Color
Color of marker
Color
Latitude
Latitude of marker's position
Number between -90 and 90
Longitude
Longitude of marker's position
Number between -90 and 90
Title
Title of marker (displayed when marker is clicked)
Text
Description
Description of marker (displayed when marker is clicked)
Text
Icon
Image to use as marker
Input
Description
Data Type
Coordinate
List of points to draw a line between. List can be any length.
Stroke Width
Width of polyline
Number
Stroke Color
Color of polyline
Color
Input
Description
Data Type
Coordinate
List of points to draw a line between. List can be any length.
Stroke Width
Width of outline
Number
Stroke Color
Color of outline (Only visible if Stroke Width > 0)
Color
Fill Color
Color of polygon shape
Color
For activities that take more than a few seconds, loading icons can be helpful to tell your app users that an activity is happening in the background, such as retrieving or uploading data.
Color
The color of the Loading Icon
Color
X
Location of top left corner of Loading Icon on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Loading Iconon Y-axis, where the top side is Y=0
Number
Height
Height of Loading Icon in pixels
Number
Width
Width of Loading Icon in pixels
Number
Resize Mode
Define dimensions of the loading icon component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Loading Icon
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Loading Icon in pixels
Number
Border Radius
Radius of corners of border on Loading Icon in degrees
Number
Shadow Color
Color of loading icon's shadow
Color
Shadow Opacity
Opacity of loading icon's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of loading icon's shadow in pixels
Number
Shadow Offset
How far loading icon's shadow should be offset, in Height and Width, in pixels
Number
Select a size for the Loading Icon. Can choose between extra small, small, middle, large,
or extra large
.
Returns the height of the Loading Icon on the device screen in pixels.
Returns the width of the Loading Icon on the device screen in pixels.
The loading icon should be displayed when the app is performing an activity in the background and hidden when it is not.
One way to show and hide the icon is to use the visible
property of the component.
In the following example the loading icon shows up when the app opens but disappears after data is retrieved from Airtable.
When the visibility is set to true, the loading icon will be seen on the app screen. If set to false, the loading icon will not be seen on the app screen.
Allow your users to view your favorite PDFs -- legal contracts, art posters or maybe even a PhD dissertation -- all from the convenience of your app
File
PDF to be displayed in the PDF Reader
PDF file or URL ending in .pdf
There are two ways to set a file to display in the PDF Reader.
You can enter a URL that points to a PDF on the web to display in your PDF. Make sure this URL ends in .pdf
Once you upload the PDF, you will be able to view it in your app and pinch to zoom in.
X
Location of top left corner of PDF Reader on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of PDF Reader on Y-axis, where the top side is Y=0
Number
Height
Height of PDF Reader in pixels
Number
Width
Width of PDF Reader in pixels
Number
Resize Mode
Define dimensions of the PDF Reader component/container
Select from list [Stretch, Float in Place]
Returns the height/width of the PDF Reader on the device screen in pixels.
When building apps on Thunkable, Screens function like blank pages in a book. They allow you to display different components and information.
There are two ways to add a new screen to your app:
Click the + icon next to your Screen names in the Screens bar.
Click New Screen icon at the top of your components tree. Select Create New Screen.
Once you’ve perfected the design of a screen on the Design tab of a drag and drop project you can duplicate it using copy and paste keyboard shortcuts.
To copy and paste a screen:
Click on a screen name in the component tree (A) or the screen itself within your workspace (B).
Type ctrl+c or command+c on Mac, and ctrl+c on PC, to copy the screen.
Type ctrl+v or command+v on Mac, and ctrl+v on PC, to paste a duplicate of the screen.
The new screen will be added to the right of the existing screen.
This determines how to resize the image when the frame doesn't match the raw image dimensions.
Cover: Fills the entire screen without changing the height and width ratio of the image
Contain: The entire image will be scaled down to fit inside the screen, without changing the height and width ratio of the image
Stretch: The image's height will change to fill the screen length-wise
Repeat: Repeat the image to cover the screen. The image's height and width ratio will not change
Center: Positions the image in the middle of the frame
The status bar is located at the top of a phone's screen. The status bar displays information regarding signal strength, battery, and whether or not things like the alarm or wi-fi are enabled.
Thunkable allows you to reuse a screen, and its associated blocks, in multiple projects.
Select the screen in the Designer.
Click the vertical elipses at the top of the screen's properties pane.
Give your screen a descriptive name.
Click Save.
Open the project in which you'd like to add the saved screen.
Click the upside-down arrow at the top of the Designer's component tree.
Click Add From Saved Screens.
Select the screen you want to add.
Click Copy.
When a saved screen is added to a new project, you may notice some errors in the blocks that you’ll need to address. This is because the app you have added the screen to doesn’t necessarily have the same features. For example, the blocks may navigate the user to a screen that doesn’t exist in the new app. Another example of an error that would need to be addressed is if the screen had a data viewer, but the data source wasn’t connected to this project.
Navigate to your Projects Page.
Click My Screens in the upper left.
On you My Screens page you can view your screens, rename them, and delete screens you no longer need.
You can disable screen preview for apps with many screens to improve platform performance and load time. When enabled, the project only loads the screen you're working on, and the others are paused.
To disable app screen preview:
Click your account avatar or icon in the upper right corner.
Select Settings.
Click the FEATURES tab.
Toggle on Disable app screen preview.
The video component lets you play videos in your app.
The Video component lets you play videos in your project that are stored in the cloud or in your project. Users can easily pause, rewind or fast-forward the video with this player.
There are a few ways you can set a video source in your app:
Enter the URL of the video you want to show in your project.
The link has to end in .mp4
, .mov
, …so videos uploaded to YouTube and other video sharing sites may not work.
Please note that the Video component is not recommended for streaming live video content.
Returns the height of the Video on the device screen in pixels.
Returns the width of the Video on the device screen in pixels.
See a video tutorial for using Animations in your Thunkable project here:
You can trigger some action to happen when the animation is clicked using the 'when Animation Click' event.
Returns the height of the Animation on the device screen in pixels.
Display websites in your app
If you own the website being displayed in your Web Viewer, you can send and receive messages between your website and the Web Viewer using Javascript.
Fires when the Web Viewer receives a message from the web page it's displaying. Returns message
output. This is a piece of text that contains the message that was returned.
Reload the Web Viewer.
Go back to the previous page visited.
Move forward to the next page in your browser history.
Post a message.
Returns any message that was received after calling the Post Message function.
Returns the on-screen dimensions of the web viewer, after it has been rendered on-screen.
The value returned is an integer, representing the size of the Web Viewer in pixels.
Returns the on-screen dimensions of the web viewer, after it has been rendered on-screen.
The value returned is an integer, representing the size of the Web Viewer in pixels.
Show or hide the Web Viewer.
Change the web address that is displayed in the web viewer. Use HTTPS:// URLs with this block.
Create powerful, no-code, data-driven apps connected directly to Google Sheets, Airtable, or stored locally.
The Data Viewer Grid lets you connect to a Data Source and view your data as a grid. This layout works well with data that includes images.
The Item Click
event is fired when any card in the Data Viewer is clicked.
Returns a row id
which corresponds to the unique Thunkable Id of the card that was clicked.
Refresh the Data Viewer Grid to sync with the Data Source.
Get the computed Height and Width of the Data Viewer Grid as it appears on-screen.
Set and get the Visible property of the Data Viewer Grid
Set and get the Horizontal Scroll property of the Data Viewer Grid
Set and get the Empty Text property of the Data Viewer Grid
When you connect a Data Source to your project you will also have access to a second block drawer. These Data Source blocks allow you to perform a variety of CRUD (Create, Read, Update, Delete) operations on your data.
Click on the link below to learn how to use the Data Sources blocks in your project.
Dropdown menu (select )
List of . Each object must have the properties latitude
and longitude.
Latitude and Longitude must be .
List of . Each object must have the properties latitude
and longitude.
Latitude and Longitude must be .
Set and get of the Loading Icon component.
If you want to show different styles of animations in your app as content loads, check out the component.
You can upload a PDF as an to your app and display it in the PDF Viewer. Be careful of the Thunkable 50 MB if you choose to upload a file to your project.
Set and get of the PDF Reader.
This feature is available with the Thunkable Teams plan. See here for more information: .
Click Save Screen.
When you add a Screen to a Navigator, you will see a new section for Navigation Options in your Screen's Properties panel. You can read about these properties in the , , and docs.
You can upload a video file as an in your project. Be careful of the Thunkable 50 MB if you choose to upload a file to your project.
Set and get of the Video component
The Animation component powered by makes adding animations as easy as adding images. For designers, animations can be created in or and imported as a .json
file.
For the rest of us, there is a large and growing community of designers who have that you can easily add to your app.
Change the of your Animation component
Some websites may not appear when previewing your app on the web. You may need to the app on a device, or and install the app, to see your web page.
You can see examples of sending/receiving messages and get further setup instructions .
You may also find the component useful for sending/receiving information between your app and a website.
The row id is particularly useful when used with the the blocks.
Set and get of the Data Viewer Grid.
Visibility
Decide whether you want the status bar visible on the screen.
True/False
Style
Default is best practice, but you can select light-content or dark-content to potentially override the user's phone settings.
Select from menu (default, light-content, dark-content)
Color (Android only)
Color of the status bar.
Color
Translucent (Android only)
When translucent is set to true, the app will appear under the status bar.
True/False
Event
Description
Starts
Fires when the Screen is first opened
Event
Description
Opens
Fires anytime the Screen is opened
Event
Description
BackButtonPressed
Fires when the physical or on-screen back button is pressed. (Android only)
Video
The video users can play within your app.
Uploaded video file or the video's URL.
Play
Toggle whether or not video file auto-plays when Screen opens
True/False
X
Location of top left corner of Video component on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Video component on Y-axis, where the top side is Y=0
Number
Height
Height of Video component in pixels
Number
Width
Width of Video component in pixels
Number
Resize Mode
Define dimensions of the video component/container
Select from list [Stretch, Float in Place]
Animation
The name of a JSON animation you wish to display
Text
Loop
Toggle whether Animation loops or not
True/False
Property
Description
Data Type
X
Location of top left corner of Animation on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Animation on Y-axis, where the top side is Y=0
Number
Height
Height of Animation in pixels
Number
Width
Width of Animation in pixels
Number
Resize Mode
Define dimensions of the animation component/container
Select from list [Stretch, Float in Place]
URL
Set initial URL to be displayed in the Web Viewer. URL should begin with HTTPS://. Can also type in the name of a HTML file that has been uploaded to the project to display in the Web Viewer.
URL
Geolocation Enabled (Android only)
Select if you want to enable geolocation functionality for Android apps.
True/False
X
Location of top left corner of Web Viewer on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Web Viewer on Y-axis, where the top side is Y=0
Number
Height
Height of Web Viewer in pixels
Number
Width
Width of Web Viewer in pixels
Number
Resize Mode
Define dimensions of the Web Viewer component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Web Viewer
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Web Viewer in pixels
Number
Border Radius
Radius of corners of border on Web Viewer in degrees
Number
Shadow Color
Color of Web Viewer's shadow
Color
Shadow Opacity
Opacity of Web Viewer's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Web Viewer's shadow in pixels
Number
Shadow Offset
How far Web Viewer's shadow should be offset, in height and width, in pixels
Number
Property
Description
Data Type
X
Location of top left corner of component on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of component on Y-axis, where the top side is Y=0
Number
Height
Height of component in pixels
Number
Width
Width of component in pixels
Number
Resize Mode
Define dimensions of the Data Viewer Grid component/container
Select from list [Stretch, Float in Place]
Scrollable
Select whether your user can scroll on this screen. For scrollable to work, the components in your screen must have heights either set in absolute
pixels or set to fit contents.
True/False
Background Color
Default (none
). Select any color using the color picker, RGBA or HEX value
Color
Background Image
The image file to be shown in the tab's background
Background Image Resize Mode*
Set how image is shown if the file and the tab component have different dimensions/aspect ratio
Select from list [cover, contain, stretch, repeat, center]
Orientation (iOS and Android only)
Define the screen's orientation.
Select from list [portrait, landscape, auto]
Function
Description
ToggleDrawerMenu
Data Source
Reference to chosen data source
Table
Table from your Data Source to show data from
Reference to chosen table in Data Source
Grid Appearance
How your data will be displayed in your app
Select from list
Populate Data
Select what items of data from your Data Source to show in which aspects of your layout
Select from lists
Horizontal Scroll
Toggle whether your Data Viewer should scroll horizontally (if false
, Data Viewer will scroll vertically)
True/False
Empty Text
Text that will be displayed if there is no data to fill a string in your Data Viewer
Text
AdMob is the most popular ad network for monetizing mobile apps today.
We highly recommend that you only add ads to your app after it has been completed and you have a good idea of how users will move through your app. Once your app is complete, you can go back in find natural points to add the different types of ads for your users.
Default value: "This identifier will be used to deliver personalized ads to you."
Click on the Apps tab in your AdMob Sidebar
Click View All Apps
Click the name of the app associated with the ad unit.
Click on the Add Ad Unit button
Select the type of ad you wish to add (Note: Thunkable only currently supports Banner, Interstitial, or Rewarded Ads).
Add a name for your Ad Unit (e.g. "Banner Ad")
Click the Create Ad Unit button
To download and publish Thunkable apps that contain ads, you must first be a member of Thunkable's MCM (Multiple Customer Management) network.
By joining this network, you consent to sharing 10% of your AdMob revenue for all apps you have currently on AdMob with Thunkable to support maintenance costs.
Thunkable has partnered with AdMob to ensure that apps created on our cross-platform use ads to monetize apps in a way that both provides high quality traffic to advertisers and a high quality user experience for end users of apps.
Inappropriate content that advertisers do not want to be associated with e.g. copyrighted, adult
Invalid activity that lowers the quality of traffic to advertisers e.g. ad placements that encourage clicks
Thunkable will review apps for compliance with AdMob policies but will specifically reject apps that are:
Incomplete apps - apps that are still in their early stages and won't show how ads will be used in the app
Earning apps - apps that encourage users to clicks ads in exchange for some form of payment
Auto-impression apps - apps that repeatedly load banner ads in the background of apps
Apps that show an Interstitial ad or Video ad on startup - these ads must be implemented properly in your app
Thunkable reserves the right to change an app's approval status subject to any violation of our guidelines.
If your app is rejected, the Thunkable AdMob team will send an email to the address used in your submission and you will be provided with an explanation and a recommendation for changes to make to get your app approved upon re-submission.
You are welcome to submit the same app for approval multiple times.
The Banner ad is a rectangular image or text ads that occupy a spot within an app's layout.
AdMob banner ads are the simplest ad format to implement and are recommended for beginners. No blocks are needed to show your Banner ad to your end users.
The first banner ad will load when ready and will reload a new ad every minute.
Ad Unit ID (Android)
Ad Unit ID for showing your ad on Android devices
Text
Ad Unit ID (iOS)
Ad Unit ID for showing your ad on iOS devices
Text
Test Mode
Toggle whether real ads or sample ads should display in your app. Set this to true while testing your own app.
True/False
Y
Location of top left corner of Banner ad on Y-axis, where the top side is Y=0
Number
Visible
Set whether the Banner ad component is visible
True/False
Interstitial ads are full-screen ads that cover the interface of their host app.
These should displayed at natural transition points in the flow of an app, eg. between activities, between levels in a game. The user can click on or close the ad.
There is a limit of one interstitial ad component per app, but you can show the ad multiple times.
To add an Interstitial ad to your app:
Go to your Blocks tab
Click on the icon next to the Ads drawer of blocks
Select AdMob Interstitial
You will see a dialog where you can set the following properties:
Ad Unit ID (Android)
Ad Unit ID for showing your ad on Android devices
Text
Ad Unit ID (iOS)
Ad Unit ID for showing your ad on iOS devices
Text
Test Mode
Toggle whether real ads or sample ads should display in your app. Set this to true while testing your own app.
True/False
Use the when Ad Open and when Ad Close blocks to trigger events to happen when the interstitial ad opens or closes.
Use the Show Ad block to show an interstitial ad in your app. If there is an error, the error block will catch and return it.
Ad Unit ID (Android):
Ad Unit ID (iOS):
Test Mode:
Rewarded video ads are recommended after a user has completed a heavy task in your app and would be willing to watch a long video to continue.
There is a limit of one rewarded video ad component per app, but you can show the ad multiple times.
To add an Rewarded Video ad to your app:
Go to your Blocks tab
Click on the icon next to the Ads drawer of blocks
Select AdMob Rewarded Video
You will see a dialogue where you can set the following properties:
Ad Unit ID (Android)
Ad Unit ID for showing your ad on Android devices
Text
Ad Unit ID (iOS)
Ad Unit ID for showing your ad on iOS devices
Text
Test Mode
Toggle whether real ads or sample ads should display in your app. Set this to true while testing your own app.
True/False
Use the when Ad Close block to trigger events to happen when the Rewarded Video ad closes.
Use the Show Ad block to show the ad video, and the Reward User block to reward the user after displaying the video.
Ad Unit ID (Android):
Ad Unit ID (iOS):
Test Mode:
For your convenience, we have provided a test Ad Unit ID
for you to see how a particular ad format may appear in your app. You must change this to your own Publisher and Ad Unit ID before publishing.
During live test, all AdMob ads will be set to test mode = true
, which means clicks and impressions will not be counted.
This is true even if you add your own Ad Unit ID
and set test mode = false
.
test mode = false
To protect the integrity of your account, we have by default set test mode = true
.
When you are ready activate your ads when you publish, you'll simply need to set test mode = false
.
Once approved, apps can be downloaded and published without further review.
With iOS 14.5 and above, your app users will be asked if they consent to an advertising identifier being used to show them personalized ads. This is what the dialog looks like:
If you are not seeing ads appear in your app, it may be due to the following reasons:
Your AdMob component property test mode = true
. To activate, you'll need to flip the switch to test mode = false
Your Ad Unit ID
has not yet been activated. This may take up to a few hours
You have entered the App ID or the Publisher ID instead of the Ad Unit ID which begins with ca-app-pub-xxx
Please check the mobile device internet connectivity or disable ad blockers on the mobile device
Your setup is correct. The issue is that AdMob does not always have an ad to return for every request. This may happen particularly if you have just registered your AdMob publisher ID, as it takes some time and multiple requests before the new ID starts returning ads
Adding error handling to your AdMob blocks can better help troubleshoot issues
A Time Input component allows your app's user to easily select a specific time using the native Android or iOS date picker.
Style
Format to use when displaying selected time
Select from menu [Hour:Minute AM/PM, Hour:Minute 24h]
Font Size
Size of font when displaying time
Number
Font Style
Select whether font is italic
True/False
Font Weight
Select whether font is bold
True/False
Color
Color of font when displaying time
Color
X
Location of top left corner of Time Input on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Time Input on Y-axis, where the top side is Y=0
Number
Height
Height of Time Input in pixels
Number
Width
Width of Time Input in pixels
Number
Resize Mode
Define dimensions of the time input component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Time Input
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Time Input in pixels
Number
Border Radius
Radius of corners of border on Time Input in degrees
Number
Shadow Color
Color of Time Input's shadow
Color
Shadow Opacity
Opacity of Time Input's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Time Input's shadow in pixels
Number
Shadow Offset
How far Time Input's shadow should be offset, in Height and Width, in pixels
Number
The time that a user selects will show up automatically in the Time Input label but if you want to save the time somewhere to be uploaded later, you'll need to add a block like the one below.
Get Time
Time in whichever format you specify
Get Hours
Hour of the Day from 1-24
Get Minutes
Minutes from 1-60
Fires when the user has selected a time with the Time Input
Launches the Time Input picker for the user to select a time.
Returns the hour of the currently selected time in 24 hour format.
Example: if the user selects 2:30 PM, this block will return 14.
Returns the minute of the currently selected time.
Example: if the user selects 2:30 PM, this block will return 30.
Example: if the user selects 2:30 PM, and the Style is set to Hour:Minute AM/PM, this block will return 2:30 PM.
If the user selects 2:30 PM, and the Style is set to Hour:Minute 24h, this block will return 14:30.
Returns the height/width of the Time Input on the device screen in pixels.
Set the background color of the Time Input as it is displayed in the project.
Set the Text Alignment of the Time Input to Auto
, Left
, Right
, Center
or Justify
.
A Date Input component is helpful when you want the user of your app to easily select a specific date using the native Android or iOS date picker
Style
Format to use when displaying selected date
Select from menu [YYYY-MM-DD, MM/DD/YYYY, M/D/YY, Month Day, Year, Mth. Day, Year]
Font Size
Size of font when displaying date
Number
Font Style
Make the date's text italicized
True/False
Font Weight
Make the date's text bold
True/False
Color
Color of font when displaying date
Color
X
Location of top left corner of Date Input on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Date Input on Y-axis, where the top side is Y=0
Number
Height
Height of Date Input in pixels
Number
Width
Width of Date Input in pixels
Number
Resize Mode
Define dimensions of the date input component/container
Select from list [Stretch, Float in Place]
Visible
Toggle whether your end users can see the Date Input
True/False
Border Style
Set whether border style is solid, dotted or dashed (only visible if border width > 0)
Select from list [solid, dotted, dashed]
Border Color
Color of border (only visible if border width > 0)
Color
Border Width
Width of border around Date Input in pixels
Number
Border Radius
Radius of corners of border on Date Input in degrees
Number
Shadow Color
Color of date input's shadow
Color
Shadow Opacity
Opacity of date input's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of date input's shadow in pixels
Number
Shadow Offset
How far date input's shadow should be offset, in Height and Width, in pixels
Number
You can trigger actions to happen when an event occurs.
This event fires when the user has selected a date using the Date Picker.
Returns full date from Date Picker in format Mon., DD, YYYY.
Returns date from Date Picker in numeric form.
Eg. If February 17, 2021 has been selected in Date Picker, this block will return 17. If 5 March 2021 is selected in Date Picker, this block will return 5.
Returns date from Date Picker in numeric form.
Eg. If February 17, 2021 has been selected in Date Picker, this block will return 2. If 7 November 2021 is selected in Date Picker, this block will return 11.
Returns date from Date Picker in YYYY form.
Opens Picker of the Date Input to prompt the user to enter a date.
Returns the height/width of the Date Input on the device screen in pixels.
Set the Text Alignment of the Date Input to Auto
, Left
, Right
, Center
or Justify
.
Display text on your Canvas.
To add a Canvas Label to your app, click on the Stage of your Canvas. This will automatically bring you to the Canvas tab.
Underneath your component tree, where you would see a component menu in the Design tab, you will see your Sprite Type menu and a User Interface menu.
You can find the Canvas Label in the Unser Interface menu.
You can drag and drop the Canvas Label onto your Stage.
Connect a data source to your app in minimal time.
Add a Data Viewer List or a Data Viewer Grid to your app in order to connect to your data source:
You can use blocks to let your user create, read, update and delete information in your data source by interacting with the Data Viewer, using Data Sources blocks:
Program a sprite's speed and location
Set the X or Y value for the sprite's speed to a particular value.
Change the X or Y value for the sprite's speed by a specific amount.
Get the X or Y value for the sprite's speed.
Set or change the sprite's velocity, by a given amount, in the pointing or moving direction.
Move the sprite to the x and y location specified in the block
Set the sprite's X, Y, Z or Angle value to a specific position.
Change the sprites X, Y, Z or Angle value by a given amount.
Note: Sprite angle is measured in degrees, so should be a value between 0 and 360.
Get the sprite's current X, Y, Z or Angle value.
Note: Sprite angle is measured in degrees, so should be a value between 0 and 360
Get the X, Y, or Angle of the where the user tapped on the canvas
On the canvas, it's possible to make a sprite either draggable or to have it fixed in position.
Similarly, it's possible for other sprites to pass through a sprite, or it can be made impassable.
Finally, if a sprite is moving, it's possible to programatically cause it to stop moving.
Set the draggability or passability of the sprit
Get draggability of the sprite
Stop all sprites that are moving.
When the user clicks on the canvas these blocks will move the Sprite1
to the location that was touched.
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
Opens or Closes the drawer menu, if available. Must be used in conjunction with the
The your data is to be pulled from
AdMob is a component. All Thunkers can add AdMob to their projects and live test the ads in their apps. Only PRO Thunkers can download and publish apps that contain ads. To get started, .
Apps with large audiences can use AdMob to not only generate revenue for the creator, but in some cases, create better user experiences. For example, users may prefer to watch a to unlock extra content than pay money to unlock extra content.
You need an to show ads in your project.
Once you have an AdMob account, you will need to paste the following into the :
(if publishing to App Store)
(if publishing to Play Store)
(if publishing to App Store)
Once you have published your app, you will also need individual for each AdMob component in your project. To add an Ad Unit ID:
An invitation to this network will be sent to you the first time you submit your app for review. If you do not change AdMob accounts, this only needs to be done once, when you .
All apps with AdMob must be first approved by Thunkable before they can be downloaded or published. AdMob has its that an app must comply with including but not limited to:
There is a maximum of 1 Banner ad allowed per screen. You can show multiple banners in a single multi-screen app. You can learn more about best practices for implementing and using banners .
To show an interstitial app, you need to first add the component and then add the after the appropriate event in your app.
Set and get of your Interstitial ad.
Rewarded Video Ads are full-screen video ads that users have the option of watching in full .
To show a rewarded video app, you need to first add the component and then add the after the appropriate event in your app.
You'll then want to add a to reward your user in the app. You can learn more about best practices for implementing and using Rewarded Video ads .
Set and get of your Rewarded Video ad.
Downloading your app with test mode = false
to generate more impressions/clicks for your ads is considered and may lead to your AdMob account being suspended or disabled.
You can set a personalized Tracking Usage Description in your . All characters in your Tracking Usage Description must be alphanumeric or an underscore [a-z A-Z 0-9 _]
If this permission is declined, your app will still show ads. These will be more generic ads and won't be targeted at the user.
If the user has turned off the Allow Apps to Request to Track
property in their device settings, this permission will be declined by default and they will not see this dialog.
Your AdMob account has been disabled due to a policy violation. Please sign in to
Check your app's . Only apps with a Ready status will be served ads.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
Returns the selected time in the same format as the Style of the Time Input.
Set and get of the Time Input
Set and get of the Date Picker.
The Canvas Label is a piece of text that can be placed onto your .
Read about the Canvas Label blocks in the section of the Gaming Blocks docs.
This is a gallery of Sprites that have been awarded to the winner (as voted by the Community) of our Game Design challenges. This is a part of our Weekend Design Challenge challenge calendar. You can find these Weekend Design Challenges in our .
Property
Description
Data Type
Text
The Text being displayed on your Canvas Label
Text
X
The X-co-ordinate of the top-left pixel of the Canvas Label
Number
Y
The Y-co-ordinate of the top-left pixel of the Canvas Label
Number
Font Size
The size of the font of the Canvas Label
Number
Color
The color of the text of the Canvas Label
Color
Background Color
The color of the background of the Canvas Label
Color
Stage Selection
Select a Stage to display the current Canvas Label on
Select from menu
Create interactive gaming apps with the canvas component.
The canvas component is a touch-sensitive panel that enables the movement of items.
You can use this component to create a variety of games and experiences that involve different methods of touching a screen.
To add a canvas to your app, drag and drop the canvas component into the app builder.
When you click on the Canvas in your component tree, Canvas tab will appear. Click on this tab to customize your canvas
The three elements of a Canvas are the Stage, the Sprites, and the Canvas Label.
The Stage is the background of your Canvas. You can set a background color or background picture, a border color, and the stage's Height and Width. You can click and drag your Sprites on the stage in the Canvas tab.
You can set Gravity of the Stage along the X and Y axis. The Sprites on the stage can be toggled to ignore gravity or not. If a Sprite is affected by gravity, it will be pulled in the direction of the gravity.
Your Canvas Stage will automatically scale up in order to match the size of the device screen. If the aspect ratio of the Stage does not match the aspect ratio of the device, you can use Stage Scaling Mode to resize the background to fill the device screen.
Scale: The aspect ratio of the background will be maintained, and the background will be scaled up. May result in some of the background being cropped.
Stretch: The background image will be stretch in order to fill the screen. May result in the background image being distorted.
Select how you want your background image to be centered when it is scaled to match the device screen.
Can be set to center, center horizontally only, center vertically only, or none.
You can enable Touch Drawing on your Screen. You can set the Drawing Color to choose the color you draw in. You can set the Drawing Width to choose the thickness of the line you draw on the stage.
You can add multiple stages to a Canvas component, in the same way you can add multiple Screens to an app project. when you have selected your Canvas tab, click on the + next to your Stage name to add another Stage to the Canvas.
Each Stage has its own Sprites, background color, gravity, etc.
How to set up and organize your app.
To go from an idea to an app, we strongly recommend sketching out your vision using the below app templates. It's important to design a roadmap for how people will interact with your app.
Most apps navigate through screens using navigators. Four navigator options are available in Thunkable: bottom tab, top tab, drawer, and stack navigators.
This navigator allows your app's user to change screens by clicking on icons at the bottom.
This navigator allows your app's user to change screens by clicking on icons at the top.
This navigator pulls out a side menu or drawer of navigation options for the app user to select.
This navigator stacks screens from left to right or top to bottom.
The Rating component is a visible component which can be used to display the rating of a product or content in your app, and allow the user to leave their own rating.
A Rating component is made up of 5-10 icons. An icon can be filled, partially filled, or empty, as seen below:
Value
Initial value of your rating
Number
Count
Max value of your rating
Number between 5 and 10
Image*
Shape of the icons in your Rating component
Select from menu (Pick One or Custom Image)
Read Only
Toggle whether or not the user can edit the rating
True/False
Rating Color
Color of filled-in icons to reflect the current rating
Color
Background Color
Color of unfilled icons
Color
There are two ways to set an Image for your Rating component:
If you set the Image property to Custom Image, you will be able use your own images as icons for the Rating component.
Selecting Custom Image will show two new properties:
Filled Image
Images to reflect 'filled-in' icons to reflect the current rating
Image file name
Empty Image
Images to reflect 'unfilled' icons
Image file name
These URLs must end in a file extension, such as .jpg or .png.
Property
Description
Data Type
X
Location of top left corner of Rating component on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of Rating component on Y-axis, where the top side is Y=0
Number
Height
Height of Rating component in pixels
Number
Width
Width of Rating component in pixels
Number
Resize Mode
Define dimensions of the Rating component/container
Select from list [Stretch, Float in Place]
This block fires when a user enters a rating in the Rating component.
Select how the Rating component is displayed: as a row (left-right), row-reverse (right-left), column (top-bottom), or column-reverse (bottom-top).
Change the size of the icons that make up the Rating component.
Get or change the size of the margin between the icons of the Rating component.
You can upload your own images to be displayed for filled and empty icons.
Create powerful, no-code, data-driven apps connected directly to Google Sheets, Airtable, or stored locally.
The Data Viewer List lets you connect to a Data Source and view your data as a list.
Data Source
References chosen data source
Table
Table from your Data Source to show data from
Reference to chosen table in Data Source
Row Appearance
How your data will be displayed in your app
Select from list
Populate Data
Select what items of data from your Data Source to show in which aspects of your layout
Select from lists
Left Swipe
Toggle whether your end user can swipe a list item to the left to view an additional Button. Reveals Left Swipe Button settings if set to true
True/False
Left Swipe Button Text
Text of Button visible when user swipes list item to the left
Text
Left Swipe Button Text Color
Text Color of Button visible when user swipes list item to the left
Color
Left Swipe Button Background Color
Background Color of Button visible when user swipes list item to the left
Color
Right Swipe
Toggle whether your end user can swipe a list item to the right to view an additional Button. Reveals Right Swipe Button settings if set to true
True/False
Right Swipe Button Text
Text of Button visible when user swipes list item to the right
Text
Right Swipe Button Text Color
Text Color of Button visible when user swipes list item to the right
Color
Right Swipe Button Background Color
Background Color of Button visible when user swipes list item to the right
Color
Empty Text
Text that will be displayed if there is no data to fill a string in your Data Viewer
Text
X
Location of top left corner of component on X-axis, where the left hand side is X=0
Number
Y
Location of top left corner of component on Y-axis, where the top side is Y=0
Number
Height
Height of component in pixels
Number
Width
Width of component in pixels
Number
Resize Mode
Define dimensions of the Data Viewer List component/container
Select from list [Stretch, Float in Place]
The Item Click event is fired when any list item in the Data Viewer is clicked. It returns a row id
which corresponds to the unique Thunkable Id of the item that was clicked. The row id is most useful when used with the the Data Source blocks.
The left and right swipe click events are fired when these buttons are clicked. Both return a row id
to quickly identify which row was clicked when using the Data Source blocks
Refresh the Data Viewer List to sync with the Data Source.
Get the computed Height and Width of the Data Viewer List as it appears on-screen.
Set and get the Visible property of the Data Viewer List
Set and get the Empty Text property of the Data Viewer List
When you connect a Data Source to your project you will also have access to a second block drawer. These Data Source blocks allow you to perform a variety of CRUD (Create, Read, Update, Delete) operations on your data.
Click on the link below to learn how to use the Data Sources blocks in your project.
Connecting your project to a data source allows you to work with the information that you have stored in Airtable, Google Sheets, Webflow or a local table.
The data sources blocks allow you to perform a variety of CRUD (Create, Read, Update, Delete) operations on records you have stored in Airtable, Google Sheets, Weblow or a local tables.
There are two ways to connect your app to a source:
Add a Data Viewer (list or grid) to your project. More on Data Viewers is available here: Data Viewers, OR
Click the Data Sources icon in the menu on the far left and click the ⊕ icon.
In the modal that appears, select a previously connected Data Source, or add a new one.
To create your own table as a data source:
Give your local data source table a name.
Click Create.
To add data to your local table, copy and paste it from another source or click into a cell and type to input the data.
To modify the table's columns:
To update the table’s column headers, click their names and typ a new header name.
To add additional columns, click the + New Column button.
To delete columns, click the x in the column’s title box.
To modify the table's rows:
To add additional rows, with your cursor in the bottom row, press your keyboard’s enter or return key.
To delete a row, right-click on it and select Remove row.
Select your preferred storage option:
App Data Source - If the data is changed while the app is open, the table's data resets when a user of your app closes and reopens the app. This reduces the time it takes for the app to load on the user's device.
Stored Data Source - If the data is changed while the app is open, the table's data persists when a user closes and reopens the app.
When your table is complete, click the X in the upper right.
The newly created local data source is now listed in your project's list of data sources.
Click the pencil icon to rename the data source.
Click the data source's name to review and edit the data.
Click the trash can icon to delete the data source from your project.
API Key (supported until Jan 31, 2024)
OAuth
Navigate to your Airtable account page.
Copy your API key (a 14-character code beginning with "key").
Return to your Thunkable tab.
Paste the copied Airtable API token into the corresponding field.
Click Refresh to see your Airtable bases.
Select the base you want to use as your data source.
Click Create.
Click Connect to Airtable.
An Airtable authorization screen opens.
Click + Add a base.
Select the bases you want to authorize access to.
Click Grant access.
Select the correct base from the dropdown menu.
Click Create.
In Airtable, a table is similar to a sheet in a spreadsheet. You can have multiple tables within your Airtable base, and each table can have multiple views. A view indicates how the data is presented within the table. For example, you can use views to show only specific fields or records and apply other configurations to manage the information in that view. The initial default view for an Airtable table is the grid view.
When connecting an Airtable base as your Thunkable project’s data source, you can select a custom view instead of the default grid view. This will apply only to the first table in your base. For subsequent tables, Thunkable will use the default grid view. If you have a base with two tables and the second table has a custom view, you can reorder the tables within the base in Airtable so that the custom view is applied to the correct table.
Once you've connected your Airtable the Thunkable account via OAuth, API keys are no longer used.
In Google Sheets, the entire document is considered to be the data source.
To use a Google Sheet as a data source the following must be true:
The first row in your sheet must be a header row and every column must have a header.
To connect a Google Sheet, sign in and grant permission for your Thunkable project to access your Google Drive.
Some users have reported issues connecting to Google Sheets if they are using G Suite for Education accounts. You may need to contact your G Suite administrator to review your security settings.
Once you have allowed this, you will see a list of spreadsheets in your Google Drive. If you don't see the sheet you are looking for you can switch to list view, sort alphabetically or search for the one you need. Click Select
to return to your Thunkable project.
At this time, connecting to .xlsx files that are hosted on Google Sheets is not supported. You can convert your .xlsx file to a Google Sheet before connecting it to your Thunkable app project. Simply open your .xlsx file on Google Sheets, then click File > Save as Google Sheets.
When using Weblow as the data source for your Thunkable app, you’ll connect to a Webflow CMS or Content Management System collection.
To connect your Webflow CMS to your Thunkable project, you have two options:
API Key
OAuth
Within the Webflow platform:
Navigate to your site settings.
Click the Integrations tab
Under the API access header, click Generate API token.
Copy the Webflow API token.
Within the Thunkable platform:
Paste the copied Webflow API token into the corresponding field.
Click Refresh to see your Webflow sites.
Select the site you want to use as your data source.
Click Create.
Click Connect to Webflow.
A Webflow authorization screen opens.
Select the sites or Workspaces you want to authorize access to.
Click Authorize app.
The create row in
block allows you to append new rows to the end of your data tables.
The inputs are dynamic so if you change the name of Column 1 or Column 2 in the designer these changes will be reflected in the block too.
The get value from
blocks allows you get read one value from a specific cell in your data table. You can specify the column name in the block itself and pass the unique row id as an input.
Note that each row has its own unique 24 character ID. You must use this ID to refer to rows of your Airtable and Local data sources in the blocks below.
If your data source is a Google Sheet, you can refer to the row by its integer position (1 for the first row, 2 for the second row, etc.)
The number of rows in
block returns an integer corresponding to how many rows are in a given table.
You can use the update value in
block to modify or update an existing cell in your data table. The column name is specified in the block itself. Both the row id and new value are passed as inputs.
You can use the Delete Row
block to delete a row of data from your Data source.
The row id
is passed as an input.
If there is an error
, the error message is passed as an output.
You can use the delete all rows
block to delete all rows in your data source.
If there is an error
, the error message is passed as an output.
Learn how to program the canvas and sprite components.
When you add a canvas to your project, you will get 7 additional categories of blocks. Each of these categories will allow you to programatically control what happens with your sprites and sprites types, on the canvas and the stage.
Get the distance between two sprites
Get the distance between a sprite and a point
Get angle between sprites
Gets the closest instance of the provided sprite type to the given sprite
Select which Stage to display in the Canvas.
Sets the background color of the specified Stage.
Returns the hexadecimal value of the background color for the specified Stage.
Sets the color of the Frame for the specified Stage.
Returns the hexadecimal value of the Frame Color for the specified Stage.
Set the background image of the stage to the specified item in the list.
Set the Stage's height in pixels
Returns the Stage's height in pixels
Set the Stage's width in pixels
Returns the Stage's width in pixels
Sets the Stage gravity in the vertical direction.
Returns the value of the Stage gravity, in the vertical direction.
Sets the Stage gravity in the horizontal direction.
Returns the value of the Stage Gravity, in the horizontal direction.
Enable drawing on the stage if set to true
.
Disable drawing on the stage if set to false
.
Return true or false, depending on whether or not drawing is enabled on the Stage.
Set the Drawing Color, or Line Color, for the stage.
Returns the hexadecimal value of the Drawing Color for the specified Stage.
Set the Drawing Width, or Line Width, for the stage.
Returns the numeric value for line width on the Stage.
Program a sprite's image, size, and visibility
Show the selected sprite or hide the selected sprite on the canvas.
Returns true if the sprite is visible, and false if it is hidden
Set the Sprite's height or width.
Change the sprite's height, width, or opacity.
Get the sprite's height or width.
Flip Sprite along a specified axis.
Add freeze frame of sprite in current position.
Draw line between two points with specified width and color.
Draw circle outline at specified point with a given radius.
Draw filled circle at specified point with a given radius.
Draw a polygon outline at a specified point. The number of sides, length of sides, and angle of rotation (measured in degrees) can be specified.
Draw a filled polygon at a specified point. The number of sides, length of sides, and angle of rotation (measured in degrees) can be specified.
Clear all the drawings on the specified canvas.
Get an image of the specified canvas. Returns a base 64 encoded image.
Program a sprite's direction
Turn the sprite in the direction of where the user has tapped on the canvas
Turn a sprite in the direction of another sprite
Set or change the angle of the sprite.
Get the angle of the sprite
Set or change the angular velocity of the sprite.
Get the angular velocity of the sprite.
Navigate to different screens using a clickable drawer that slides out from the side.
You can watch a video tutorial for using Navigators in your Thunkable app here:
To add a navigator to your app, click Screens + at the top of your component tree. Select Add Navigator and select the Navigator you want to add.
Within the component tree, drag and drop screens to nest them under the Drawer Navigator component.
Once a screen has been added to the drawer navigator, a new section in the screen's properties panel, Drawer Navigation Options, becomes available. This is where you define the screen's label that displays in the user's drawer navigator.
You have many options for styling your Drawer Navigator, such as changing the background color or tint color. Here are the different options for customization:
Navigate to different screens using a bottom tab navigator.
To add a navigator to your app, click Screens + at the top of your component tree. Select Add Navigator and select the Navigator you want to add.
You have many options for styling your Bottom Tab Navigator, such as changing the background color or tint color. To access the navigator's properties panel, click the Bottom Tab Navigator's name in the component tree. Here are the different options for customization:
To access the properties panel for a specific tab, click the screen name in the component tree.
The status bar is located at the top of a phone's screen. The status bar displays information regarding signal strength, battery, and whether or not things like the alarm or wi-fi are enabled.
Possibly the most common style of navigation in mobile apps is tab-based navigation.
The Top Tab Navigator is positioned at the top of your app, and allows users to switch between different screens by clicking.
To add a navigator to your app, click the dropdown arrow at the top of your component tree. Select Add Navigator and select the Navigator you want to add.
You have many options for styling your Top Tab Navigator, such as changing the background color or tint color. To access the navigator's properties panel, click the Top Tab Navigator's name in the component tree. Here are the different options for customization:
When designing a tab, you can use words or images to guide users to different screens.
To access the properties panel for a specific tab, click the screen name in the component tree.
The status bar is located at the top of a phone's screen. The status bar displays information regarding signal strength, battery, and whether or not things like the alarm or wi-fi are enabled.
You can create a list of variable lengths with the blocks below
Creates an empty list
Allows you to specify what items in what order you want in your list
Creates a list of a given item repeated a specified number of times.
Create a list between two numbers, with a chosen increment.
Eg. list of 1 to 5 by 1 is [1, 2, 3, 4, 5]
. List of 2 to 10 by 2 is [2, 4, 6, 8, 10]
This block lets you create a list from text and even lets you set delimiters i.e. ","
You can also use this block to make text from a list with a given delimiter
If you are importing a list from a Spreadsheet or other data source, it may be helpful to sort it in your app. You can sort a list alphabetically or numerically, ascending or descending
The following blocks analyze a list in different ways
Returns the length of a list as a number.
Checks if a list is empty. Returns true or false.
Returns the position of the first or last occurrence of an item, where the index of the first item is 1. Returns 0 if the item is not in the list.
Checks if a given list contains a given item. Returns true or false.
Returns the result of the chosen operation on a list of numbers. Returns NaN if the operation cannot be performed on the given list of values.
Items in a list have an index number. The first item is 1, second is 2 and so on. You can get:
Item at position X
Item X items from the end of the list
The first item
The last item
A random item
Behaves the same as the Get block, except the chosen item is removed from the list.
Returns random item of list.
Returns a sub-list of items between two positions in a longer list.
Get a copy of a list with the items shuffled in a random order.
You can change an item in your list with the blocks below
This block will either insert an item at the specified location, or set the item at the specified location to the new value.
Removes the item at the specified position from a list
Create interactive gaming apps with sprites.
Sprites are images that can be placed on the Stage in the Canvas. They can react to being touched or dragged across the screen, or colliding with other sprites or the edge of the screen.
A Sprite Type is a category of Sprites that you can add to your app. For example, in a video game you might have a Main Character Sprite Type and Obstacle Sprite Types.
A Sprite is a single instance of a Sprite Type. In the video game example, you could have a single Obstacle Sprite Type, but multiple Obstacle Sprites in your app. They would be multiple Sprites of the same Sprite Type.
Groups of sprites that have the same behavior should belong to the same sprite type. In the example below, WallType is a Sprite Type, and there are multiple Sprites of this type in the app (ie. the walls).
Whenever the ball touches any of the WallType Sprites, the ball goes back to its starting location.
To add a Sprite Type to your app, click on the Stage of your Canvas.
This will automatically bring you to the Canvas tab.
Underneath your component tree, where you would see a component menu in the Design tab, you will see your Sprite Type menu.
You can click on 'Add Sprite Type' to add a new Sprite Type to your app.
Click on the Canvas to see the menu of Canvas components you can add to your project.
You will see this menu under the component tree, where the Component menu is usually shown in the Designer.
Select a Sprite Type and drag it onto your Canvas to create an instance of a Sprite Type. This is a single Sprite.
In the below GIF, there is a canvas with a Sprite, called Sprite1. There is also a Sprite Type in the Sprite Type menu called Sprite_Type1. When a Sprite is dragged from Sprite_Type1 and dropped onto the Canvas, we see a new Sprite, called Sprite_2.
In the GIF below, we see that when one Sprite (the Thunkable Beaver) collides with another Sprite (the tree trunk), the appearance of the Tree Sprite changes.
This demonstrates the following:
Picture List: we see the image displayed by the Tree sprite changing
Bounce: We see the Beaver sprite bounce off of the Tree sprite. As it bounces, it has a speed of 50% of its original speed
Passes Through: the Beaver Sprite does not pass through the Tree sprite until it has collided with the Tree sprite 3 times
Z: The Beaver sprite has a higher Z-value than the Tree sprite, so the beaver passes in front of the tree
Thunkable provides a menu of pre-set icons from Expo that you can choose from.
You can upload your images as to your project, or provide URLs that point to your chosen images.
Set and get of the Rating component
You can select an image from the list available. All of the image options are suitable for any platform. You can preview the image options .
The your data is to be pulled from
Set and get of the Data Viewer List.
When connecting to a new data source, select from one of the following options: • • • •
Follow the steps above: and select Create your own table.
When using as your data source, a base is connected to Thunkable. To connect your Airtable base to your Thunkable project, you have two options:
Your Google Sheet must be so that Thunkable can access the data.
Looking to reset your Google Sheets connection? for instructions
Get row object
will return the row object of the specified row ID. The row object can be used with
The list of values in
block allows you to read an entire column of data from a table and returns it as a list that you can then manipulate with the built-in .
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
Please refer to the to see some animated examples of the gravity properties.
Set the sprite's image to the next or previous image in the sprite type's .
Set the sprite's image to an image in the sprite type's .
You can read more about the Stage's gravity properties .
Check out the to see the blocks available to use with Sprites in your project.
Drawer Width
The width of the Drawer in pixels.
Number
Drawer Position
The position the Drawer enters the screen from.
Select from menu (left or right)
Active Tint Color
Text color of selected drawer.
Color
Active Background Color
Background color of selected drawer.
Color
Inactive Tint Color
Text color for unselected drawers.
Color
Inactive Background Color
Background color for unselected drawers.
Color
Active Tint Color
Select a text color for the tab currently in use.
Color
Active Background Color
Select a background color for the tab currently in use.
Color
Inactive Tint Color
Select a color for the text of the tabs that are not in use.
Color
Inactive Background Color
Select a color for the tab not currently in use.
Color
Show Label Icon
Select whether to show icons, labels, or both in the Tab Navigator.
Select from menu
Visibility
Decide whether you want the status bar visible on the screen.
True/False
Style
Default is best practice, but you can select light-content or dark-content to potentially override the user's phone settings.
Select from menu (default, light-content, dark-content)
Color (Android only)
Color of the status bar.
Color
Translucent (Android only)
When translucent is set to true, the app will appear under the status bar.
True/False
Swipe Enabled
Allow the user to swipe between screens.
True/False
Animation Enabled
Select whether to animate the transitions between screens.
True/False
Lazy
If true
, tabs are only loaded once the tab is opened. If false
, all tabs are loaded when the Tab Navigator is first opened.
True/False
Background Color
Select a color for the top tab navigator.
Color
Tab Indicator Color
An underline will appear underneath the tab you select. You can select a color for the underline
Color
Active Tint Color
Select a text color for the tab currently in use.
Color
Inactive Tint Color
Select a color for the text of the tabs that are not in use.
Color
Show Label Icon
Select whether to show icons, labels, or both in the Tab Navigator.
Select from menu
Uppercase Label
Make the text for all the tabs upper case.
True/False
Press Color (Android only)
Color of material ripple as a tab is pressed.
Color
Press Opacity (Android only)
Opacity of material ripple as a tab is pressed.
Number
Tab Indicator Height
An underline will appear underneath the tab you select. This section will allow you to choose how tall the underline is.
Number
Visibility
Decide whether you want the status bar visible on the screen.
True/False
Style
Default is best practice, but you can select light-content or dark-content to potentially override the user's phone settings.
Select from menu (default, light-content, dark-content)
Color (Android only)
Color of the status bar.
Color
Translucent (Android only)
When translucent is set to true, the app will appear under the status bar.
True/False
Picture List
Images that can be shown with the given Sprite Type
Image files
Height
Height of the sprite picture.
Number
Width
Width of the sprite picture.
Number
Angle
Change the angle of the sprite. The angle is measured in a clockwise direction and is measured in degrees, eg. setting the angle to 30 will rotate your sprite 30 degrees clockwise
Number
Z
Control the sprite's depth on the screen and the overlap of sprites. Sprites with a higher value for Z will overlap the sprites with a lower Z value.
Number
Opacity
Change the opacity of the Sprite, where 100% is max opacity and 0 is max transparency
Number
Bounce
When a sprite hits a surface or another sprite, this is the percentage of the speed that sprite with bounce back with. A bounce of 100 means that the sprite will bounce back at the same speed it had in its collision. A bounce of 200 will cause the sprite to bounce off with twice its speed.
Number
Is Draggable
Toggle whether the player can drag the Sprite Type
True/False
Passes Through
Toggle whether Sprite Type passes through other Sprites
True/False
Is Static
Toggle whether Sprite Type's location is fixed
True/False
Ignore Gravity
Toggle whether of not the sprite is affected by the Stage's gravity
True/False
Fixed Rotation
Toggle whether Sprite Type's Angle can be changed
True/False
Drawing
Toggle whether Sprite Type draws a line as it moves
True/False
Drawing Color
Toggle color of line drawn when Drawing is true
Color
Drawing Width
Width of line drawn when Drawing is true
Width
Name
Description
Data Type
Picture Selection
Select an image from the Picture List defined in the Sprite Type to display on the SpriteImage files
Select from menu
X
Location of the top-left pixel of the Sprite on the X-axis of the stage, where the left-hand side is 0
Number
Y
Location of the top-left pixel of the Sprite on the Y-axis of the stage, where the top is 0
Number
Z
Where the Sprite is in the depth of the Canvas. A Sprite with a higher Z-value will appear in front of a Sprite with a lower Z-value.
Number
Height
Height of the sprite picture.
Number
Width
Width of the sprite picture.
Number
Angle
Change the angle of the sprite. The angle is measured in a clockwise direction and is measured in degrees, eg. setting angle to 30 will rotate your sprite 30 degrees clockwise
Number
Opacity
Change the opacity of the Sprite, where 100% is max opacity and 0 is max transparency
Number
Bounce
When a sprite hits a surface or another sprite, this is the percentage of the speed that sprite with bounce back with. A bounce of 100 means that the sprite will bounce back at the same speed it had in its collision. A bounce of 200 will cause the sprite to bounce off with twice its speed.
Number
Stage Selection
The stage the sprite is part of.
Select from list
Is Draggable
Toggle whether the player can drag the Sprite Type
True/False
Passes Through
Toggle whether Sprite Type passes through other Sprites
True/False
Is Static
Toggle whether Sprite Type's location is fixed
True/False
Ignore Gravity
Toggle whether of not the sprite is affected by the Stage's gravity
True/False
Fixed Rotation
Toggle whether Sprite Type's Angle can be changed
True/False
Drawing
Toggle whether Sprite Type draws a line as it moves
True/False
Drawing Color
Toggle color of line drawn when Drawing is true
Color
Drawing Width
Width of line drawn when Drawing is true
Number
Navigation Button Name
Text that appears in the top tab navigator.
Text
Scrollable
Select whether your user can scroll on this screen. For scrollable to work, the components in your screen must have heights either set in absolute
pixels or set to fit contents.
True/False
Background Color
Select the tab's background color.
Color
Background Image
The image file to be shown in the tab's background
Background Image Resize Mode
Set how image is shown if the file and the tab component have different dimensions/aspect ratio
Select from list [cover, contain, stretch, repeat, center]
Orientation (iOS and Android only)
Toggle whether your end user can swipe a list item to the left to view an additional Button. Reveals Left Swipe Button settings if set to true
True/False
Tab Bar Label
Set the Label of this Screen's tab in the Tab Navigator
Text
Active Tab Icon
Set the Icon of this Screen's tab in the Tab Navigator for when the Screen is active
Inactive Tab Icon
Set the Icon of this Screen's tab in the Tab Navigator for when the Screen is inactive
Tab Bar Visible
Set whether the Tab Navigator is visible when this Screen is open
True/False
Navigation Button Name
Text that appears in the top tab navigator.
Text
Scrollable
Select whether your user can scroll on this screen.
True/False
Background Color
Select the tab's background color.
Color
Background Image
The image file to be shown in the tab's background
Background Image Resize Mode
Set how image is shown if the file and the tab component have different dimensions/aspect ratio
Select from list [cover, contain, stretch, repeat, center]
Orientation (iOS and Android only)
Toggle whether your end user can swipe a list item to the left to view an additional Button. Reveals Left Swipe Button settings if set to true
True/False
Tab Bar Label
Set the Label of this Screen's tab in the Tab Navigator
Text
Active Tab Icon
Set the Icon of this Screen's tab in the Tab Navigator for when the Screen is active
Inactive Tab Icon
Set the Icon of this Screen's tab in the Tab Navigator for when the Screen is inactive
Tab Bar Visible
Set whether the Tab Navigator is visible when this Screen is open
True/False
To enable a Stack transition, add a Screen navigation block like the one below. You can find the Screen navigation block in the Control drawer of blocks:
Mode
Define how your screens will stack.
Select from list:
card
- new screens slide in from the left
modal
- new screens slide in from the bottom
It is possible to hide the Header bar and maintain the Stacking transition by using the Stack property below. Hiding the Header bar will also hide the back button that makes it easier to transition to the previous screen.
HeaderMode
Define how the header appears in your app.
Select from list:
float
- headers fade in with the screen change
screen
- headers slide with the screen change
none
- hide header (including the back arrow)
Events Blocks: Blocks that program the canvas to respond
Program an action after the canvas loads.
Program an action when the user touches the canvas
Please note, that for the sprite events, event handlers can be configured to work with an entire type of sprite or just with one specific sprite.
This event triggers when the sprite is clicked.
This event triggers when the two sprites collide.
This event triggers when the sprite collides with the defined edge.
This event triggers when the user stops dragging the sprite.
Set the text being displayed in the Canvas Label.
Get the text of the Canvas Label.
Set the X Co-ordinate of the top-left pixel of the Canvas Label.
Get the X Co-ordinate of the top-left pixel of the Canvas Label.
Set the Y Co-ordinate of the top-left pixel of the Canvas Label.
Get the Y Co-ordinate of the top-left pixel of the Canvas Label.
Set the font size of the text of the Canvas Label.
Get the font size of the text of the Canvas Label.
Set the color of the text of the Canvas Label.
Get the color of the text of the Canvas Label.
Set the color of the background of the Canvas Label.
Get the color of the background of the Canvas Label.
Move the Canvas Label to the named Stage.
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
PNG, JPG, GIF, SVG, etc. Can also use URL that ends in file extension (eg )
The Canvas contains the Stage where your Sprites are displayed. Read more in the .
Sprites are the elements on your stage that represent characters, obstacles, and more. Read more in the
Use the Canvas Label to display text on your Canvas. Read more in the docs.
You can use blocks to change the appearance and behavior of your Stage and Sprites. Read more in the
An app is simply a sequence of events.
This is where Thunkable Blocks come in.
Thunkable Blocks are the building blocks of a great experience for your app users. Every component has its own set of blocks to start or trigger an event and set and change properties.
They can be connected to a commonly used set of blocks that range from opening screens, setting up logic, reformatting data or simplifying code.
The best apps define an elegant sequence of events that happen without the user even noticing. A great sign in flow for example can happen in seconds but the logic and sequence behind them is a work of art that has been iterated on many times (often using Thunkable's app).
In app creation, variables work like containers to hold numbers, phrases, the results of a calculation, a database call, or other important values in the app, in the mobile device itself or in the cloud.
Instead of repeating these values in multiple places, a variable can be used wherever it is needed in your Blocks code.
Variable names can only contain alphanumeric characters and underscore. Invalid characters may cause your app to crash.
App
, stored
and cloud
variablesWhen you create a variable, you'll have the choice between an app, stored and cloud variable. All variable types work across screens and the only difference is where they are stored.
An app variable works across screens and is stored in the app itself. You can save any data type as an app variable.
A stored variable also works across screens but is saved to the mobile device itself. This means that a stored variable can be retrieved from a previous session.
You can save any data type as a stored variable.
Cloud variables can be used similar to saving and retrieving values to a Realtime DB powered by Firebase and can be used in a number of applications that share data across users in the cloud. If you use cloud variables, you no longer need to add a Realtime DB to your app.
To save a list as a cloud variable, use the 'make text from list' block to convert the list to a piece of text.
When you retrieve this text from your cloud variable, you can convert it to a list with the 'make list from text' block to work with it as a list in your app.
To create a variable when the app starts, you can grab the block above, select your variable scope
(app, stored, cloud) and give the variable a name
like hello. You'll have to connect a block to give app variables an initial value (in the picture above). We recommend placing these blocks in the initial app screen.
Variable names can only contain alphanumeric characters and underscore. Invalid characters may cause your app to crash.
You can also set a variable within a block event like the one above. Simply grab the set variable block and connect it to the value that you want it to be set to.
Variables do not have to be fixed values and there may be times when you want to change your variable automatically like incrementing it by 1 after an event. To do so, grab a block like the one above.
Once you have stored a value to your variable, you can retrieve it any time using a block like the one above.
Once you have created your variable, you can set it to update when the variable updates in your app.
With Cloud variables, this block will also be triggered when the value of the Cloud variable is changed in your Firebase DB. This block replaces the Add.Listener and DataChanged blocks in the Realtime DB.
The above blocks use hard coded variable names, where you must select a variable from a list of variables that you have initialized.
You can also create dynamically named variables. There are variables that you create and name during app runtime, which do not have an initialize block.
You can name these by typing in a name, or by using other variables to name the dynamically created variables.
You can create dynamically named app, stored or cloud variables.
Thunkable provides a default Firebase account for testing purposes. When your app is ready to be distributed, we strongly advise connecting your app to your personal Firebase instance.
Otherwise, you will need to set your Read and Write rules to true
To connect your Firebase project with Thunkable, you'll have to add an API key
and Database URL
to the Firebase Settings in the App Settings, which you can find by clicking on the gear icon on the left hand side of the Design tab.
One way to retrieve the API key
and Database URL
from Firebase is to click on the Add Firebase to your web app option
Once your project is connected to your Thunkable app, we recommend that you do a simple test and save a value into your database. It should appear in your data tab in your Firebase console.
You can find videos to demonstrate the use of , and below:
A cloud variable also works across screens but is saved to the cloud powered by Firebase. By default, the cloud variable is saved to the Thunkable default Firebase database. We recommend saving them to your own private Firebase DB by .
You can only save a piece of or an as a cloud variable.
To save media as a cloud variable, use the block to upload your audio to Cloudinary and get a URL that points to it. You can save this URL as a cloud variable.
Firebase Realtime Database also pairs well with and you can use a single Firebase project for both services.
If you are using powered by Firebase in your app, you do not need to edit the default database rules which permit reading and writing to the database for authorized users.
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
this
, do that
The if this
, do that
block can be transformed to support more complex logic
The Test block can be used to return a value based on a given condition. If the condition is true, one value is returned. If the condition is false, a different value is returned.
Wait the specified amount of time before performing the next action.
Repeat a set of blocks for a specified amount of time
Repeat an action for an unlimited period of time
Repeat an action the specified number of times
Repeat an action for a certain amount of times, with the incrementer index i
Repeat an action over every item in a list
Repeats an action while a condition is true
Break out of an existing loop
You can prompt a user to open a page within an app installed on their phone or a url in their browser using the block above.
If the device has the relevant app installed, the link will open in the app. Otherwise, the link will open in the browser.
The gyroscope is capable of measuring how quickly the phone is being turned. It measures the rate of rotation of the phone and returns values in radians per second about the x axis, the y axis and the z axis. This rate of rotation is also known as the Angular Velocity, so the gyroscope can tell us the speed of rotation of the phone. By extension, if the speed of rotation is any number greater than 0, we can infer that the phone is being turned.
To add a Gyroscope to your app:
Navigate to the Blocks tab of your project.
Under the App Features heading, locate Sensors.
Click the ⊕ symbol next to Sensor.
Select Gyroscope from the provided menu.
Click Add.
You will see a settings panel where you can set:
The Name of the Gyroscope
Whether the Gyroscope is Enabled
You can either confirm your choices and create the Gyroscope, or delete the Gyroscope.
You will see the sensors you have added to your app underneath the Sensors section of your blocks.
If you click on the ⚙ icon next to your Gyroscope, you will be able to edit its settings as seen in the panels above. You can click on your Gyroscope's name to access its drawer of blocks.
Enabled
Toggle whether the component is functioning in your app
True/False
Whenever the phone is turned, or rotated, the Changes
event will fire.
Call Alpha/Beta/Gamma, call X/Y/Z
Alpha
Number
Rotation about the y-axis
Beta
Number
Rotation about the x-axis
Gamma
Number
Rotation about the z-axis
X
Number
Angular velocity about the X axis
Y
Number
Angular velocity about the Y axis
Z
Number
Angular velocity about the Z axis
By default the gyroscope sensor is turned on, but the enabled
property can be used to read and write new values to the gyroscope, thus allowing you to turn it on or off.
Use this block to specify a number you want to use in your app.
You can also round up or down a decimal figure into an integer using the round block
You can also round a number to a selected amount of decimal places
There is also a block for irrational numbers like π
Returns true or false based on whether the chosen condition applies to the number
If the given number is of a lower value than the lower bound, this block will set the given number to have the value of the lower bound.
If the given number is of a higher value than the upper bound, this block will set the given number to have the value of the upper bound.
Perhaps the most often used calculation in an app is addition
but this block also supports subtraction
, multiplication
, division
and exponential
figures
Returns the remainder when a number is divided by another number.
There are also a few more advanced calculation blocks that may be helpful including trigonometric.
These blocks will return a value assuming the input is given in degrees.
For games and other apps, it may be important to introduce randomness into your app.
Returns integer between two given integers. Is inclusive of the given integers.
Returns a random integer between two given integers. Is inclusive of the given integers.
You can manage much of your screen navigation through our , , and navigator components but for simple screen navigation, you can use the very popular block below
In most apps, one event leads to another event if a condition is met. To specify these scenarios, the this
, do that
block is commonly used with blocks that define the conditions that lead one event to the next.
Returns a random fraction where
The blocks also have blocks for selecting .
The blocks have a block for getting certain mathematical values from a List, including
The most basic but most often used text block is below. You can type into this text block, or leave it empty.
Often, you'll want to join text values together with the join
block:
You can use the newline
block to add a line break in a piece of text.
Use these blocks to change the content or formatting of your text. These blocks will return the reformatted text.
Set a piece of text to the selected case:
Trim blank spaces from the left side, the right side, or both sides of a string of text:
Find and replace all occurrences of a substring within a string.
The block below tests whether the text value is empty. Returns true
or false
Returns the character at the specified position, where 1 is the first letter of the string. Returns the empty string if the length of text given is less than the position specified.
Returns the substring at the specified start and end position, where 1 is the first letter of the string. Returns the empty string if the length of text given is less than the starting position specified.
Returns the starting position of a substring within a string, where 1 is the first letter of the string. Returns 0 if the string does not contain the substring.
Checks if a string contains a substring. Returns true
or false
.
Returns length of a given string as a number
You can find a video that explains all of the Logic blocks below:
The comparison blocks will compare two values and return true or false based on whether the condition is met.
You can compare multiple conditions at once.
The and block will return true if both statements are true, false otherwise.
The or block will return true if either statement is true, and false if neither statement is true.
Inverts the value of a true/false statement.
Can also be used to check if a value is not null
.
Value blocks can be used to set the value of a variable. They can be used in conjunction with any of the above blocks.
blocks are often paired with statement blocks that test whether a condition is met
There is a predefined set of colors in the blocks palette
Clicking on this color will bring up a menu:
You can create a color by blending two together with a selected ratio of color 1 to color 2:
This block will return a random color (with an Alpha value of 100%):
You can use this block to select a color with :
You can use a block to set a color with : rgba(r,g,b,a)
You can use this block to set a color with :
You can use a block to include a for your preferred color:
The magnetometer is used to measure magnetic flux density. This is the total magnetic field passing through a given area, per metre squared, . The sensor will returns values with units of microtesla for each of the three coordinate axes; x, y and, z. The magnetic flux density is quite similar to magnetic field strength.
To add a Magnetometer to your app:
Navigate to the Blocks tab of your project.
Under the App Features heading, locate Sensors.
Click the ⊕ symbol next to Sensor.
Select Magnetometer from the provided menu.
Click Add.
You will see a settings panel where you can set:
The Name of the Magnetometer
Whether the Magnetometer is Enabled
You can either confirm your choices and create the Magnetometer, or delete the Magnetometer.
You will see the sensors you have added to your app underneath the Sensors section of your blocks.
If you click on the ⚙ icon next to your Magnetometer, you will be able to edit its settings as seen in the panels above. You can click on your Magnetometer's name to access its drawer of blocks.
Enabled
Toggle whether the component is functioning in your app
True/False
When the magnetometer detects a change in the ambient magnetic field the Changes
event will fire. The event returns 4 parameters that we can work with.
xFluxDensity
Number
yFluxDensity
Number
zFluxDensity
Number
error
String
Error message from the Sensor
Returns flux density, in the x direction, expressed in
Returns flux density, in the y direction, expressed in
Returns flux density, in the x direction, expressed in
Returns a value between 0 and 360 which denotes the user's direction relative to the Earth's geographic North Pole
The magnetometer is, by default, turned on, but the enabled
property can be used to turn in on and off by setting it to true
or false
respectively.
set Enabled
Bool
true
get Enabled
Bool
For each block in this drawer, you can right-click the block and select Show advanced block to see an expanded block with additional outputs. Both the simple and advanced blocks will be explained in this document.
This block will open the user's photo library and allow the user to select a photo or video. The file can then be used in the app.
This block will open the user's file library and allow the user to select a file. The file can then be used in the app.
You can allow the user to upload any kind of file, or limit their selection by file type using the drop down menu.
Thunkable provides a shared Cloudinary account for your convenience, but we strongly recommend creating your own account to ensure privacy for your uploaded media. In addition, the shared Thunkable Cloudinary account has a media size limit of 10MB per app and your files will be deleted after 90 days.
To connect your Cloudinary accout to your Thunkable project:
From your Cloudinary dashboard, retrieve the following account details:
Cloud Name
API Key
API Secret
Return to your Thunkable project page.
Scroll down until you reach the Cloudinary Settings section.
To access the url from uploaded file
or upload file
block:
Navigate to your project's Blocks tab.
Under the App Features heading, click Files.
This block will take an image file and return it in the given dimensions, quality and format.
This block will vibrate the device.
There may be times you may want to design a different experience when a user is offline. To detect a user's connection, you can simply use the blocks below:
This block will return true
or false
.
Returns the height or width of the screen running the app in pixels.
Since Thunkable can build apps for Android, iOS and web, there may be times when you want to modify your user experience depending on their mobile operating system. To do so, you can use the block below:
This block will return true
or false
.
If you have a Text Input in your app, there may be situations when you want to dismiss the keyboard for the user. The block below will help with that:
Some devices will auto-sleep if there is no user activity in an app for a certain period of time.
The Keep Screen Awake block can be used to keep the screen awake even if the user is not actively interacting with the app.
This block can be set to true
or false
.
Having dark mode and light mode available is a popular choice for apps and device operating systems.
This block can be used to detect whether the user's device has a light or dark theme on their device.
You can then use blocks to change the color scheme of components in your app to match the user's preferences.
This block will return true
or false
.
You can use the Share blocks to share media and messages with people using external apps.
Opens your phone app with the given number ready to call. This block will not place a phone call without the app user's knowledge.
Opens your default text messaging app with the given text ready to be sent to the given number. This block will not send a text message without the app user's knowledge.
Opens your default email app with an email with the given subject and body ready to be sent to the given email address. This block will not send an email without the app user's knowledge.
You can send an email to multiple recipients by separating the different email addresses with a comma in the 'send email to' section of the block.
Opens a menu of apps that the app user can choose from to share the given message.
Opens a menu of apps that the user can choose from to share the given image.
You can watch a video to learn about the Firebase Sign In blocks here:
In the Firebase console, navigate to Authentication and go to the Sign-in method
tab.
Find the Email/Password
item under Sign-in providers
.
Click the pen icon to edit the configuration. Set the Email/Password
property to true and save.
There are two properties you need to retrieve from Firebase to connect it with Thunkable, API key
and database URL
. Both are retrievable from the Firebase console.
You can add these values to your Project Settings, which you can access by clicking on the gear icon to the left of the Design tab of your project.
To get these values from your Firebase project, click on the gear icon next to Project Overview and click Project settings
.
In the General tab, scroll down to the section called Your Apps. You will find your API Key and Database URL in the code snippet provided.
You can modify the default email that is sent to new users in the Templates tab of the Authentication segment of your console.
Click on the Sign In drawer of blocks to access the Sign In blocks.
The first step for users is to sign up with their email address and a password. They will be sent an email to verify the address that they provided.
Here is an example of using this block:
This block will sign a user in and return their user ID.
You can use these blocks below to sign a user in:
When the user's email and password have been stored locally, the following blocks can be used to sign the user in with these details automatically.
Signs the user out.
Sends an email to the specified email address to reset their password.
On the Firebase console, navigate to the Users tab under Authentication and you'll find a dashboard where you can reset a user's password, and disable and delete their accounts.
This block allows end users of Thunkable-built apps to sign up and sign in to the app using their existing Google account.
To use this feature, you will need to obtain an OAuth Client ID and iOS URL scheme from Google:
If this is your first time visiting, you may need to log in, provide your location, and accept the Google Cloud Platform Terms of Service.
Click "Select a project" from the dropdown on the top-left of the screen. Select a project or click the "NEW PROJECT" button at the top-right of the popup screen and create the project on the next screen.
You will see a notification to the top-right of the screen once a new project is created. Click "SELECT PROJECT" to select this project. You can also select this project from the 'Select a project' dropdown menu as described above.
1. Go to the OAuth consent screen.
In the side menu, expand "APIs & Services" and select "OAuth consent screen"
On the OAuth consent screen, select the User Type and select "CREATE." (You probably want to select "External" unless you are creating an app specifically for users in the same organization as your Google Cloud account).
Make sure you complete the required fields, highlighted in red below. Click "SAVE AND CONTINUE" .
You will then be taken to the "Scopes" step. Click on the "ADD OR REMOVE SCOPES" button at the top. This will open a panel on the right. Select the ".../auth/userinfo.email" and ".../auth/userinfo.profile" scopes.
In the side menu, select "Credentials."
On the Credentials screen, click the "CREATE CREDENTIALS" button at the top Select "OAuth client ID"
Below are instructions for getting credentials for Android, iOS, and web projects. If you are implementing this feature on more than one platform, you will need to follow the instructions for each platform separately.
Following step 5, select "Android" from the drop-down list. Fill in the required fields. For "Package name" you should use the App (Bundle) ID listed under "Publishing Settings" in your Thunkable project's Settings page.
For "SHA-1 certificate fingerprint" you will need to export your app's keystore and run a Java tool. To do so, you must complete the below sub-steps.
8. Get credentials for iOS. Following step 5, select "iOS" from the drop-down list. Fill in the required fields. For "Bundle ID" you should use the same App (Bundle) ID listed under "Publishing Settings" in your Thunkable project's Settings menu. Click "CREATE" at the bottom when completed. When the iOS OAuth 2.0 client ID becomes available, you may click on it to view your "Client ID" and "iOS URL scheme." Copy these into the "Google iOS Client ID" and "Google iOS URL Scheme" fields in your project settings.
9. Get credentials for web.
Following step 5, select "Web application" from the drop-down list.
Fill in the required fields and click the "ADD URI" button at the bottom.
To test your project on the web, use "https://x.thunkable.com
"
To use Google sign-in with a published web app, use "https://thunkable.site/
".
Copy the resulting Client ID for this platform into the "Google Web Client ID" field of your project's Settings page.
If an app end user is already signed in with Google, this block will return the following outputs If they are not logged in, the block will trigger a prompt to sign in with Google, after which a successful login will return the following:
For web apps, no blocks, including errors, will be returned if the user rejects login (as opposed to fails login).
Flux density, in the x direction, expressed in
Flux density, in the y direction, expressed in
Flux density, in the z direction, expressed in
Thunkable integrates with , a service that allows you to store media files in the cloud. The upload file block allows you to send media directly from your Thunkable app to a linked Cloudinary account.
Create a free Cloudinary account here: .
Click the Settings icon in the left side menu.
Input your Cloudinary Cloud Name, API Key, and API Secret.
Drag the url from uploaded file
block into your workspace. This is the regular version of the block.
The upload file
block is the advanced block. To access it, right-click the url from uploaded file
block and select Show advanced block.
To see an example of the url from uploaded file
block in action, check out this video tutorial: .
At the moment, all the dates and times are in numerical format i.e. month = 1 rather than month = Jan. If you want to convert the numbers into names, we suggest you to add a Local and a simple table like the ones shown below.
Measures seconds since 00:00:00 UTC on 1 January 1970. This timestamp is also known as Unix time or Epoch time. You can read about its use in computer programming at the .
Some external setup is needed to add authentication to your app. See more details in the and sections of this document.
Create your free account and create a new project
You can also use the User ID as a key for storing user data in the cloud. See the for an example of this.
Download your Android app (if you have never done so before for this app). See instructions to download your Android app here: This will automatically generate a keystore for your Thunkable project You do not need to download the resulting Android app file
Export your keystore. See instructions to export your keystore here:
Run the keytool command.
You will need to get the SHA-1 fingerprint for the keystore you just downloaded by using the keytool command.
To use this command, you will need to for your system.
After installing the JDK, you may run the command from the Command Prompt (Windows) or Terminal (macOS):
keytool -keystore
path-to-debug-or-production-keystore
-list -v
where "path-to-debug-or-production-keystore" is the location of the keystore file on your computer.
If prompted for a password, enter the password you saved when exporting your keystore (see: )
Look for the "Certificate fingerprints" section. It may look something like:
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
photo or video
image/video
if a file was selected, returns the file
was cancelled
true/false
returns whether the user cancelled selecting a file
error
text
if there was an error, returns the error
URL
text
returns a URL for the uploaded file
error
text
if there was an error, returns the error
resize image
Any image file
The image to be resized
width
Number
Width in pixels to resize image file to
height
Number
Height in pixels to resize image file to
quality
Number
Quality of resulting image, as a percentage of quality of original image
using ... format
Select from menu
Select image type for resulting image
resized Image
Image
The resized image in the selected format and quality level
error
Text
If there was an error, returns the error. Else returns NULL
Event
Description
Sign up ( email
, password)
)
Signs up a user for a new account. Returns an error
if sign up is not successful. A common error
is "The email address is already in use by another account."
User ID
Unique identifier for user's Google account
Text
Display Name
Full name associated with the Google account (eg. Mary Smith)
Text
Given Name
Given name associated with the Google account (eg. Mary)
Text
Family Name
Family name associated with the Google account (eg. Smith)
Text
Email address
Email address of the Google account
Text
Profile photo image URL
URL that points to the profile image associated with the Google account
Text
error
If there is an error, returns the error. Else returns null
Text
file
Points to the file that has been uploaded
Data type of the file that has been uploaded. Can also return address of the file as text
name
Name of the uploaded file
Text
mime type
Text
size
Returns size of uploaded file in bytes
Number
was cancelled
Indicates whether the end user cancelled selecting a file
True/False
error
If there is an error, returns the error. Else returns null
Text
The accelerometer sensor is used to measure the force of acceleration acting on the phone. The sensor reports this force for each of the three principal axes, the x axis, y axis and, the z axis. The values obtained from the sensor are in metres per second squared, .
To add an Accelerometer to your app:
Navigate to the Blocks tab of your project.
Under the App Features heading, locate Sensors.
Click the ⊕ symbol next to Sensor.
Select Accelerometer from the provided menu.
Click Add.
You will see a settings panel where you can set:
The Name of the Accelerometer
Whether the Accelerometer is Enabled
Whether the Sensitivity of the Accelerometer is low, medium or high
You can either confirm your choices and create the Accelerometer, or delete the Accelerometer.
You will see the sensors you have added to your app underneath the Sensors section of your blocks.
If you click on the ⚙ icon next to your Accelerometer, you will be able to edit its settings as seen in the panels above. You can click on your Accelerometer's name to access its drawer of blocks.
Enabled
Toggle whether the component is functioning in your app
True/False
Sensitivity
Set how sensitive the accelerometer is to movement, where higher sensitivity will react to smaller movements
Select from list: [low, medium, high]
There may be some instances where you want to start an event by shaking your mobile device or when the mobile device is shook. There is a Shaking
event that you can add to your blocks that has sensitivity levels of high
, medium
and low
When the accelerometer sensor detects a change in the force acting on the phone the Changes
event will be fired. Each time the event fires the four associated parameters will be updated.
xAcceleration
Number
yAcceleration
Number
zAcceleration
Number
error
String
Error message from sensor
You can get the values for xAcceleration, yAcceleration and zAcceleration at any time with the following blocks.
By default, the accelerometer sensor will be turned on, but you can use the Enabled
property to read its current state and to change its state, i.e turn the sensor on and off.
set Enabled
Bool
True
get Enabled
Bool
You can use the Sensitivity blocks to set the sensitivity of the Accelerometer and get its current level of sensitivity.
set Sensitivity
one of [low, medium, high]
low
get Sensitivity
one of [low, medium, high]
A function is a block of code that performs a specific task. If you use the same code set multiple times in your project, you can work more efficiently using functions. Clear function names also make your code more readable.
You can view a video tutorial on using functions here:
You can use the following block to create a function and give it a name:
One example of a function is below. This function will create and shuffle a list of items.
After you have created your function, you can simply use it at any time using the function block you have named:
You can also create a function that returns a specific output.
You can add multiple return
blocks to your function. This allows you to return a different output based on some conditions.
For example, this function will take a rating out of 100, and return a description of the quality of the item being reviewed:
The function will break when the return
block is fired. For example, in the above example, if the quality rating is 100, the function will return Perfect and then stop. It will not run the other tests, and won't return Excellent. Good, Fine, etc.
You can click the gear icon to add inputs to your functions.
You can then treat that input as a local variable in your function.
To add a Location Sensor to your app:
Navigate to the Blocks tab of your project.
Under the App Features heading, locate Sensors.
Click the ⊕ symbol next to Sensor.
Select Location Sensor from the provided menu.
Click Add.
You will see a settings panel where you can set the properties of the Location Sensor before clicking Submit.
The Location Sensor returns a user's current location in latitude
and longitude
as well as a location
object which includes additional properties like accuracy
, altitude
, speed
and heading
(or direction) which you have to retrieve with the object blocks above
Describes the type of file in
Change in speed of the phone, along the x axis, in
Change in speed of the phone, along the y axis, in
Change in speed of the phone, along the z axis, in
In this example, the function change font size
takes a number as an input and sets the text on a Screen to this font size. The number can be fed in as the number selected on a , or the user can click a Reset to set the font size back to 18.
EnableHighAccuracy
Enables network provider that uses Google Play services to improve location accuracy and location-based services
True/False
Timeout
How long the Lotion Sensor will look for the user's location before quitting, in milliseconds
Number
Maximum Age
How long a previously fetched location will remain valid, in milliseconds
Number
Get Current Location
Returns a user's location in latitude
and longitude
degrees; also includes additional information in a location object including i) estimated location accuracy
in meters, ii) altitude
in meters, iii) speed
in meters/second and iv) heading
in degrees
Every time you send a request to an endpoint it takes time and bandwidth. From your perspective, as an app developer you want to minimise wait times in your app. From the perspective of your API developer you want to keep your bandwidth usage as low as possible - especially if it's something they're paying for and you're using for free. Thankfully these issues are two sides of the same coin and
By the end of this lesson you'll understand how to:
Maximise app speeds while minimising API calls.
Set WebAPI headers.
The API allows us to get jokes in HTML, JSON or plain text format. In order for us to specify which format we would like the response in we need to use a header. In the WebAPI drawer, there are four different properties we can set; Body, Headers, QueryParameters and URL. Going back to the API docs, we are asked to specify an Accept
header and a User-Agent
header. To request a response in JSON format from the API we set the value of the Accept header to application/json
. The user agent header is used as a way for us to identify ourselves to the API developer. Recall that this is a free service and we don't want to take advantage of the generosity of the developer. In this case I've used an email address since it gives the developer a way to contact me directly if there are too many calls being made.
The API request is quite similar to the one we saw in the previous tutorial. After specifying the URL and the Headers we send a Get
request to the API. The if error then do
block is for basic error handling and should not be omitted. To display the text of the joke itself we get the joke
property from the response object.
GET
https://icanhazdadjoke.com/
Accept
String
Request a response in HTML, JSON or plain text format. Defaults to text/plain if not specified.
User-Agent
String
A good user agent should include the name of the library or website that is accessing the API along with a URL/e-email where someone can be contacted regarding the library/website.
Once the joke is displayed on screen we can temporarily "deactivate" the Get Joke button. This serves two purposes. First of all, it gives the user a moment to read (and appreciate) the joke and secondly it prevents users from making multiple requests to the API per second by repeatedly clicking on the button. In the example below we add a pause of 5 seconds, which means that at most a user can request 12 jokes per minute. This still a good number of jokes, and a lot better than not having any pause at all.
Finally, for a bit of visual interest, we add in a random emoji reaction. This is obviously a pretty simple thing to do, but you can easily expand on this by adding some sound effects or a laugh track to your app.
In this section we've looks at why it's a good idea to use a proper API, how to set the URL and make a GET request, how to implement basic error handling, how to convert a JSON response to an Object and pull information out of that object and finally we learned how to set API headers and implement some basic rate limiting.
In the next section we'll increase the complexity slightly and learn how to use APIs that require some basic auth or an access token before we can perform any other operations.
If you have any questions about this tutorial, please post them in this topic over in the Thunkable Community
To answer this question, we're going to build an app that doesn't use APIs. Instead, we will use a spreadsheet as an intermediary to get stock market data. Our app will write ticker symbols to the spreadsheet and get stock prices back from the sheet. Most of the time. Hopefully.
By the end of this demo you should understand that:
API requests are asynchronous, which means:
For the best performance, you should always aim to minimize the total number of calls in your app.
Let's get started by making a copy of this sheet, which has all the functions your app will need. By default the Google Finance function will return the most recent price for a given symbol. Alternatively, you can pass any one of a number of different parameters to find the corresponding value. In the image below, we are showing the price in cell B2 and showing the chance in price in cell B3. With everything set up in our Google Sheet we can connect this directly to our Thunkable project.
The user interface for this example is quite simple, but if you want yours to look identical to the tutorial then go ahead and make a copy of it for yourself.
Next step is to connect to our Sheet. Click on the Data tab on left hand side of your screen and choose "Google Sheets" as your data source.
Finally, choose the Google Finance sheet and create a new data source within your Thunkable project.
Since we're just testing the waters we won't worry too much about data validation just yet. The first thing we'll do is get a ticker symbol from the user and send it to our sheet. In your Thunkable blocks it looks like this:
After a few seconds the data will update and we can call the new values from the Sheet.
Now, the first and last thing we do is show/hide the loading icon. In between, we send a new value to the sheet, wait 3 seconds and then (hopefully!) get the most recent price back. Since we have no control over how long it takes our Sheet to update this 3 second values is really a best guess. Most of the time it will be a lot faster, but other times it will be significantly slower and we'll end up fetching the previous value from the spreadsheet. In general we want to avoid doing things like this in our app and instead make asynchronous calls to an API.
As we've just seen in the previous example, having fixed wait times in our app is a bad idea. In the best case scenario the operation is completed much quicker than our delay and we've kept our user waiting unnecessarily. The worst case scenario is that the delay isn't long enough and we get inaccurate or out of data information for our use. A much more sensible approach is to use an asynchronous approach. In this context asynchronous simply means that the request and response don't happen at fixed, or predefined, intervals. In the case of a synchronous approach we might send a value to our sheet and then repeatedly check, every 1 second, to see if the result has been updated. With an asynchronous request we send our data to the API and when the response is ready it gets sent back to the app. Our app "listens" for this response from the API and only acts when the response has been received.
The other value in our spreadsheet is the change in price. This will either have gone up, gone down or stayed the same. While this isn't - strictly speaking - related to working with APIs, it's nice to demo how you can make decisions in your app, based on different responses you might get. In this case, we want the text to be green if the price has increased, red if it has decreased and black if it's stayed the same.
In this tutorial we learned that we can use Thunkable data sources to read and write data to a spreadsheet in the cloud. This is a fantastic tool to have at our disposal but is poorly suited to something like a simple stock market app. In the next two section we will learn how to request data from an API, parse the response and set the request headers. Armed with this new information we will then be able to create a much more robust and scalable app for stock market data.
Remix link:
According to , icanhazdadjoke.com can be used as an API for fetching a random joke, a specific joke, or searching for jokes in a variety of formats.
Community Link:
Use text-to-speech, speech-to-text, and translation functions in your app
Read a piece of text aloud in a specified language.
Afrikaans
✅
✅
✅
Albanian
❌
✅
✅
Arabic
✅
✅
✅
Armenian
✅
❌
❌
Azerbaijan
✅
✅
✅
Basque
✅
✅
✅
Belarusian
✅
❌
❌
Bengali
✅
❌
❌
Bosnian
❌
✅
✅
Bulgarian
❌
✅
❌
Catalan
✅
✅
✅
Cebuano
✅
✅
✅
Chinese China
✅
✅
✅
Chinese Hong Kong
✅
✅
✅
Chinese Taiwan
✅
✅
✅
Croatian
❌
✅
✅
Czech
✅
✅
✅
Danish
✅
✅
✅
Dutch
✅
✅
✅
English GB
✅
✅
✅
English US
✅
✅
✅
Esperanto
✅
✅
✅
Estonian
✅
✅
✅
Finnish
✅
✅
✅
French
✅
✅
✅
Galician
✅
✅
✅
Georgian
✅
❌
❌
German
✅
✅
✅
Greek
✅
✅
✅
Gujarati
✅
❌
❌
Haitian Creole
✅
✅
✅
Hebrew
✅
✅
✅
Hill Mari
✅
✅
❌
Hindi
✅
✅
✅
Hungarian
✅
✅
✅
Icelandic
✅
✅
✅
Indonesian
✅
✅
✅
Italian
✅
✅
✅
Irish
✅
✅
✅
Japanese
✅
✅
✅
Javanese
✅
✅
✅
Kannada
✅
❌
❌
Kazakh
✅
✅
❌
Khmer
✅
❌
❌
Korean
✅
✅
✅
Kyrgyz
❌
✅
❌
Latin
❌
✅
✅
Latvian
✅
✅
✅
Lithuanian
✅
✅
✅
Luxembourgish
✅
✅
✅
Macedonian
✅
✅
❌
Malagasy
✅
✅
✅
Malay
✅
✅
✅
Malayalam
✅
❌
❌
Maltese
✅
✅
✅
Maori
✅
✅
✅
Marathi
✅
❌
❌
Mari
✅
✅
❌
Mongolian
✅
❌
❌
Nepali
✅
❌
❌
Norwegian
✅
✅
✅
Papiamento
✅
✅
✅
Polish
✅
✅
✅
Portuguese Brazil
✅
✅
✅
Punjabi
✅
❌
❌
Romanian
✅
✅
✅
Russian
✅
✅
✅
Scottish
✅
✅
✅
Serbian
✅
✅
❌
Sinhala
✅
❌
❌
Slovakian
✅
✅
✅
Swahili
❌
✅
✅
Slovenian
✅
✅
✅
Spanish
✅
✅
✅
Sudanese
✅
✅
✅
Swedish
✅
✅
✅
Tagalog
✅
✅
✅
Tajik
✅
✅
❌
Tamil
✅
❌
❌
Tatar
✅
✅
❌
Telugu
✅
❌
❌
Thai
✅
✅
✅
Turkish
✅
✅
✅
Udmurt
✅
❌
❌
Ukrainian
✅
✅
❌
Urdu
✅
❌
❌
Uzbek
✅
✅
✅
Vietnamese
✅
✅
✅
Xhosa
✅
✅
✅
Recognize a piece of audio in a given language. Returns a text transcription of the speech.
Now that we know what URL parameters are, we can start creating blocks in our project to dynamically update the parameters. To do this we'll use the Text blocks, and in particular the Join block, to change out each of our variables.
To recreate the UI for this app you can add an image and a button - click on the remix button to add the UI and blocks for this project to your Thunkable account.
Drag an image component onto the screen. The chart URL will be used as the image source. The URL should be set in your blocks unless you plan to have a static chart image, in which case you may set the image source on the design screen.
Drag an image component to the screen
Go to your blocks
Following some user or system generated action, set the url for the image component using the Quickchart API base URL provided while saving your chart
All chart updates will be made by appending text join blocks
to the image source URL.
Currently, three aspects of your chart can be overriden with custom values:
Chart title
Dataset labels
Data
These customizations are passed as URL parameters. For example, to override chart title, take the base URL and add the following:
You can join URL parameters together using the & symbol. For example:
To override data, use data1, data2, data3, …, for each dataset on the chart.
For example, to override the first (primary) dataset:
To override multiple datasets and the chart title:
You can see the and blocks in use in this video tutorial:
Translate a piece of text. This block is powered by Yandex. Any language code from can be used.
Remix Link:
Most modern APIs will have support for a variety of CRUD operations. In this context, the acronym CRUD stands for Create, Read, Update, Delete. While most API developers probably won't want to give just anyone free rein to change or remove data on their system there are plenty out there who provide public, read-only access to their end points. This is also convenient for us, since reading data from an API and displaying it in a Thunkable app is probably the easiest way to familiarise ourselves with APIs.
At the end of this tutorial, you should be able to
Send a GET request to an API
Parse (interpret) a response from that API.
At its core we need at least three components to get this app working correctly; a Button to send the API request, an Image to show the picture in the response and a Label to display the name of the dog breed. If you want your project to look the same as the sample project then you can go ahead and make a copy of it for yourself.
Our response contains just two properties, message
and status
which really makes this API as easy as possible for us to work with.
GET
https://dog.ceo/api/breeds/image/random
The URLs for every image also contain the breed names for each dog. If you look closely you'll notice they all follow the same pattern:
https://API-HOST/DOG-BREED/DOG-IMAGE.jpg
What we want to do is grab the name of the dog breed, remove any stray backslashes and convert it to Title Case. In practice, this involves using the make list from text blocks and then the in list get # block to get the name of the breed and then pass that through the Title Case text block to output the nicely formatted dog breed in our label.
While the above approach works perfectly well for pugs and collies, our API is set up in such a way that you might also see responses like "terrier-welsh" or "terrier-westhighland". The second if then do block below shows one way that you can split the text at the hyphen and display the words in reverse order.
In this first example we've learned how make a Get
request in Thunkable and use the object blocks to retrieve information from the API response. We've also seen firsthand how just a handful of list and text blocks can be combined to extract additional information and present it to the end user in an easy-to-read format.
If you have any questions about this tutorial, please post them over in the Thunkable Community
Great data is an essential part of many apps built today and the Web API component enables apps to retrieve data from any public or private API (application programming interface) service on the web. For more advanced developers who have write access to a private API, this component also enables you to upload and delete data.
To add a Web API component to your app:
Go to your Blocks tab.
Scroll to the bottom of your blocks panel on the left side and find the Advanced
section.
Click the expand chevron to show the Advanced invisible components.
A Web API component properties dialog launches. See the chart below for descriptions of the various properties. Click Submit to create the Web API component, or Delete to dismiss the dialog without creating the component.
Once you have the API key, you'll need to enter the unique URL into the property field of the Web API component.
URL
The url for the web request which usually contains an API key
Required
QueryParameters
Specifies some parameters of the data
Optional
Body
Body of your API call. Select from String or Multipart Form Data.
Optional
Headers
Specifies some meta-data, eg: usernames and passwords
Optional
Once you have added at least one Web API component to your app, you will be able to view all of your Web API components under the Web APIs
drawer in the Advanced section of the Blocks tab.
To edit the properties of a Web API component, click on the ⚙ icon next to the component's name to bring up the properties dialog. You will be able to change the properties and click Submit to save your changes, or click Delete to delete the component.
Query parameters and headers can be set in the designer or in the blocks editor. In the example below you can add any property:value pair you want. You can add as many params to your app as you need, but each parameter has to be added one at a time.
In the blocks editor, it is possible to use the create object
block to add multiple property:value pairs simultaneously.
In addition to creating your own objects, it is also possible to use JSON to specify the property:value pairs for your query parameters or headers.
To retrieve data from an API, you simply need to use the Get
block.
Get (response
, status
,error
)
Performs an HTTP GET request using the Url property and retrieves the response
. Reports status
of request and if request does not go through, will report an error
One of the most common output formats for APIs is JSON, short for Javascript Object Notation. The Open Weather Map API returns a JSON file like the one below.
In your JSON response, objects can be found within the "
quotes "
followed by a colon :
. The properties of the object is follows the colon :
but is within the {
curly brackets}
.
Once you have converted the JSON into objects, you can then specify the objects
and property
that you are interested in. To get the name of the city we are viewing weather data for ("name":
in line 22), we'll want to get the property name
of the response:
If we wanted to get the temperature in Dhaka from the Open Weather API above, we would need to do the following:
Convert the JSON response to an object
Get the property main
of the response object
Get the property temp
of main
We can write this as getting the property main.temp
of the response object:
The JSON output of the Google Maps Distance Matrix API seems similar to the Open Weather Map API with one notable exception: it includes objects, properties and lists. Lists are items bounded by [
square brackets ]
.
If you want to retrieve the "text"
property in line 13, you'll have to:
convert the JSON to an object
select the "rows"
property of the object
select the first item in the list
select the "elements"
property of the rows object
select the first item in the list
select the "duration"
property of the elements object
select the "text"
property of the duration object
This can also be written as the property rows[1].elements[1].duration.text
of the response:
Uploading and deleting data is usually reserved for a private API that you or your organization owns
Put (response
, status
,error
)
Performs an HTTP PUT request using the Url property and retrieves the response
. Reports status
of request and if request does not go through, will report an error
Post (response
, status
,error
)
Performs an HTTP POST request using the Url property and retrieves the response
. Reports status
of request and if request does not go through, will report an error
Patch (response, status, error
)
Performs an HTTP PATCH request using the Url property and retrieves the response
. Reports status
of request and if request does not go through, will report an error
Delete (response
, status
,error
)
Performs an HTTP DELETE request using the Url property and retrieves the response
. Reports status
of request and if request does not go through, will report an error
With the camera component, you can open up your phone’s camera to take a picture.
You can find the Camera blocks in the Camera drawer of blocks.
You can view a video tutorial that demonstrates all of the Camera blocks here:
For each block in this drawer, you can right-click the block and select Show advanced block to see an expanded block with additional outputs. Both the simple and advanced blocks will be explained in this document.
This block will open the camera and allow the user to take a photo. The photo can then be used in the app.
photo
image
if a photo was taken, returns the photo
was cancelled
true/false
returns whether the user cancelled taking the photo
error
text
if there was an error, returns the error
Opens user camera, films from selected camera for chosen amount of time, returns video file.
Number of Seconds
Number
Set how long to record for
Using [...] Camera
Select from menu
Select camera to record with
videoFile
Video file
The recorded video footage
Error
Text
If there is an error, returns the error. Else returns NULL
Using [...] Camera
Select from menu
Select a camera to record with
video file
Video File
Returns the recorded video footage
Error
Text
If there is an error, returns the error. Else returns NULL
This block will generate a description of a given image. This block requires internet access.
description
text
description of the image
tags
list of text
returns tags used to identify the image
confidence level
number between 0 and 1
returns calculated confidence level that given description is accurate
error
text
if there was an error, returns the error
This block will scan a barcode or a QR code and return its value.
value
text
value of scanned barcode/QR code
type
text
returns whether bar code or QR code was scanned
was cancelled
true/false
returns whether the user cancelled scanning a code
error
text
if there was an error, returns the error
Push notifications are one of the biggest advantages of mobile apps over mobile websites since they can send messages to users without the app being open.
When a user first opens an app with push notifications enabled they receive an alert prompting them to enable push notifications. Once they accept they are a subscriber of your app's push notifications.
To send push notifications to your app's users, you must link your Thunkable app to your OneSignal apps (iOS and/or Android). Once you've added your OneSignal App IDs into Thunkable, the work in Thunkable is done, and the remainder of the management takes place in third-party platforms (OneSignal, Apple Developer, and Firebase, depending on the platform).
Notifications that are irrelevant and too frequent are often dismissed or blocked. We highly recommend sending notifications only when the content is relevant to the user. Examples include an e-commerce app letting the user know about a sale, or a game app letting the user know about a new level or feature.
To add Push Notifications to your app :
Navigate to your project's Blocks tab.
Locate Push Notification under the App Features heading.
Click the gear icon next to Push Notification.
The Push Notification settings modal opens. This is where you will enter your OneSignal Android App ID and OneSignal iOS App ID to configure the connection between OneSignal and your Thunkable project.
The remainder of this document will assist you with:
Click Sign Up.
Create your account and complete the OneSignal onboarding.
If you didn't create an app as part of the OneSignal onboarding, navigate to your OneSignal dashboard and click + New App/Website.
Enter your app name. We recommend including the platform in your app name, for example, Employee Directory - Android or Employee Directory - iOS.
Select Apple iOS (APNs) or Google Android (FCM).
Click Next: Configure Your Platform.
Follow the platform-specific configuration instructions below.
In OneSignal, select Native Android as your target SDK.
Click Save & Continue.
Copy Your App ID.
Return to the Blocks tab of your Thunkable project. Do not close the OneSignal tab.
Click the gear icon next to Push Notification.
In the Android App ID field, paste Your App ID that you copied from OneSignal in step 5.
Indicate whether you want to collect Geolocation Permissions. OneSignal allows you to push messages to users based on their location. In order to do that, you need permission from your users to register their location. Use the toggle in the Push Notification settings to indicate whether you want to request users share their location with OneSignal.
If you enable Geolocation Permissions, when you publish your app, ensure that you indicate that you're tracking location when you publish your app.
Click Submit.
Click the Live Test on Device icon and open the Thunkable Live app on your device.
Return to your OneSignal tab.
Click Check Subscribed Users.
If the configuration was successful, you will see a congratulations message.
Click Done.
To test Android push notifications, download the app to your Android device and send a test message through OneSignal to see the push notification in action.
When you get to the section titled "Provisioning Profiles," return to these instructions.
In your Apple Developer account, select Identifiers under the Certificates, IDs & Profiles heading.
Select your app from the list of Identifiers.
Scroll down the list of app capabilities, and place a checkmark next to Push Notifications.
Click Save.
Select your app from the list of Identifiers again.
Scroll down the list of app capabilities, until you get to Push Notifications again.
Click the associated Configure button.
Under Production SSL Certificate, click Create Certificate.
Under Upload a Certificate Signing Request, click Choose File.
Select the Certificate Signing Request (CSR) you downloaded from Thunkable as part of the publishing process.
Click Continue.
Click Download to download your iOS certificate.
Select your app from the list of Profiles.
Click Edit.
Click Save.
Click Download.
In OneSignal, select Native iOS as your target SDK.
Click Save & Continue.
Copy Your App ID.
Return to the Blocks tab of your Thunkable project. Do not close the OneSignal tab.
Click the gear icon next to Push Notification.
In the iOS App ID field, paste Your App ID that you copied from OneSignal in step 4.
Indicate whether you want to collect Geolocation Permissions. OneSignal allows you to push messages to users based on their location. In order to do that, you need permission from your users to register their location. Use the toggle in the Push Notification settings to indicate whether you want to request users share their location with OneSignal.
If you enable Geolocation Permissions, when you publish your app, ensure that you indicate that you're tracking location when you publish your app.
Click Submit.
To test iOS push notifications, you have to publish to TestFlight. This requires the provisioning profile with push notifications enabled.
The first time your app is opened on a new device, it is automatically assigned a unique push notification user ID. This block returns the user's push notification user ID that can be used to send a notification to a specific user with a web API call.
In this guide, you will learn how to:
Create and customize a chart template without any code.
Save the chart as a URL (API endpoint) that you can use in emails, Excel, Salesforce, and any other formats.
Set the chart’s data by providing special parameters in the URL.
To get started, add some dummy or example data. The chart preview will update so you can get an idea of how your visualization will work.
Enter data as comma-separated values (e.g. 10,20,30,40
). Each data value maps to a label (e.g. Jan, Feb, Mar, Apr
). Edit “Labels” at the top of the Data settings to change this mapping.
Edit labels and data on the left-hand side of the chart maker
Using coordinates
For more advanced use cases, you may provide your data as (x, y) coordinates.
An example of category-based coordinates:
(Jan, 10), (Feb, 20), (Mar, 30), (Apr, 40)
. These coordinates will give you more power over how your line or scatter plot is displayed.Numeric coordinates are also accepted:
(1, 50), (10, 40), (12, 20), (8, 10)
. This format is most commonly used for scatter plots, and requires you to change your Axes tolinear
orlogarithmic
under settings. In this case, you should clear the “Labels” setting at the top of the Data settings - labels will be automatically generated.Time series use coordinates too. For example:
(2020-01-01, 50), (2020-03-15, 12), (2020-06-05, 40)
. To display time series, change the X-axis totime
type and clear the “Labels” setting in Data settings, as labels will be generated automatically.
Now that your data is set, time to make the chart look however you want.
Close the data menu to customize your chart’s axes, ticks, legend, and its overall layout.
Customize the chart by expanding different sections
Click Save as API Template in the top right.
You’ll be presented with an API endpoint. This is the base URL of your chart. If you go to it, you will see a chart image. The URL can be further customized to override properties of your chart.
Saving as an API template gives you an endpoint you can use to generate unlimited charts.
In-App Purchases (IAPs) are a great way to monetize your app. These allow you to offer access to specific in-app sections. This allows you to offer some content to the general user, but also offer ‘premium’ content/features of your app for a price.To begin, you'll need to take care of a few details for either platform you plan to incorporate IAP with. Follow the links below to get the groundwork laid to begin using IAP in your app!
Now, these combos will vary from app to app, but the basic setup is the same. Complete a purchase, parse the response, store the relevant data.
When prompted, it composes responses relevant to the topic requested. Thunkable creators can utilize this model in their own apps and tap into the power of AI and natural language generation.
To use the OpenAI ChatGPT model in your Thunkable app, you need to generate a personal Open AI API key. To do this:
Click Sign Up.
On the Overview page, click your avatar to show the menu and select View API Keys.
Select Create new secret key.
Copy the secret key that is provided in the popup window. You will need to paste this into your Thunkable project.
You will only be able to see your OpenAI API key once. You will not be able to copy it after the initial modal closes.
To setup the OpenAI integration in Thunkable:
Navigate to your project’s Blocks tab.
Scroll to the bottom of the blocks panel on the left side to access the Advanced section.
Click the expand chevron to show the Advanced components.
Click the plus icon next to Open AI Services
.
Your “Open AI Services” component will appear under the Open AI Services (Beta) drawer. Click the gear icon next to the component's name to access its properties dialog.
Paste your Open Secret API Key in the text box under APIKey (currently set to ‘default’).
Click Submit.
API Key
Your person API for making requests to the OpenAI API (default key used if this field is left blank)
Text
Property
Name of the property you are assigning a value to in your API request
Text
Value
Value of the property you are specifying in your API request
Text
Prompt
Text prompt for OpenAI to generate text around
Text
Yes
response
Generated Text from OpenAI API
Text
error
If an error is encountered while making the API call, returns the error
Text if an error is returned; else null
Prompt
Text prompt for OpenAI to generate image
Text
Yes
response
Generated Image from OpenAI API
Image
error
If an error is encountered while making the API call, returns the error
Text if an error is returned; else null
Set the API Key being used to make calls to the OpenAI API in your app
Get the API Key being used to make calls to the OpenAI API in your app
To utilize the OpenAI ChatGPT integration, your Thunkable project will need a minimum of:
One text input
One label
Two buttons
One image component
Below is a sample minimum viable product design:
To use the OpenAI integration to display text and an image from a query, recreate the following block combination.
Users of this app enter a prompt into the text input.
The app calls the OpenAI API and populates the label and image components when the 'Text' or 'Image' button is clicked.
The label component shows the text output from the OpenAI model. The image component shows the image output from the OpenAI model.
Remix Link:
The app we're going to build in this example is called "Dogs-as-a-Service". It connects to the and can "fetch" an image and breed name for a random dog.
Let's begin by sending a GET request the to API. Notice here that the purple Get
block returns three parameters; response, status and error. If anything goes wrong with the request then an error will be returned so it's always a good idea to do some error handling in your app. The status block returns the HTTP status. According to there are about 30 different response codes. You don't need to remember what they all mean but it is good to know that a response code in the 200s is successful, codes in the 300s are for redirects and status codes in the 400s correspond to errors. Indeed you may already be familiar with the 404 error code for "Page Not Found". The example below has some basic error handling and, if successful, displays the entire JSON response in a label.
All we need to do here is get the value from the message
property and pass that to our image component. The in Thunkable make this incredibly easy to do and we can set our picture by using just two of them. First we have to convert the raw JSON response into an object using the get object from JSON block, then we can go ahead and get the message value and pass it to the image component using the get property of object block like this:
Community Link:
To see what public APIs are available, we recommend
Click the ⊕ icon next to Web APIs.
Most APIs will return data in JSON format, so we'll take a few moments to walk through a few examples of how to parse this data using our blocks.
In the example above, "base"
, "dt"
, "id"
, "name"
and "cod"
are simple properties of the JSON response. "coord"
, "main"
, "wind"
, "clouds"
and "sys"
are properties of the overall response, but each of these properties is also an object with properties of its own, or contained within the {
curly brackets }
. "weather"
is a one-item list which also contains an object.
The first step in parsing this response is converting the JSON response to an . Objects have properties (like name
) that we can retrieve and display in our app. Objects can be embedded within another object.
You can read about getting nested values from Objects .
You can read about getting nested values and values from lists in Objects . Let's work through an example.
You can find a working example of this in the sample app, .
You can see the example below for how this would look using the and blocks
You can also post and receive messages between a web page and a using the Post Message function. Read more about that .
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
This component is powered by . You can get your own server URL and subscription key for Microsoft Azure . You can add these details to your app in the , which you can access by clicking on your app icon.
Thunkable utilizes the services of to facilitate push notifications from your app. OneSignal is a free service that supports unlimited devices and notifications. You can learn more about their features here: .
Push Notifications are available on Thunkable Pro, Business, and Team plans. While all Creators can add Push Notifications to their projects and live test them in their Android apps, only Creators on the previously mentioned plans can download and publish apps with Push Notifications. See our for more details.
Go to .
If you don't already have one, create a account. Instructions for getting started with Firebase are available here: .
Follow OneSignal's instructions to generate a Firebase Server API key for sending Android App Notifications here: .
Follow OneSignal's instructions to generate a p8 certificate: .
Access your Apple Developer account’s .
You require a new provisioning profile with push notifications enabled to publish to the App Store. See OneSignal's instructions here: .
Once you have your platforms configured in OneSignal you can create and sent push notifications to your app's users. Follow OneSignal's instructions here: .
One of the quickest and easiest ways to send data to an API is by passing information, which we call parameters, in the API URL. One great use case for this is to create graphs and charts with data that has been generated in our app. QuickChart is a no-code solution to automatic chart generation. Create a chart template using the interface. Then use the template endpoint to customize and generate charts automatically.
To create charts online, first go to the . Use the interface to build a chart template. This chart will be the basis of the charts you generate automatically in the future.
Looking for inspiration? Head over to the - most examples are editable in the chart maker.
An artificial intelligence research and deployment company, focuses on the creation of safe, artificial, general intelligence. Their latest AI model, called ChatGPT, has the ability to interact with a user in a conversational tone.
Navigate to
Request Settings are passed as a of , or key-value pairs. In this modal, you can pass the property name and property value in their own fields.
See what kind of settings you can pass in OpenAI's documentation.
Make a call to
Make a call to
Use and blocks to set the of your call to the OpenAI API
Get the of your call to the OpenAI API
Your Request Settings will be returned as a of
Have feedback on this doc? Please take a moment to share your feedback here: . Your valuable insights will help us improve and better serve you in the future.
Alerts are useful components for displaying important messages while users are in the app itself
To add an Alert component to your app:
Navigate to the Blocks tab of your project.
Under the App Features heading, locate Alerts.
Click the ⊕ symbol next to Alerts.
Complete the properties fields as described below.
Click Submit.
You will see a dialog with options to enter certain properties for your Alert.
Once you have an Alert to your app, you can view it under the Alerts
heading on the Blocks tab.
To edit the properties of an Alert component, click on the ⚙ icon next to the component's name to bring up the properties dialog. You can change the properties and click Submit to save your changes, or click Delete to delete the component.
A one button alert, also known as a notification, displays a message and one button to confirm user has viewed the message
To set up an alert, simply fill in the following simple
properties. The Cancel Button Text only needs to be filled out for a two-button alert. You can use blocks to start an event when
Title
The title of the alert
Message
The subtitle of the alert
Confirm Button Text
The text of the button
Cancel Button Text
LEAVE BLANK
Two button alerts have two buttons, one that dismisses the notification and one that can be programmed to start an event
To set one up, simply add the following simple
properties
Title
The title of the alert
Message
The subtitle of the alert
Confirm Button Text
The text of the right confirm button; If the Dangerous
switch is turned on, the text will be in red (iOS only)
Cancel Button Text
The text of the left cancel button
If you want to start an event from a confirm button, you will want to add the blocks below:
You can set the Text of the Alert. You can set the Style of the Alert to ok, destructive or cancel.
On iOS, the Alert can show more than 3 Buttons. On Android, the Alert can show up to 3 buttons. If more than 3 buttons are specified, the first 3 will be shown.
Property
Description
Title
The title of the alert
Message
The subtitle of the alert
Text Advanced
The text of the button
Style Advanced
The style of the button; ok
is a confirm button, cancel
is a cancel button and destructive
is a confirm button with text in red (iOS only)
The 'showButtonList' block will return an output called 'buttonPressed'. This will return the position of the Button in your Button List. You can take some action based on which button was pressed.
Note: the Buttons may appear in a different order when testing the app on a device. The number that ‘buttonPressed’ returns is the order that the Buttons are added in the app project.
With no auth APIs there is no need to provide any credentials to access the API, they are publicly available.
You can add a Timer to your app from the Blocks tab of your Thunkable project. Under the App Features header, click the ⊕ icon next to Timers to add a Timer to your app.
The Timer's properties are initially set when you add a Timer to your project.
You will see the Timers you have added to your app underneath the Timers section of your blocks. To edit the properties after the fact or delete a timer, click the gear icon next to the Timer's name in the left panel of the Blocks tab.
Set something to happen when the Timer fires.
Starts the Timer.
Stops the Timer.
If Count Up
is false
, returns remaining time from the Timer's interval in seconds.
If Count Up
is true
, returns elapsed time from the Timer's interval in seconds.
If Count Up
is false
, returns remaining time from the Timer's interval in milliseconds.
If Count Up
is true
, returns elapsed time from the Timer's interval in milliseconds.
Set interval of Timer in milliseconds.
Returns interval of Timer in milliseconds
Set whether Count Up is enabled for this Timer.
Returns true
or false
value for whether Count Up is enabled for this Timer.
If Loops = true
, the timer will reset itself after it fires. If your interval is 10 seconds, the Timer will fire every 10 seconds.
If Loops = false
, the timer will finish its current interval if it is in the middle of one, and will no longer fire. If your interval is 10s, the timer will finish its current 10 second interval, fire, and then stop.
Returns true
or false
value for whether Loops is enabled for this Timer.
Set whether the Timer is enabled.
Returns true
or false
value for whether this Timer is enabled.
It is possible to add buttons to an alert for more sophisticated use cases.
This can be done using the set Button List to
block by creating a of .
These components require a little more set-up than the other , but deliver awesome functionality to your app.
Interval
How regularly the Timer fires, in seconds or milliseconds
Number
Count Up
True/False
Loops
Toggle whether the Timer will start again once it has fired
True/False
Enabled
Toggle whether the Timer is active in your app
True/False
Toggle whether the Timer's return the current time as counted up from 0 or counted down from the interval duration
Offer extra content and features your users can purchase — including digital goods, subscriptions, and premium content — directly within your app.
The IAP component works on the Android platform and iOS platform.
Currently, there is no support for IAP on web apps
The IAP component doesn’t work on the Thunkable live apps (Android/iOS)
Before you set up your IAP blocks in Thunkable, you need to establish a set of product IDs. Each product ID is associated with the item being paid for.
If you are developing for both Android & iOS, we suggest you use the same product ID for similar items in both stores.
Product IDs need to start with a number or lower case letter, and be 148 characters or less. They can contain any of the following characters: numbers (0-9), lowercase letters (a-z), underscores (_), and periods (.)
Select your product type:
In-App Product - a one-time purchase
Subscription - recurring purchases
Before you can create your In-App Purchases, you are required by Apple to request and fill out their Paid Applications contract.
To do so, log into your App Store Connect account, and go to the Agreements, Tax, and Banking section. In this section, you will see the ability to request the Paid Applications contract towards the top of the page.
After this is complete, you will now be able to add your In-App Purchases.
Consumable - a one-off purchase which can be repeated and keeps no history
Non-Consumable - a product that can only be purchased once and keeps history in your apple account. If you try and buy a second time, it reports you have already purchased and offers a free download
Auto-Renewable Subscription
Non-Renewing Subscription
To add IAP to your project, navigate to the block section and create an instance of the IAP component, which is nested under Advanced. You need to enter the product IDs from the store setups during the setup stage.
If you need to pull the product/subscription info from the Play Store or App Store, you can use the following block. For the fields in the return object, you can reference them here.
You can use the following blocks to start the one-time purchase or subscription. For the fields in the return object, you can reference them here.
You can use the following block to get the purchase history and you can verify the purchase from the return list. This block is helpful when you need to restore an existing purchase either on a new device or a new app installation. For the fields in the return object, you can reference them here.
The "Get Most Recent Active Purchase" block may crash your iOS app.
To test the IAP component, you have to publish it to the Google Play Store or App Store. You will not be able to test IAP with the Thunkable Live App or through Web Preview.
Be mindful to leave extra time for testing in your app development cycle to allow time for each respective store to review your apps. Depending on your stage of app development, a review could take anywhere from an hour to 4 days.
Testflight sets up a sandbox environment automatically. When you send your update to the app store, you are able to test without having it go to the live version.
You have to upload the APK or AAB file to the Play Store console before you can add any In-App Purchases.
There are two ways you can test how a pre-release app functions on the Google Play store: You can publish an app to the alpha or beta distribution channels. This makes the app available on the Google Play store, but only to the testers you put on a "whitelist."
In a few cases, you can test Google Play functionality with an unpublished app. For example, you can test an unpublished app's in-app billing support by using static responses, special reserved product IDs that always return a specific result (like "purchased" or "refunded").
At this time, there are no blocks to support in-app subscription management by the user.
Users can manage their own subscriptions in the Google Play Store or Apple App Store.
We recommend including instructions in your app or app’s website that outline the processes below.
Subscriptions on Google Play renew automatically unless you unsubscribe through the Google Play app. Uninstalling an app won't automatically cancel your subscription.
At the top right, tap the profile icon.
Select the subscription you want to cancel.
Tap Cancel subscription.
Follow the instructions.
Open the App Store app on your iOS device or on a computer
Sign in to the App Store if necessary
Choose a subscription, then do any of the following:
Change or cancel an existing subscription.
Resubscribe to an expired subscription.
On iOS you need to submit to the App Store via Testflight to test the features. You can read more about Testflight here: .
On Android publish to the Play Store via internal beta testing. You can read more about internal beta testing in the Play Store here: .
Open the Google Play app .
Tap Payments & subscriptions Subscriptions.
Read more about managing your Android subscriptions .
Tap or your profile picture at the top right, then tap Subscriptions.
with other family members in your Family Sharing group.
Read more about managing your iOS subscriptions .
The components in the ‘Any Component’ drawer are great tools to use instead of repeatedly using the same combination of blocks. They will also help you use fewer blocks in your app.
For example, to change the colour of any button on the screen to blue (the blocks on the left) we have to use 6 blocks. Using the ‘Any Component’ Blocks (on the right), we only need to use 2 blocks.
With the Generic Event block, you can set when an event will take place.
For example, in the picture below, any button you click on the screen will change the text of Label1 to be “Thunking Is Fun!”.
With the first dropdown menu, you can select what type of component you want to handle events for.
With the second dropdown menu, you can choose when an event will take place.
If you want to customize the button that you clicked on the screen, you can use this block.
With these blocks, anytime a button is clicked, the text of that button will be set to “I Love Thunkable!”.
With the Create Block, you can program your app to create visible components (things you can see--like button or images) while it is running.
When you use the create block, your app will automatically create something. For example:
This picture shows that when Screen1 Opens, your app will create a button and put it on Screen1.
With the first dropdown menu, you can select what type of visible component you want to create.
With the second dropdown menu, you can select where you want to position the component you are creating on the app’s screen.
Note: The options in the second and third drop down will vary depending on which component you select from the first dropdown. The following block creates a new button and places it as the first item on Screen1.
The table below explains the different block options:
Property
Description
As first in
This creates and positions the component as the first item in the specified row, column or screen.
As last in
This creates and positions the component as the last item in the specified row, column or screen.
Before
This creates and positions the component before the component selected in the third dropdown menu.
After
This creates and positions the component after the component selected in the second dropdown menu.
Note: You can replace the third dropdown with any block that represents a visible component using the component block. It can also be a variable function parameter, or any block whose value is a component.
If you want to customize the component you just created, you can use this block.
These blocks say, when any button on the screen1 is clicked, create a new label. Next, set the new label’s text to “I was just created!”.
The clone block makes a copy of an existing component in your app. For example, if you have a button on your screen and want to create another button that looks exactly the same, you can use the clone block to do that.
You can use the clone block instead of repeatedly using the same combination of blocks. This will also help you use less blocks.
Note: You cannot clone screens and invisible components with the clone block.
With the first dropdown menu, you can select the component that you want to clone.
With the second dropdown menu, you can select where you want to position the cloned component relative to another component on the app’s screen.
Property
Description
As first in
This clones and positions the component as the first item in the specified row, column or screen.
As last in
This clones and positions the component as the last item in the specified row, column or screen.
Before
This positions the cloned component before the component selected in the third dropdown menu.
After
This positions the cloned component after the component selected in the third dropdown menu.
Note: The options in the third drop down will vary depending on which component you select from the first dropdown.
If you want to customize a cloned component, you can use this block.
The Generic Method Block can be used to call functions for components that were made with the clone or create blocks.
The blocks above say that when Button1 is clicked, create a Web Viewer component and call the reload function for it.
With the first dropdown menu, you can select the component you want to call a function for.
The second dropdown menu allows you to select which function you want to call.
Notes: The options in the second drop down will vary depending on which component you select from the first dropdown. Also, the component you plug-in needs to be of the same type as the one in the first dropdown.
The Generic Set Block allows you to change properties such as text and colour of any component that is on the app’s screen.
Using the Generic Set Block
There are two ways to change the text of a component using the Generic Set Block.
Use the dropdown menu to select the component whose text you want to set
2. You can use the Component Item Block with the Generic Set Block to change the text of the component that was clicked.
The Generic Get Block allows you to get properties (such as text and color) of any component that is on the app’s screen.
You can use the dropdown menu to select the component whose text you want to get.
There are two ways to get the text of a component using the Generic Get Block.
Use the dropdown menu to select the component you want to get the text for.
2) You can use the Component Block, as well as the Component Item Block, with the Generic Get Block to select the component you want to get the text of.
The ‘All Components in Container’ block groups together all the visible components in a container (ie. Row, Column or Screen) that are of the same type, in a list.
The ‘All Components in Container’ block can be used with the loop block from the control drawer.
The combination of blocks above goes through all the buttons on screen1 and sets the text of each button to “Thunkable!”.
The Remove Block allows you to delete a component from your app. You can delete a component that you dragged out from the designer, cloned, or made with the create block.
There are two ways to delete a component using the Remove Block.
Use the dropdown menu to select the component you want to remove from the app.
2. You can use the Component Item Block with the Remove Block to remove the component that was clicked. You can also use a variable, function parameter or any block whose value is a component.
The Component Block has a dropdown menu which lists all the components that are on the screen.
You can select one of the components from the menu and use it within any of the blocks that have an input for a component. Some examples include: the clone, create or generic event block.
With these blocks, when Screen1 is opened, the Component Block sets the text of Button3 to be “I Love Thunkable!”.
When Screen1 opens, these blocks will tell your app to clone Button2, and then set the clone’s text to be “I was just cloned!” (Try this out for yourself ).
In the block above, all of the buttons that are on Screen1 are stored in list. This means that you can use blocks to select items from this list, eg. the first item in 'all Button in Screen1'.
Description
Bluetooth Low Energy, or BLE, is used to wirelessly connect two devices to one another. The BLE component allows you to find and connect to BLE devices and to communicate directly with them.
To add a Bluetooth component to your app:
Go to your Blocks tab
Find the Advanced
drawer of blocks. Click the drop-down menu icon to show the Advanced invisible components
Click the ⊕ icon next to the Bluetooth
drawer
You will see a dialog to create your Bluetooth component. Click Submit to create the component, or Delete to dismiss the dialog without creating the component.
Once you have added at least one Bluetooth component to your app, you will be able to view all of your Bluetooth components under the Bluetooth
drawer in the Advanced section of the Blocks tab.
To delete a Bluetooth component, click on the ⚙ icon next to the component's name to bring up the properties dialog and click Delete.
Version 1 of the BLE component in Thunkable ✕ contains 5 functions, each of which are documented in greater detail below.
This function is used to scan for nearby BLE or Bluetooth enabled devices. Scanning happens for 10 seconds. Once scanning has successfully completed then a list of the available device ids and a list of available names will be returned. If the scanning function can not be completed then an error will be returned.
Device Ids
List
Returns a list of the IDs of the available devices
Device Names
List
Returns a list of the names of the available devices
error
Text
Returns an error message from the function
The Connect to Device Id
function allows your app to connect to a BLE enabled device based in the Id of that device.
Device Id
Text
Expects a text string with the device id you want to connect to
Device Name
Text
Returns the name of the device you have just connected to
error
Text
If an error message is returned, returns the error. Else returns null
When you know the name of the BLE device that you want to connect to you can use the Connect to Device Name
block to connect directly to it. Please note that device names are not unique and it is relatively easy to change the name of a BLE device.
Device Name
Text
Expects a text block with the name of the device to connect to
Device Id
Text
Returns the ID of the device that you have just connected to
error
Text
If an error message is returned, returns the error. Else returns null
If connected to another Bluetooth device, this block will disconnect your app from the device.
If you have a BLE device that is capable of sending data to another device then you will need to use the Receive String
function in your app in order to listen to, or receive, data coming from the BLE device in String format.
You need to be connected to another Bluetooth device in order to use this block.
characteristic UUID
Text
Expects a text block with a 32-bit UUID for the BLE type, service or profile required
data (string)
Text
Returns a string containing the information received from the BLE device
error
Text
If an error message is returned, returns the error. Else returns null
If you have a BLE device that is capable of sending data to another device then you will need to use the Receive Byte Array
function in your app in order to listen to, or receive, data coming from the BLE device in Byte Array format.
You need to be connected to another Bluetooth device in order to use this block.
characteristic UUID
Text
Expects a text block with a 32-bit UUID for the BLE type, service or profile required
data (byte array)
Returns a byte array containing the information received from the BLE device
error
Text
If an error message is returned, returns the error. Else returns null
This asynchronous function listens for when your device disconnects from a named Bluetooth device.
You can program some events to happen when your device disconnects from the named device in the then do
section of this block.
Device Id
Text
Unique ID of the bluetooth device to listen for disconnection with
error
Text
If an error message is returned, returns the error. Else returns null
Use this block to send data as a string of text to a BLE device.
You need to be connected to another Bluetooth device in order to use this block.
characteristic UUID
Text
Expects a text block with a 32-bit UUID for the BLE type, service or profile required
data
Text
Expects a text block with the message that you want to send to your BLE device
error
Text
If an error message is returned, returns the error. Else returns null
You need to be connected to another Bluetooth device in order to use this block.
characteristic UUID
Text
Expects a text block with a 32-bit UUID for the BLE type, service or profile required
data
Expects a text block with the message that you want to send to your BLE device
error
Text
If an error message is returned, returns the error. Else returns null
You need to be connected to another Bluetooth device in order to use this block.
characteristic UUID
Text
Expects a text block with a 32-bit UUID for the BLE type, service or profile required
data (hexadecimal)
Expects a text block with the message that you want to send to your BLE device
error
Text
If an error message is returned, returns the error. Else returns null
BLE functionality can't be tested with the app on iOS. To test the BLE functionality in your app on iOS, please your app.
array () of bytes
Use this block to send data as an array () of bytes to a BLE device.
array () of bytes
Use this block to send data in format to a BLE device.
data in format
Please follow all of the included steps to setup and test your In App Purchases via the Android Play Store.
we cover this below
Click Create payments profile. Make sure to have your business information available to set up your payments profile.
Under "Payments profile," click the down arrow and select Create payments profile.
Name and address:
Enter the legal name of your business as you want it to appear on your payments profile. This information will be shown to your customers and also on your receipts.
Primary contact: Enter the name of an authorized representative for your company who Google can contact if we have questions about your payments profile. Provide an email address and a phone number (optional).
Enter the following public business information, or choose to match your public merchant profile and payments profile information:
Enter your business website.
Select the category of products that you sell.
Your customer support email.
The business/product name that'll appear on your customers' credit card statements.
Note: To help customers remember what they purchased and keep chargebacks to a minimum for you, use an appropriate credit card statement name.
After you create a payments profile it is automatically linked to your Play Console. Note: If you have set up a payments profile or merchant center account previously, it is already linked to your Play Console.
Before creating a product, make sure to plan your product IDs carefully. Product IDs need to be unique for your app, and they can’t be changed or reused after they’ve been created.
Product IDs must start with a number or lowercase letter, and can contain numbers (0-9), lowercase letters (a-z), underscores (_), and periods (.).
You can’t change or reuse a product ID after the product has been created.
Note: The product ID android.test
is unavailable for use, along with all product IDs that start with android.test
.
To create an in-app product:
Click Create product.
Enter your product details.
Product ID: A unique ID for your in-app product.
Title: A short name of the item (up to 55 characters, but we recommend limiting titles to 25 characters to display properly in all contexts), like "Sleeping potion."
Description: A long description of the item (up to 200 characters), like “Instantly puts creatures to sleep."
Icon: A unique and accurate image for your product. Don't include text, promotions, or branding. Your product icon is shown on your store listing and during the purchase flow.
32-bit PNG
512 px by 512 px
Up to 1 MB
Multi-quantity: Allow multi-quantity checkout for this product. Users will be able to purchase in multiple quantities within the threshold of their country/region. Note the following information:
Multi-quantity checkout is not available in some countries/regions.
In most countries/regions where Multi-quantity checkout is available, the SKU price threshold is around US$100. To allow multi-quantity checkout, you will need to adjust the price (before tax) to below the threshold in each country/region.
Play Points exclusive: Make your product available only in Google Play Points.
Save your changes and click Activate to make your in-app product available to users..
To be available for purchase, a product needs to be active, and its app needs to be published.
Before creating a subscription, make sure to plan your product IDs carefully. Product IDs need to be unique for your app, and they can’t be changed or reused after they’ve been created.
Product IDs need to start with a lowercase letter or a number and must be composed of only lowercase letters (a-z), numbers (0-9), underscores (_), and periods (.)
Note: The product ID android.test
is unavailable for use, along with all product IDs that start with android.test
.
To add a subscription:
Click Create subscription.
Enter your subscription details.
Name: A short name of the item (up to 55 characters, but we recommend limiting titles to 25 characters to display properly in all contexts) such as "Sleeping potion."
Description: A long description of the item (up to 80 characters) such as "Instantly puts creatures to sleep."
Benefits: Provide up to 4 benefits, which each describes a feature of the subscription (up to 40 characters each)
Benefits should highlight the features to give users a better idea of what your subscription offers, like “Full catalog of TV shows and movies.”
Since not all users will be eligible for a promotional price or free trial, the benefit should not mention free trial or price, for example “Try 7 days free” is not allowed.
Enter pricing details in the “Price” section:
Billing period: Choose the time interval between billing statements.
Default price: Enter a default price or import from an existing pricing template; this is used to generate local prices in other countries. Local prices use today’s exchange rate and country-specific pricing patterns. Countries without local currency support use your default price.
Choose and define additional options in the “Subscription settings” section:
Click Save.
Click Activate to make the subscription you created active.
To be available for purchase, a product needs to be active, and its app needs to be published.
With application licensing, you can set up a list of Gmail accounts to test your in-app billing and subscription integration. Your own publishing account is always considered a licensed tester.
You're able to purchase your own app, in-app item, or subscription as a test purchase. Once you've set up application licensing, authorized users can also purchase in-app products and subscriptions without charging the users’ accounts.
When making a purchase from a license test user, you will see two choices for payment method:
“Test card, always approves”
“Test card, always declines"
Before they can be tested, your in-app products and subscriptions need to be published.
When testing consumable products, we recommend testing a variety of situations, including the following:
A successful purchase where the user receives an item. With a license tester, you can use the Test instrument, always approves payment method.
A purchase where the payment method failed to be charged, and the user should not receive the item. With a license tester you can use the Test instrument, always declines payment method.
Ensure items can be purchased multiple times.
Non-consumables should be tested the same as consumables, but you should verify an item cannot be purchased again within your app. Be sure to verify purchase acknowledgement for both non-consumables and consumables (when applicable) since the logic to process each the two types of purchases vary.
The purchase flows for one-time products and subscriptions are similar, but subscriptions have additional scenarios, such as successful or declined subscription renewals. To test renewals, you can use the Test instrument, always approves and Test instrument, always declines payment methods that are available for license testers, as shown in figure 1. Use these payment instruments to test scenarios beyond the successful subscription scenario.
Test subscriptions renew more quickly than actual subscriptions, and test subscriptions can renew a maximum of six times.
The following table lists the testing renewal times for subscriptions of various durations. These times are approximate. You may see small variations in the precise time of an event. To compensate for variation, call the API to view the current status after every subscription expiration date.
Production subscription period
Test subscription renewal
1 week
5 minutes
1 month
5 minutes
3 months
10 minutes
6 months
15 minutes
1 year
30 minutes
Time-based subscription features such as free-trials are also shortened for testing. The following table identifies the testing time periods associated with time-based subscription features:
Feature
Test period
Purchase acknowledgement
5 minutes
Free trial
3 minutes
Introductory price period
Same as subscription test period
Grace period (both 3- and 7-day)
5 minutes
Account hold
10 minutes
Pause (1 month)
5 minutes
Pause (2 months)
10 minutes
Pause (3 months)
15 minutes
This next step is vital for subscriptions. If you don't complete this step, you wont be able to 'acknowledge' subscriptions. For android IAP, 'acknowledging' is how you complete the transaction and if not completed the transaction will revert and you as the developer will not make money on that purchase plus your users will likely have an unpleasant experience (i.e. they loose access to the thing they wanted to buy).
To do this process you need to make API calls. Before you can start making API calls, you need to set up API access to your Google Play Developer Account. This involves changes in both the Google Play Console and Google Cloud Console. The following instructions explain the four steps needed to start using the Google Play Developer API.
Link your developer account to a new or existing Google Cloud Project.
Enable the Google Play Developer API for your linked Google Cloud Project.
Authorize an API key for the Google Play Developer API in your linked Google Cloud Project.
Set up a service account with appropriate Google Play Console permissions to access the Google Play Developer API.
Before you can access the Google Play Developer API, you must link your Google Play Developer Account to a Google Cloud Project. In most cases, we recommend that you create a new Google Cloud Project dedicated to your Google Play Developer Account, but you can link an existing project. Keep in mind that each Google Play Developer Account can only be linked to a single Google Cloud Project. If you have multiple apps in the same Google Play Developer Account, they all must share the same Google Cloud Project.
Click Create new project.
The Google Cloud Project is automatically created and linked to your Google Play Developer Account.
If you are already a user of the Google Cloud Console, you can link to your existing Google Cloud Project by following these steps:
Choose the project you’d like to link. If your project isn't listed, verify that your user account is designated as Owner in the Google Cloud Project you want to link.
Click Link existing project.
Once you have set up the linked Google Cloud Project, you need to enable the Google Play Developer API for this project. To do this, you need to be an owner of the Google Cloud Project.
Under APIs, find the Google Play Developer API and click Turn on.
This directly updates the Google Cloud Project and the change takes effect immediately.
To use the API, you need an API key in your linked Google Cloud Project that is authorized to use the Google Play Developer API. Set this up in the Google Play Console.
You need to configure access to the Google Play Developer API with an OAuth client or a service account. In most cases, you should use a service account to access the API.
Service accounts must be used in a secure environment, such as your server. The service account credentials need to be securely managed so they are not revealed to anyone that is not authorized to use the API.
The OAuth Client ID should be used if you need to access the API on behalf of an individual user. For example, if your website needs to access the Google Play Developer API from the web client on behalf of the user, you can use the Client ID. The user will be authenticated with their Google account instead of the service account. This allows you to make API calls on behalf of a user without compromising service account credentials.
Service account: A secure software service will access the API (most common)
OAuth clients: A user will access the API
Under Service accounts, click Create new service account.
Follow the instructions to create your service account.
During the process of account creation you need to grant your service account access to the Google Cloud Project in order for it to appear in the Google Play Console.
Click Grant Access to provide the service account the necessary rights to perform actions.
To use the Google Play Billing APIs, you must grant the following permissions:
View financial data, orders, and cancellation survey responses
Manage orders and subscriptions
3. Find and click on the service account in the list in the Google Cloud Platform
4. Click the Keys tab
5. Click "Add key" then "Create new Key"
6. Select JSON as the key type and click Create. The file will automatically download to your default download folder.
Using , you can offer in-app products that charge users on a one-time basis, known as in-app products. In-app products can include items like virtual goods (for example, game levels or potions) and premium services within your app on Google Play.
You can also , which charges users on a recurring basis.
Important: Google Play and apply to all in-app products, including both one-time products and subscriptions
Create a payments profile in payments center to manage and track your app sales from Play Console. Review the list of .
Sign in to .
Go to the page (Settings > Developer Account > Payment settings).
Provide your legal business address as it appears on official documents. It’s important that we have a valid physical address on file for your business. We don't allow you to use a PO box address. Later, you'll need to make sure that your bank account is registered in the same country listed in your payments profile. Learn more .
When you're finished, click Submit. Note: You cannot change your business location country but you can later.
Open Play Console and go to the page (Monetize > Products > In-app products).
Price: Enter a price in your local currency or .
To configure multi-quantity checkout in Play Console, your app needs . Visit the to learn how to integrate the Google Play Billing Library into your app
If you’re using a test account, active items are available in unpublished apps. To learn more, go to the .
In-app products use the same default language as their app. To add translations in specific languages, select an in-app product, and then click Manage translations and apply the languages you want. .
Review Google's updated in the Developer Policy Center to ensure your app is compliant with the latest changes.
Using , you can offer in-app products that charge users for content or services on a recurring basis, known as subscriptions. Subscriptions can include items like a collection of apps, games, or other content for a recurring fee within your app on Google Play.
You can offer multiple subscriptions within the same app. Subscriptions must be priced within the . Subscriptions can't be unpublished.
You can also , which charges users on a one-time basis.
Important: Google Play and apply to in-app products and subscriptions.
If you’re in a supported location and want to start using Google Play's billing system features in your apps, and .
Note: Weekly subscriptions can now be charged using Direct Carrier Billing (DCB). For more information, review the .
Read more about Google in-app subscriptions .
Adding a subscription is similar to , except the price is set for a period of time.
Before adding a subscription, review our .
Open Play Console and go to page (Monetize > Products > Subscriptions).
Free trial: You can let users try your subscription before they pay. If you select Enabled, choose how many days you want to make it available for free. Learn more .
Introductory price: You can offer new subscribers a discounted price for a specific duration. If you do, this must be within the accepted price range and cost less per day than the original price. Learn more .
Grace period: You can give users time to resolve payment issues while keeping their subscription active. Grace periods can be 3 days, 7 days, or 14 days. Learn more .
Resubscribe: Enabling resubscribe allows users to resubscribe from the Play Store after cancellation. Learn more .
If you’re using a test account, active items are available in unpublished apps. To learn more, go to Google's site.
To set up , start by adding your list of testers' Gmail addresses in Play Console.
Open .
Your app has been published to the open, closed, internal test, or production track. We recommend publishing your app to the internal test track. Make sure that your testers are also eligible to receive your release by following the instructions for or using .
You've .
Learn more about and using .
You should also verify that purchases are properly acknowledged as described in . For purchases from license testers, a purchase will be refunded after 3 minutes if your app does not acknowledge the purchase and you will receive an email about the cancellation. You can also check the Orders tab in the Google Play Console to see if an order was refunded after 3 minutes.
Similar to one-time products, you should also verify that purchases are properly acknowledged as described in . For purchases from license testers, a purchase will be refunded after 3 minutes if your app does not acknowledge the purchase and you will receive an email about the cancellation. You can also check the Orders tab in Google Play Console to see if an order was refunded after 3 minutes.
Go to the page on the Google Play Console.
Go to the page on the Google Play Console.
Go to the page on the Google Play Console.
You can create a from the Google Play Console.
Go to the page on the Google Play Console.
Once you’ve created the service account on the Google Play Console, click Done. The Service Accounts section of the page automatically refreshes, and your service account is listed.
At this point, you should be able to access the Google Play Developer API through the service account. For more information, see .
Go to your in the Android Developer Console
Find the service account you created in and click "View in Google Cloud Platform"
The sound component plays a designated sound.
You can right-click any block to show an advanced version of the block.
These blocks will return an error
output block. If there is en error with executing the block, the error block will return an error message. If not, the error block will return a null value.
Play a selected sound. This can be an audio file that has been uploaded to your project, or a URL that streams audio.
Pause a selected audio file that is currently playing.
Resume a selected audio file that has been previously paused.
Returns true if named sound file has been partially played, then paused. Returns false otherwise.
Records for the specified amount of seconds, then returns the recorded audio.
The start recording block begins a recording.
The sound file from stopped recording block will stop the recording initiated by the start recording block, and return the recorded sound file.
Stop a selected audio file that is currently playing. A sound that has been 'stopped' cannot be resumed using the block.
The label component allows you to display text in your app.
You can customize your label using the following properties:
Text
Text that appears on the label
Text
Font
Font used to display Label's text
Select from menu
Custom Font (mobile only)*
Font used to display Label's text
OTF or TTF file
Color
Color of the text that appears on the label
Color
Font Weight
Make the label's text bold
True/False
Font Style
Make the label's text italicized
True/False
Underline
Underline the label's text
True/False
Strikethrough
Apply strikethrough formatting to the label's text. You can further select the strikethrough's color and style.
True/False
Text Align
Set alignment of the text relative to the Label's outline
Select from menu
Font Size
Size of the text that appears on the label
Number
Number Of Lines
Maximum amount of lines of text that your Label will display
Number
Writing Direction
(iOS and web only)
Writing direction of your Label's text
Select from list [left-to-right, right-to-left]
Letter Spacing
(iOS and web only)
Spacing between letters of your Label
Number
X
Location of your Label on the X-axis in pixels
Number
Y
Location of your Label on the Y-axis in pixels
Number
Height
Height of your Label in pixels
Number
Width
Width of your Label in pixels
Number
Resize Mode
Stretch the label to fit the device screen or render it the same as the design, regardless of the device (float in place).
Select from menu (Stretch, Float in Place)
Visible
Toggle whether your end users can see the Label
True/False
Background Color
Color of your Label's background
Color
Border Style
Style of Label's Border
Select from list [solid, dotted, dashed]
Border Color
Color of the Label's Border
Color
Border Width
Width of border outline in pixels
Number
Border Radius
Radius of corners of Label
Number
Shadow Color
Color of Label's shadow
Color
Shadow Opacity
Opacity of Label's shadow
Number between 0 and 100
Shadow Radius
Radius of corners of Label's shadow in pixels
Number
Shadow Offset
How far the Label's shadow is offset, in Height and Width, in pixels
Number
This event will fire when the user clicks on the label.
The get and set font size blocks are used to work with the size of the text that is displayed in the label. This value must be a number.
The font style property can be either "Normal" or "Italic".
The font weight value can be either; "Normal", "Bold" or a a value from 100 to 900
The set and get height blocks work with the Height property of the label component. Acceptable input values are.
Number of Pixels
Percentage Height
"Fit Contents"
"Fill Container"
The Computed Height
block returns the on-screen dimensions of the label, after it has been rendered on-screen. The value returned is an integer, representing the size of the label in pixels.
The get and set number of lines property is used to work with the maximum number of lines of text that should be displayed in a label before that label starts to scroll.
This property corresponds to the text that is displayed in the label component.
Text Align can be any of the following values:
Auto
Left
Right
Center
Justify
The set and get visible blocks are used to show or hide the entire image component. Acceptable values are:
True
False
The set and get width blocks work with the Width property of the label component. Acceptable values are.
Number of Pixels
Percentage Width
"Fit Contents"
"Fill Container"
The Computed Width
block returns the on-screen dimensions of the label, after it has been rendered on-screen. The value returned is an integer, representing the size of the label in pixels.
Uploading a custom font is available on Thunkable's Business and Enterprise plans.
The get and set background color properties work with the color of the label itself i.e. the region behind the label text. Best practice is to use one of the to set this value but HEX or RGB values may be used too.
The get and set color properties can be used to work with the color of the text that is displayed in the label. Best practice is to use one of the to set this value but HEX or RGB values may be used too.
You can click on the gear icon to add properties to your object:
Similarly, you may want to convert an Object to JSON to make an API POST, or set headers or query parameters for your API call. You can do this with the generate JSON from Object
block:
You can use the get property
block to read the value of an object's property.
If the object does not have a property with this name, it will return undefined
.
The Get Values Of block can be used to get nested values, ie. properties of properties of an object. If you are trying to get nested property b of property a of an object, you can simply get property a.b of an object, instead of using multiple get property of blocks.
You can also get a value from an Array (or list) of values. If an object property b is a 3-items list, and you want to get the second item of that list, you can get property b[2] of that object. The first item of the list is at index 1.
The blocks below demonstrate each of these methods, as well as a block that combines these methods by getting a value from an array that is a nested property of an object. The blocks are presented with the objects written in JSON format as well as created with Objects blocks, but both sets of blocks are doing exactly the same thing. In these blocks, Get nested property
will return 5, Get value from array
will return 6, and Get value from nested array
will return 7.
You can use the get Object properties of
block to return the names of the properties of an object.
With the set property
block, you can change the value of a single property of an object.
Often, when retrieving data from an API, you will get a large data dump in JSON format, as shown below.
{ "response": { "version": "0.1", "termsofService": "http://www.wunderground.com/weather/api/d/terms.html", "features": { "conditions": 1 } }, "current_observation": { "image": { "url": "http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png", "title": "Weather Underground", "link": "http://www.wunderground.com" }, "display_location": { "full": "San Francisco, CA", "city": "San Francisco", "state": "CA", "state_name": "California", "country": "US", "country_iso3166": "US", "zip": "94101", "latitude": "37.77500916", "longitude": "-122.41825867", "elevation": "47.00000000" }, "observation_location": { "full": "SOMA - Near Van Ness, San Francisco, California", "city": "SOMA - Near Van Ness, San Francisco", "state": "California", "country": "US", "country_iso3166": "US", "latitude": "37.773285", "longitude": "-122.417725", "elevation": "49 ft" }, "estimated": {}, "station_id": "KCASANFR58", "observation_time": "Last Updated on June 27, 5:27 PM PDT", "observation_time_rfc822": "Wed, 27 Jun 2012 17:27:13 -0700", "observation_epoch": "1340843233", "local_time_rfc822": "Wed, 27 Jun 2012 17:27:14 -0700", "local_epoch": "1340843234", "local_tz_short": "PDT", "local_tz_long": "America/Los_Angeles", "local_tz_offset": "-0700", "weather": "Partly Cloudy", "temperature_string": "66.3 F (19.1 C)", "temp_f": 66.3, "temp_c": 19.1, "relative_humidity": "65%", "wind_string": "From the NNW at 22.0 MPH Gusting to 28.0 MPH", "wind_dir": "NNW", "wind_degrees": 346, "wind_mph": 22.0, "wind_gust_mph": "28.0", "wind_kph": 35.4, "wind_gust_kph": "45.1", "pressure_mb": "1013", "pressure_in": "29.93", "pressure_trend": "+", "dewpoint_string": "54 F (12 C)", "dewpoint_f": 54, "dewpoint_c": 12, "heat_index_string": "NA", "heat_index_f": "NA", "heat_index_c": "NA", "windchill_string": "NA", "windchill_f": "NA", "windchill_c": "NA", "feelslike_string": "66.3 F (19.1 C)", "feelslike_f": "66.3", "feelslike_c": "19.1", "visibility_mi": "10.0", "visibility_km": "16.1", "solarradiation": "", "UV": "5", "precip_1hr_string": "0.00 in ( 0 mm)", "precip_1hr_in": "0.00", "precip_1hr_metric": " 0", "precip_today_string": "0.00 in (0 mm)", "precip_today_in": "0.00", "precip_today_metric": "0", "icon": "partlycloudy", "icon_url": "http://icons-ak.wxug.com/i/c/k/partlycloudy.gif", "forecast_url": "http://www.wunderground.com/US/CA/San_Francisco.html", "history_url": "http://www.wunderground.com/history/airport/KCASANFR58/2012/6/27/DailyHistory.html", "ob_url": "http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.773285,-122.417725" } }
You may just want to pull out one attribute (like temp_f or the temperature in Farenheit). To do so, you'll need to use the object blocks below:
The Object blocks pair well with the , and components which often send data in object format.
You can use the following block to create a new object. Objects can be uploaded to your as the value of a .
Sometimes, you want to convert between JSON (JavaScript Object Notation) and Objects. If an returns a JSON value, you can convert it to an Object to use with Object blocks. Use the get object from JSON
block:
This block returns a list of property names. This list can be used with blocks.
You can use Object blocks when making calls to an