FlutterFlow is one of the world's most popular platforms for quickly developing mobile, desktop, and web apps without writing your own code. Using FlutterFlow's UI, you can rapidly create and test apps. It's not well-suited for complex, long-term app projects, but it's one of the best tools for prototypes and simple apps.

Now if you're an app developer working with FlutterFlow and you need data from Google to display in your app, SerpApi slots in easily to do just that.

SerpApi scrapes public search results from engines such as Google, Bing, DuckDuckGo, and many more. SerpApi then packages up the results into clean, easy-to-consume JSON via our APIs.

In this tutorial, I'll show you how to query SerpApi to get Google results and make use of them in a FlutterFlow app. We'll use the Google Shopping API to get shopping results for our app, but this tutorial can be used to integrate any of our APIs with FlutterFlow.

Let's get started.

Scrape Products from Google Shopping

First, you'll need a SerpApi account and API key. You can create an account and get 100 free searches per month through here: https://serpapi.com/users/sign_up

Once you're set up and logged in, you can find your API key here: https://serpapi.com/manage-api-key

Let's do a quick preview of the Google Shopping API data before jumping into FlutterFlow. We'll use the API Playground to run a simple query. I'm writing this shortly after Christmas, and I confess I still have mince pies on the mind. Let's do a shopping search for that: https://serpapi.com/playground?engine=google_shopping&q=mince+pies&location=Charleston%2C+South+Carolina%2C+United+States&gl=us&hl=en

Checking the JSON response, we see a shopping_results array with all of the products that Google returned. Our app will display the name of the product, its price, and a thumbnail image. This data is available for each product as highlighted by the red arrows below.

That was straightforward enough. Let's move on to the more complex part: getting this data into FlutterFlow!

FlutterFlow Setup

If you don't have a FlutterFlow account already, you can create one here: https://app.flutterflow.io/create-account

Once logged in, create a new project.

Give your project a name and select "Create Blank" to start with a blank project.

FlutterFlow will then prompt you to select a few more details. I've left everything as the default except I've disabled the "Setup Firebase" option to simplify the initial setup. This can be done later.

If this were a real app you wanted to publish, I would recommend updating the "Package Name" field. For demo purposes, we can leave this as is.

Click "Start Building" once you're ready.

Adding an API Call to FlutterFlow

Once your project is created, you'll be taken to the main editor for your app. We'll start by adding the API call to SerpApi.

From the side navigation, look for the button for "API Calls". See the screenshot below for reference.

From the API Calls page, hit the "Add" button.

We'll create just a single API call so select that option.

Give your API Call a name and put in the base URL of SerpApi: https://serpapi.com/search.json

Next, navigate to the "Query Parameters" tab where we'll add some params.

We'll need to add the following params:

  1. engine which will be a "Specific Value" of type "String" with a set value of google_shopping.
  2. api_key which will also be a "Specific Value" of type "String" with a set value of your API key.
  3. q which will be sourced "From Variable" from the variable named q. When you select "From Variable", the "Select Variable" menu will have a button to "Create Variable". Hit that to automatically create a variable of the same name as the query parameter.

The final configuration of the parameters should look like this:

Next, move over to the "Variables" tab to configure the q variable. It should be a "String" and you can set the "Default Value" to whatever you want. I've opted to make the default my beloved mince pies.

Time to try out our API call. Switch over to the "Response & Test" tab and hit "Test API Call". You don't need to populate the q variable since we set a default value in the previous step that will automatically be included.

If all went well, the "Preview" will show a successful response.

You can also scroll down and check out the "Response Type" options such JSON Paths. These JSON Paths are the paths we'll use to reference certain objects and fields in the JSON response of our API call.

Since this all looks good, go ahead and hit "Add Call" to add this to our project.

A quick note on security. If this were a real app, you would want to configure this API call as private to protect your SerpApi. This requires configuring Firebase or Supabase which is outside the scope of this tutorial. Please see FlutterFlow's documentation for instructions on how to do this.

Run API Call on Page Load

To prevent our app appearing empty when a user opens the home/main page, we'll run our default SerpApi Google Shopping query when it loads.

From the API Calls page of FlutterFlow, navigate to the "Widget Tree" page. See the screenshot below for reference.

Make sure the "HomePage" is selected in the Widget Tree.

On the right side of the FlutterFlow dashboard, click the "Actions" icon. I've highlighted this in a red box in the screenshot below. Then hit the "+ Add Action" button.

The "Define Action" menu should now appear and default to an action type of "On Page Load" which is exactly what we want.

Open the menu section for "Backend/Database" and select "API Call".

Now the basic Action is created, but the details need to be configured. Click the "Open" button to access the Action Flow Editor.

Set the "Group or Call Name" to the Google Shopping API call we created previously.

FlutterFlow will tell us there's an error/bug with the bug icon in red in the upper right. To resolve this, we need to tell FlutterFlow what to do if the API call fails. Click the "+" sign after "FALSE" in the Action Flow Editor.

We can tell FlutterFlow just to terminate the action for now to let it fail quietly.

Now we can test this action by clicking the blue button in the upper right corner with a lightning bolt in it. This will compile your app and create a test session for interacting with your app from the browser. It will take a couple minutes to load.

Of course we won't see anything in the actual app preview because we didn't add any content, but using the Debug Panel, we can check to see if our Google Shopping query ran successfully.

Check under Action Output for our API call with a statusCode of 200.

You can also check the body field to see if it contains what you expect.

Hopefully you see the API call executed exactly as configured in the previous step. If anything looks off, please go back and double check you created the API call correctly.

As an optional final step to distinguish this API call from the one we'll create later, let's rename the output of our API call from the auto-generated apiResultr5p (yours will be different) to something descriptive.

Update the "Action Output Variable Name" on our Backend Call to be something like pageLoadAPIResult.

Store API Results in a Page State Variable

Okay, we have some product data available to our app. Let's now present it to our users when they load the app.

The first step is to create a "Local Page State Variable". This is where we'll store the API shopping data and then reference it in order to display a list of products.

Once again make sure you've selected the "HomePage" from the Widget Tree and click the State Management icon. I've highlighted it in red below. Then click "+ Add Field."

I'll call the field googleShoppingResults and set the type as JSON. Then hit "Confirm".

Navigate back to the Action Flow Editor for our page load API call. Click the "+" button in our "TRUE" workflow.

Then select "Add Action".

Under "State Management", select "Update Page State".

Click "+ Add Field"

Select the googleShoppingResults field we created.

Change "Select Update Type" to "Set Value".

Change "Value to set" to the API result under Action Outputs.

Select "JSON Body" for "API Response Options".

The final setup should look like this:

Let's run the app in test mode again to ensure the variable is set correctly.

You should now see a Page State section in the Debug Panel with our googleShoppingResults field and the value of it should be the JSON body of the API call.

Displaying Products in a List

Finally, we can turn to adding content to our app.

FlutterFlow defaulted my app's content to list "Column" first before the "AppBar" even though the "AppBar" displays at the top. I've dragged the "Column" widget that will hold our app content under "AppBar" to make this more intuitive. You don't need to do this though.

First, we'll select the "Column" and click the "Add a child to this widget" button.

We'll add a "ListView".

Select the "ListView" in the Widget Tree and then open the "Generate Dynamic Children" menu on the right hand side.

Here we can tell FlutterFlow we have a list of items we want to display as a list. FlutterFlow will then dynamically display each item in the list.

Give it a descriptive "Variable Name" like shoppingItems. Then set the "Value" as googleShoppingResults located under the "Page State" options.

After selecting googleShoppingResults, set "Available Options" to "JSON Path" and the "JSON Path" to $.shopping_results so FlutterFlow will know exactly where the list of items is in our API JSON response. Then click "Confirm".

You can now save this. FlutterFlow will show you a notice about how this feature works. Just press "Ok".

Now we can add child widgets to the ListView and they will be applied to all items in our shopping results list.

Click the "Add a child to this widget" button for the ListView.

We'll first add a Row to hold our content for each product.

Then we'll add a child widget to the Row. We'll add an Image.

We need to add some text next; specifically we'll want to display the product name and price. In order to display these two text items vertically next to the image, we need to add a Column within our Row or more precisely, as a child widget under our Row.

Next we'll add two Text child widgets inside our Column.

The final setup should look like this:

Now let's get rid of these placeholders and insert our real data.

Starting with our Image widget, open the "Properties" tab on the right side. We'll need to update the "Path" to the thumbnail image included in the Google Shopping API results.

Click the settings icon next to "Path" to open the menu.

Select "shoppingItems Item".

Change "Available Options" to "JSON Path".

For JSON Path, we need the path to the thumbnail image for a product. If you recall from the SerpApi Google Shopping response body, every product has a thumbnail field. We can simply reference this by setting "JSON Path" to $.thumbnail.

Leave everything else as is and click "Confirm".

Moving on to our text fields. Select the first Text widget and view its Properties. We'll set the Text field the same way we did the image. Press the little settings icon next to Text.

Select the "shoppingItems Item" option again just like we did before.

Repeat the previous setup, but set the "JSON Path" to $.title. Then hit "Confirm".

Repeat these steps for the second Text widget. For this one, we'll use the price field by setting the "JSON Path" to $.price.

With those 3 widgets configured, we can now see how this looks in Test Mode.

This shows everything we want. We have the image, product name, and price. However there are some app spacing issues we need to resolve.

Resolving pixel overflow in FlutterFlow is a rather large topic with many different approaches. If you want to find the best approach for your app, I suggest FlutterFlow's blog post on this topic. For this tutorial, we'll implement a couple very simple solutions.

First we'll fix the bottom overflow. This can be resolved by enabling scrolling. We want scrolling anyway so users can see the full list of products available.

Select the Column that holds our ListView in the Widget Tree.

Click the icon to allow scrolling under "Properties". You can leave the other fields blank.

Next, we'll fix the horizontal right overflow. The easiest way to resolve this is to adjust the Column widget holding our text. Select the Column holding the text. It should be the last Column in the Widget Tree.

Under Padding & Alignment, select the Expanded option as the red arrow points to.

Let's check again in Test Mode. The overflow warnings should be gone and you should now be able to scroll vertically.

Our users probably want to search for things besides mince pies so let's add a search box to accomplish that.

We'll add a form within the top Column of our Widget Tree that holds our ListView. Another child for this Column.

Search for form and select the Form Validation widget.

The Form will be inserted at the bottom of our Column. Drag it to be above the ListView because we want this to appear before our list of products.

Next, add a Row within the Form as a child.

Add a TextField within the Row as a child.

Finally, add a Button within the Row as a child to sit next to our TextField.

Your Column should now look like this in the Widget Tree.

We can now configure our Form. First, let's adjust the Hint Text that will appear as a placeholder.

Select the TextField widget and find the "Hint Properties" menu under its Properties. Change the "Hint Text" to something like "Enter your search".

Then select the Button widget. Find the "Button Text" menu under its Properties. Update the "Text" to "Search".

Let's also set the button color to something more eye-catching. Scroll down the Button Properties until you find the "Button Default Style" menu. Change the Fill Color to whatever you prefer. I'll opt for #1d9508.

And since we're on the topic of style adjustments, let's update the text at the top of our AppBar. Select the Text widget under the AppBar.

Update the Text under the Properties menu to something else. I've opted for "SerpApi Shopper".

The top of our app should now look like this:

The search form looks the part, but doesn't do anything. Let's wire it up to an Action that will hit the Google Shopping API with whatever our user searches for.

Select the Button widget. Navigate to its Action menu and click "+ Add Action".

It should default to "On Tap". Open the "Backend/Database" menu of the Action and select "API Call".

The Action Flow Editor should be familiar to you after setting up on the page load action. We'll do mostly the same setup here except this time we need to set a variable based on the value in our form. We'll also re-name the Action Output Variable Name upfront this time.

Let's change the output name to buttonTapAPIResult.

Then hit the "+ Set Additional Variable" button to configure this.

Set the "Variable Name" to q.

For the Value, open the menu and open "Widget State". Then select "TextField (Enter your search)".

For the "FALSE" workflow, add a terminate like we did before.

For the "TRUE" workflow, add another action. The setup is exactly the same as the first time we did this, but this time we'll select the output from the buttonTapAPIResult API call.

The action definition should look like this:

And the overall Action Flow should look like this:

Let's give this a whirl in Test Mode. We should now be able to search for anything we want.

Looks good!

I think this is a good point to leave it. Of course if this were a real app, we would still have a lot of work to do. This post is long enough already, and the next steps require getting very deep into FlutterFlow that would get a little out of scope.

Here is what I would recommend doing next:

  1. Secure your API call: Depending on how you deploy this app, your SerpApi key could be exposed. To protect your key, follow steps to make the API call private.
  2. Handle empty shopping results: What will your app do if Google Shopping returns no results for a user's query?
  3. Handle API call errors: For now, we've just terminated the Action Flow if there's an error. What user experience would you want instead if an API call fails?

That's all for now. Thank you for following along! If you have any questions, please don't hesitate to contact us at contact@serpapi.com