# 👋🏽 Welcome to Browserflow

Browserflow is a no-code/low-code Chrome extension that allows you to automate your work on any website. To learn more, visit the official website: <https://browserflow.app>

Instead of manually clicking, typing, copying, pasting, and moving data between a dozen web apps, Browserflow lets you blaze through your repetitive tasks with a single click. It's like having superpowers in your browser.

Here are some things people have used Browserflow for:

* Operations: [Managing a Shopify store](https://twitter.com/deliberatecoder/status/1307011424196136960)
* Support: Responding to hundreds of customers on Intercom after a service outage
* Publishing: Importing content from Google Docs and formatting it on Substack
* Knowledge management: [Saving data from websites directly to Roam](https://twitter.com/Bieber/status/1360709205188108297)
* Social media automation: [Running a giveaway on Twitter](https://twitter.com/lunchmoney_app/status/1367346227398930433)

## Getting Started

1. [Install Browserflow](https://chrome.google.com/webstore/detail/browserflow/hfjnppljknigdnnpocjjgdcfmnodoafe)
2. [Build your first flow](https://browserflow.app/tutorial)
3. [Join the Browserflow Discord](https://discord.gg/W3WUK58aSW)

## Tutorials

You can find tutorials for the most common scenarios in the [Tutorials section](https://browserflow.app/tutorials).


# Building a flow

There are two ways to build a flow:

1. Recording actions
2. Adding commands manually

## Recording Actions

The easiest way to build a flow is by recording your actions. You can start recording recording your actions by clicking "Add Command" and selecting "Start Recording":

![](/files/-Mfj338kekmVqe9u5ENw)

When recording, Browserflow will automatically detect all actions performed in the active tab and add them as Browserflow commands.

These actions are currently not automatically detected in recording mode and must be added manually:

* Hover

### Select Element

Clicking "Select Element" in recording mode allows you to select an element and choose between common actions that may be performed on that element.

![](/files/-Mfj5kXUrTbIniky-dXw)

This makes it easy to extract data from many elements on the page compared to adding `Get Element Text` and `Get Link URL` commands individually.

### Select List

Clicking "Select List" in recording mode allows you to select a list of common elements and perform actions on each of them inside a loop.

![](/files/-Mfj6JhVId1M1Q1CfmDG)

## Adding Commands Manually

Commands can be added manually by clicking the plus button at the bottom of the flow or between commands:

![](/files/-Mfj7MXMHtVcno2tyM7G)


# Running a flow

{% hint style="warning" %}
While a flow is running, do not manually interact with the page (click, scroll, etc.) or the flow will likely break
{% endhint %}

{% hint style="info" %}
Flows must run in the active tab of a window. If you'd like to browse while running a flow in the background, create a new window.
{% endhint %}

The Browserflow editor can be opened by clicking the extension icon or pressing the [keyboard shortcut](/guides/keyboard-shortcuts) on any page.

Once the editor is open, a flow can be run by:

* Clicking the play button next to a flow's name (flow list screen)
* Clicking the Run button (flow screen)

![](/files/-Mfj8rWgktL1qm6eQDje)


# Debugging a flow

Sometimes your flows won't work as expected, and you'll need to dig a bit deeper. Here are some ways to help debug your flows.

## Step Button

The Step button allows you to run a single command at a time:

![](/files/-Mfj9GjXvEz6ngQVq_MV)

You can use the Step button to check the result after each command and make sure that each step works as expected.

If you find that your flow works correctly when you step through the flow, but that it breaks when you run it normally, this might mean that there is a race condition. In other words, Browserflow may be performing actions before the website can properly handle it.

One way to work around this is to add `Wait` commands to make Browserflow wait after a command before proceeding. If you encounter this scenario, it may be indicative of an issue with Browserflow — [please report it as an issue](/support/getting-help).

## Disable Commands

If you want to test only a few steps of your flow, you can disable commands to skip them when your flow is run:

![](/files/-Mfj9dJFb_rQISuEU_QZ)

## Add Breakpoints

The `Wait` command can be used as a breakpoint by selecting "Wait until resumed" as the type. This command will pause the flow until it is resumed by clicking "Run" or "Step". It is useful for running the flow until a certain point.

{% hint style="danger" %}
The "Wait until resumed" type for the `Wait` command is a temporary solution for supporting breakpoints and will likely be removed at some point in favor of an improved solution.
{% endhint %}

## Console

The console provides information that's useful for debugging your flow.

### Logs

The logs tab shows a record of all commands that have been run and any errors:

![](/files/-MToEHhr0a8Un_a5YJeJ)

Clicking on a log message will highlight the command that was running at the time.

### Variables

The variables tab shows the current value of each variable:

![](/files/-MToEqyvLTcNSx0Dq11o)

Stepping through the flow and inspecting the variables is often helpful for identifying issues with a flow.

### Output


# Sharing a flow

Sharing a flow allows other people to use your flows.

![](/files/-MfjA4qHPxnxZ3plwbnV)

### Updating the shared flow

If you make changes to your flow, you'll need to click "Share" again to update the shared flow:

![](/files/-MTq7EkyN16uhMTNuPM_)


# Automating Google websites

## Problem

If you try to run an automation on a Google website (Google Forms, Google Sheets, Gmail, YouTube, etc.), you'll see the following error message in the logs:

![](/files/-McBSCZh8N7n4bSj9eNN)

## Solution

1. Open chrome://apps
2. Right click on all Chrome apps for Google websites (e.g. Google Drive, Gmail, YouTube)
3. Select "Remove from Chrome..."
4. Refresh the Google website you're trying to automate
5. Your flow will now run successfully

## Background

Google Chrome comes pre-installed with Chrome apps that mainly serve as shortcuts to Google websites for Chrome OS users. Unfortunately, these pre-installed apps have a known bug that prevent extensions like Browserflow from automating Google websites. By removing these apps, you'll be able to run flows on Google websites.

Google is aware of these issues and is working on fixing them:

* <https://bugs.chromium.org/p/chromium/issues/detail?id=885025#c39>
* <https://bugs.chromium.org/p/chromium/issues/detail?id=809304>

Note: Removing these pre-installed apps will not affect your access or usage of these services. If you still feel unsure, you always have the option of reinstalling these apps via the Chrome Web Store:

* [Google Drive](https://chrome.google.com/webstore/detail/google-drive/apdfllckaahabafndbhieahigkjlhalf?utm_source=chrome-ntp-launcher)
* [Gmail](https://chrome.google.com/webstore/detail/gmail/pjkljhegncpnkpknbcohdijeoejaedia?utm_source=chrome-ntp-launcher)
* [YouTube](https://chrome.google.com/webstore/detail/youtube/blpcfgokakmgnkcojhhkbfbldkacnbeo?utm_source=chrome-ntp-launcher)
* [Slides](https://chrome.google.com/webstore/detail/slides/aapocclcgogkmnckokdopfmhonfmgoek?utm_source=chrome-ntp-launcher)
* [Docs](https://chrome.google.com/webstore/detail/docs/aohghmighlieiainnegkcijnfilokake?utm_source=chrome-ntp-launcher)
* [Sheets](https://chrome.google.com/webstore/detail/sheets/felcaaldnbdncclmgdcncolpebgiejap?utm_source=chrome-ntp-launcher)


# Keyboard shortcuts

### Chrome shortcuts

* Open the editor: `Alt/Option + J`

Shortcuts may be modified at chrome://extensions/shortcuts


# Selectors

Selectors allow you to identify elements on the page when extracting data or interacting with the page.

For example, if you want Browserflow to click on a certain button on the page, it needs to know which button to click. The selector `button:contains("Submit")` would tell Browserflow to click on a `<button>` HTML element with the text "Submit".

## Generating selectors

Ways to generate selectors:

1. Recording actions
2. Using the "Select" button
3. Writing your own selector

### Recording actions

When [recording a flow](/guides/building-a-flow#recording-actions), Browserflow will automatically generate selectors for the elements you interact with.

### Using the "Select" button

In the Browserflow editor, you'll find a "Select" button next to the selector field in any command that requires a selector:

![](/files/-MUwDdD0iKv-uWd-Sx3N)

Clicking the "Select" button will trigger the element picker on the current page. When you click on an element, Browserflow will automatically generate a selector for that element.

### Writing your own selector

In addition to all [normal CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors), Browserflow supports a few non-standard psuedo-selectors:

* [`:contains`](https://api.jquery.com/contains-selector/) - Allows selecting an element by its text contents (case-sensitive)
  * e.g. A button with the text "Submit": `button:contains("Submit")`
* [`:has`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has) - Allows selecting an element by the elements it contains
  * e.g. Tweets that embed an external link: `[data-testid="tweet"]:has(a[href*="https://t.co/"])`


# Variables

Variables allow you to store information that can be used throughout a flow.

For example, variables can be used to store information from the the page (e.g. [Get Element Text](/reference/browserflow-commands/extract-data/get-element-text)) and pass it into other commands.

### Naming

All Browserflow variables start with the prefix `$`, as in `$selector`. This naming convention allows Browserflow to differentiate between variables and normal text.&#x20;

For example, running [Type Text](/reference/browserflow-commands/interact-with-page/type-text) with the message `Hi $name` will cause Browserflow to replace `$name` with the value for the variable and leave the "Hi" portion intact.

#### Caveats

Due to this naming convention, extra processing is required if you want to append text directly to a variable.

For example, suppose you have a variable named `$time` that holds a value like `9:30`. If you wanted to show an alert with the message `The time is 9:30AM`, you may try setting the message field to `The time is $timeAM`. However, this wouldn't work because Browserflow would look for a variable named `$timeAM` rather than append "AM" to a variable named `$time`.

In order to get the formatted text, create a new variable using [Run Script](/reference/browserflow-commands/utilities/run-script). In this case, you can run it with the code `const $formattedTime = $time + "AM";` and set the alert message to `The time is $formattedTime`.


# Input variables

### Creating Input Variables

Input variables allow you to set variables that may change between runs. You can access them by opening a flow's settings:

![](/files/4HGEZWbbLVlT5wrMklTb)

For example, if you create a flow that scrapes all the tweets from a particular profile, you can create an input variable for the username so that it can be changed between runs.

![](/files/TXJJXVrErgpJY8VVSR8A)

The "Clear value when flow is shared" option ensures that any sensitive information will be removed when you share a flow.

Once you've created an input variable, you can reference it in your flow to customize the behavior:

![](/files/HssAoYYusOoq6mS3tcf9)

### Using Input Variables

Once created, input variables allow you to easily change variables between runs by setting values in the Run tab:

![](/files/IJrW9tskJVOwalRtpkXV)


# Conditions

Conditions can be used:

* To control the flow using commands like [If](/reference/browserflow-commands/control-flow/if) and [While](/reference/browserflow-commands/control-flow/while)&#x20;
* To search and filter rows in spreadsheets using commands like [Find Spreadsheet Row](/reference/browserflow-commands/spreadsheet/find-spreadsheet-row) and [Loop Spreadsheet Rows](/reference/browserflow-commands/spreadsheet/loop-spreadsheet-rows)
* To verify results and create end-to-end tests using [Assert](/reference/browserflow-commands/utilities/assert)

### Element

#### Element is visible

* Value: [Selector](/guides/selectors) for the element to check for visibility

#### Element is hidden

* Value: [Selector](/guides/selectors) for the element to check for visibility

### Basic

#### Is empty

#### Is not empty

### Text

Text comparisons are case-insensitive.

#### Text contains

#### Text does not contain

#### Text starts with

#### Text ends with

#### Text is exactly

### Numbers

#### Greater than

#### Greater than or equal to

#### Less than

#### Less than or equal to

#### Is equal to

#### Is not equal to

### Spreadsheets

#### Row number exists

#### Row number does not exist

### Code

#### Code

* Value: Javascript expression that evaluates to either `true` or `false` (e.g. `1 === 2`)


# Running flows in the cloud

Once you've built and tested your flow locally, you can also run them in the cloud to automatically run flows on a schedule.

### Enabling cloud flows

1. Enable the flow to be run in the cloud and open cloud settings

   ![](/files/6MNWqZKUpWdIi2lIxgHH)

   ![](/files/9uzSzKOPjzfPRXHrWD2H)
2. Run the flow or schedule it

### Supported Commands

Browserflow Cloud supports all commands with one exception:

* Running other flows (i.e. Run Flow)


# Loop Sheet flows

If a flow contains a [Loop Spreadsheet Rows](/reference/browserflow-commands/spreadsheet/loop-spreadsheet-rows) command, Browserflow Cloud will create a separate run for each row in the loop.

For example, if a flow loops through a spreadsheet to visit 10 different URLs and scrape each of them, Browserflow Cloud will create 10 runs that each scrape a single URL rather than a single run that scrapes 10 URLs.

Since each run is limited to 2 minutes of execution, this design allows processing spreadsheets with many rows by giving 2 minutes of execution to each row rather than timing out by trying to execute all the rows within the time limit.


# Saving files

In order to save files when running flows in the cloud, you'll need to set the [`Save File`](/reference/browserflow-commands/extract-data/save-file) destination to Google Drive and specify a Google Drive folder to save to:

![](/files/-MfjBG2ihJUMuXsvip47)


# Automating sites behind a login

To automate sites behind a login, you can add cookies that will be set when the flow is run in the cloud.

For example, to run flows that automate Instagram, add cookies for "[www.instagram.com](http://www.instagram.com)" to ensure Browserflow can login on your behalf.

![](/files/-MfjQ2K1v2MN6oqp5zVz)


# API

API documentation: <https://browserflow.notion.site/Browserflow-API-Beta-39cad79612564c97a65af50e935afe24>


# Webhooks

Webhooks allow you to notify other services (e.g. Zapier, Make, your own service) when a run completes.

A `POST` request will be made to the webhook URL with data about the run.

#### Add a webhook endpoint

Webhook endpoints can be added in the "API & Webhooks" tab of a flow.

<figure><img src="/files/6mRrLTrwwRLW7cGWMtbL" alt=""><figcaption></figcaption></figure>


# Zapier

Documentation for using Browserflow with Zapier: <https://browserflow.notion.site/Using-Browserflow-with-Zapier-1b41003f910c451c92a783c42e0e1796>


# Troubleshooting

## Run limit exceeded

Runs in Browserflow Cloud are limited to 2 minutes. If your flow takes longer than the limit, see if you can break the flow up into smaller pieces.

For example, suppose that you want to scrape a long list of items that each has its own detail page. If your flow loops through the items by clicking into each item's detail page and going back, the run will likely take too long.

Instead, you can break this up into two steps:

1. Collecting a list of URLs
2. Automating each URL

You can store the list of URLs in a Google Sheet and use the [Loop Spreadsheet Rows](/reference/browserflow-commands/spreadsheet/loop-spreadsheet-rows) command to loop through the sheet. In the cloud, each row will execute in a separate run so the 2-minute limit will apply for each URL rather than for all the URLs combined.

If your flow cannot be broken up, please [contact support](/support/getting-help) for troubleshooting and additional options.

## Command interrupted by navigation

If a page navigation occurs while a command is executing, the flow will fail because the execution context is destroyed.

Common scenarios for when this occurs and how to fix it:

#### Visiting a page that redirects

If you visit a page that redirects, you need to wait for the redirects to complete before continuing.

Add a [Wait](/reference/browserflow-commands/utilities/wait) command right after [Visit](/reference/browserflow-commands/navigate/visit) to make sure that all redirects are completed before the flow continues. Try a wait time of 3 seconds and increase it if it's not enough.

#### Clicking a button or link that loads a new page

If you click on a button/link or press a key (e.g. Enter) that loads a new page, you need to make sure that the page loads before continuing.

Select the "Wait for new page to load" option in [Click](/reference/browserflow-commands/interact-with-page/click) or [Press Key](/reference/browserflow-commands/interact-with-page/press-key).


# Browserflow commands


# Interact with Page


# Click

Clicks on an element on the page

#### Selector

* [Selector](/guides/selectors) for the element to click

#### Wait for new page to load

* If the click will trigger a URL change, select this option to wait for the new page to load before proceeding

#### Wait for file to download

* If the click will trigger a file download, select this option to wait for the file to download before proceeding

#### File destination (applicable if "Wait for file to download" is selected)

* Where to save the file

#### Store downloaded file path/URL in variable (applicable if "Wait for file to download" is selected)

* Name of the variable to store the path/URL of the downloaded file
* Storing the local file path is only needed if the downloaded file will later be uploaded in the flow since [Upload File](/reference/browserflow-commands/interact-with-page/upload-file) requires an absolute path.


# Type Text

Types text into a text box

#### Text

* Text to type into a focused element

To press a special key, like `Control` or `ArrowDown`, use [Press Key](/reference/browserflow-commands/interact-with-page/press-key)

#### Typing large amounts of text

If you need to type a large amount of text and Type Text is too slow for your needs, you can use Javascript in [Run Script](/reference/browserflow-commands/utilities/run-script) to set the text directly. ([Demo flow](https://browserflow.app/shared/e123ffb1-aa67-482d-8d92-b01a81f2c888))

#### Typing "$"

If you need to type a literal "$" character (e.g. `$100`), you can use "\\$" to escape the character so that Browserflow doesn't interpret it as a variable (e.g. `\$100`).


# Press Key

Presses a key or a combination of keys

#### Key

* Name of key to press, such as `ArrowLeft`. See [USKeyboardLayout](https://github.com/puppeteer/puppeteer/blob/main/src/common/USKeyboardLayout.ts) for a list of all key names.
* Use the "Detect" button to have Browserflow detect and complete any key combination

#### Wait for new page to load

* If the key press will trigger a URL change (e.g. pressing `Enter` to submit a form), select this option to wait for the new page to load before proceeding

### Press Key vs. Click

If you have the choice between pressing a key or clicking to perform an action (e.g. pressing `Tab` to select an element or clicking on it), go with using [Click](/reference/browserflow-commands/interact-with-page/click) as it will properly wait for elements to load and therefore be more reliable compared to Press Key, which may press the key before the page can process it.

### OS-Level Keyboard Shortcuts

Note that OS-level shortcuts (e.g. `Command + V` to paste on Mac OS) won't work because these key presses are simulated at the browser level, not at the OS level (see [puppeteer#313](https://github.com/puppeteer/puppeteer/issues/1313) for a longer explanation)


# Scroll

Scrolls the page or a scrollable element

#### **Selector**

* [Selector](/guides/selectors) for the container element to scroll

#### Direction

* Bottom
  * Scroll to the bottom of the container
* Top
  * Scroll to the top of the container


# Hover

Hovers over an element

#### Selector

* [Selector](/guides/selectors) for the element to hover over


# Select Option

Selects an option from a `<select>` element

#### Selector

* [Selector](/guides/selectors) for the `<select>` element

#### Value

* Value(s) to select
  * Note that this is the value of the `value` attribute of the `<option>` element inside `<select>`, not the text of the `<option>` element
  * Multiple values can be selected by inserting `;` between the values


# Set Date Input

Sets the date for a `<input type="date">` element

#### Selector

* [Selector](/guides/selectors) for the `<input type="date">` element

#### Date

* Date to set
  * Must be in the format `yyyy-mm-dd`


# Upload File

Upload file to a `<input type="file">` element

#### Selector

* [Selector](/guides/selectors) for the `<input type="file">` element

#### File path

* Absolute path to the file
  * Example
    * macOS: `/Users/dkthehuman/Downloads/profile.png`
    * Windows: `C:\Documents\Newsletters\Summer2018.pdf`
  * If uploading a file that was downloaded earlier in the flow from a [Click](/reference/browserflow-commands/interact-with-page/click) or [Save File](/reference/browserflow-commands/extract-data/save-file) command, pass in the variable set from the "Store downloaded file path in variable" field

### Requirements

In order to use this command, you need to allow Browserflow to access files:

1. Open chrome://extensions/
2. Click "Details" for Browserflow
3. Enable "Allow access to file URLs"

### Limitations

Browserflow does not yet support uploading files into `<input>` elements inside iframes

### Finding the file upload element

On many sites, the file upload element is hidden, which means that it's not possible to select it using the "Select" button. In these cases, you can use Recording Mode to have Browserflow detect the correct file upload element.

1. [Start recording](/guides/building-a-flow#recording-actions)
2. Upload a file as you normally would
3. Stop recording
4. Clean up the recorded actions
   * If you clicked on a button to trigger the file selector, you can remove the `Click` command as it's not needed when using the `Upload File` command
   * Enter the [absolute path](/reference/browserflow-commands/interact-with-page/upload-file#file-path) for the file you'd like to upload (Browserflow cannot detect this automatically while recording)


# Handle Dialog

Accepts or dismisses native browser dialogs

#### Response type

* Accept
  * Selects "OK"
* Dismiss
  * Selects "Cancel"

#### Response text

* If the dialog is a prompt, this is the text that will be inserted into the text box. Otherwise, this has no effect.

### Types of Dialogs

#### Alerts

![](/files/-MTptWQmH4XUbBhvjp_r)

#### Confirmations

![](/files/-MTptPfMzrY4J-sMWmXE)

#### Prompt

![](/files/-MTptsY-XboWJwBVfw0T)


# Extract Data


# Get Element Text

Gets the text of the specified element

#### Selector

* [Selector](/guides/selectors) for the element with text

#### Store result in variable

* Name of the variable to store the text

#### Use blank text if element is missing

* If selected, Browserflow will use an empty string as the element's text if the element does not exist
  * By default, Browserflow will wait for the element to appear and exit with an error if the element cannot be found
* This is useful when an element appears inconsistently (e.g. when looping through a list of elements where some elements contain a particular piece of data but others don't)


# Get Link URL

Gets the address of the specified `<a>` element

#### Selector

* [Selector](/guides/selectors) for the link element

#### Store result in variable

* Name of the variable to store the link URL

#### Use blank text if element is missing

* If selected, Browserflow will use an empty string as the result if the element does not exist
  * By default, Browserflow will wait for the element to appear and exit with an error if the element cannot be found
* This is useful when an element appears inconsistently (e.g. when looping through a list of elements where some elements contain a link but others don't)


# Get Page URL

Gets the URL of the current page

#### Store result in variable

* Name of the variable to store the page URL


# Get Element Attribute

Gets the attribute of the specified element

#### Selector

* [Selector](/guides/selectors) for the element with text

#### Attribute

* [Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes) of the element

#### Variable to assign element attribute

* Name of the variable to store the attribute
  * If the attribute does not exist on the element, an empty string will be stored

#### Use blank text if element is missing

* If selected, Browserflow will use an empty string as the attribute if the element does not exist
  * By default, Browserflow will wait for the element to appear and exit with an error if the element cannot be found
* This is useful when an element appears inconsistently (e.g. when looping through a list of elements where some elements contain a particular piece of data but others don't)


# Get Element HTML

Gets the HTML of the specified element

#### Selector

* [Selector](/guides/selectors) for the element with text

#### Variable to assign element attribute

* Name of the variable to store the HTML

#### Use blank text if element is missing

* If selected, Browserflow will use an empty string as the value if the element does not exist
  * By default, Browserflow will wait for the element to appear and exit with an error if the element cannot be found
* This is useful when an element appears inconsistently (e.g. when looping through a list of elements where some elements contain a particular piece of data but others don't)


# Get Clipboard

Gets the contents of the clipboard

#### Variable to assign clipboard data

* Name of the variable to store clipboard contents


# Save File

Saves a file from an element or URL

#### Content type

* Element
  * Saves the source of an element (`<img>`, `<video>`, or `<audio>`)
* URL
  * Saves the media at the URL

#### Content

* If content type is Element
  * [Selector](/guides/selectors) for the element whose source to save
* If content type is URL
  * URL of the media to save

#### File name

* Name to save the file as

#### File destination

* Where to save the file

#### Store downloaded file path/URL in variable

* Name of the variable to store the path/URL of the downloaded file
* Storing the local file path is only needed if the downloaded file will later be uploaded in the flow since [Upload File](/reference/browserflow-commands/interact-with-page/upload-file) requires an absolute path


# Take Screenshot

Takes a screenshot of the page or an element

#### Selection

* Visible area
  * Captures the visible area of the page
* Full page
  * Captures the entire page
* Element
  * Captures an element

#### File name

* Name of the file to save (include file extension)

#### File destination

* Where to save the file

#### Store downloaded file path/URL in variable

* Name of the variable to store the path/URL of the downloaded file
* Storing the local file path is only needed if the downloaded file will later be uploaded in the flow since [Upload File](/reference/browserflow-commands/interact-with-page/upload-file) requires an absolute path.


# Generate PDF

Generates a PDF of the page (Cloud only)

#### Filename

* Name of the file to save the PDF to
  * The PDF will be saved to Google Drive


# Navigate


# Visit

Navigates to a URL in the current tab

#### URL

* URL to navigate to
  * If the URL is the current URL, the page will be reloaded

The navigation will be considered complete when the `load` event is fired from the page.


# Go Back

Navigates to the previous page in history


# Go Forward

Navigates to the next page in history


# Reload Page

Reloads the current page


# Spreadsheet


# Loop Spreadsheet Rows

Runs commands for each row of a spreadsheet

#### Sheet

* Sheet to read

#### **Variables to assign row values**

* Variables to store the values of the current row

#### Filter

* Conditions to limit the spreadsheet rows that are looped

#### Variable to assign row number

* Variable to store the current row number
  * Can be used for updating row values with [Update Spreadsheet Row](/reference/browserflow-commands/spreadsheet/update-spreadsheet-row)

#### Limit (optional)

* Number of spreadsheet rows to loop


# Add Spreadsheet Row

Writes a row to Google Sheets

{% hint style="info" %}
Note: Writes to Google Sheets are batched and will occur every 5 minutes and when the flow finishes, not when the command runs
{% endhint %}

#### Sheet

* Google Sheet to write to

#### Fields

* Values of the output row
  * Each field represents a separate column

### Viewing the output

The output of Add Spreadsheet Row can be seen in the Output tab of the [console](/guides/debugging-a-flow#console).

### Exporting the output

There are two ways to export the output:

* Writing to a Google Sheet
* Click the "Download CSV" button in the Output tab of the console

### Avoiding Overwriting Rows

When Browserflow sends rows to Google Sheets to be appended, Google Sheets uses the first column of the sheet to determine where to add the rows. Please note that if the first column is empty, Google Sheets will **overwrite** existing rows rather than **appending** new rows. You can fix this by reordering the columns so that when a row is populated, the first column for that row has a value.


# Update Spreadsheet Row

Updates a row in a Google Sheet

{% hint style="info" %}
Note: Updates to Google Sheets are batched and will occur when the flow finishes, not when the command runs
{% endhint %}

#### Sheet

* Google Sheet to update

#### Row number

* Number of the row to update
  * Can be populated using the row number variable from [Loop Spreadsheet Rows](/reference/browserflow-commands/spreadsheet/loop-spreadsheet-rows#variable-to-assign-row-number) or [Find Spreadsheet Row](/reference/browserflow-commands/spreadsheet/find-spreadsheet-row#variable-to-assign-row-number)

**Values**

* Values to use to update the flow


# Find Spreadsheet Row

Finds a row in Google Sheets

#### Sheet

* Google Sheet to search through

#### **Condition**

* Conditions to use to find the spreadsheet row
  * Text conditions (e.g. "Text is exactly", "Text contains") are case-insensitive

#### **Search from bottom of the sheet**

* Whether to start searching from the bottom of the sheet rather than from the top
  * Allows getting the most recent result if there are multiple matches

#### Variable to assign row number

* Variable to store the row number
  * The row number will be -1 if there is no match
  * The "[Row number exists/does not exist](/guides/conditions#spreadsheets)" conditions can be used to check if there's a match
  * Can be used for updating row values with [Update Spreadsheet Row](/reference/browserflow-commands/spreadsheet/update-spreadsheet-row)

### Use cases

* Checking to see if an item already exists in a spreadsheet to avoid adding duplicates


# Control Flow


# Loop Elements

Runs commands for each matching element

#### Selector

* [Selector](/guides/selectors) for the elements to loop

#### Variable for element selector

* Stores the selector for the current element

#### Limit (optional)

* Number of elements to loop

#### Settings for loading more elements

* Action
  * None
  * Scroll down to load more elements
  * Click link to navigate to next page
  * Click button to load more elements
* Selector for element to click
  * Selector for "next page" or "load more" button
* Max seconds to wait for more elements
  * Applicable for "Scroll down to load more elements" and "Click button to load more elements"


# Loop Pages

Runs commands for each page

#### Selector for link to next page

* [Selector](/guides/selectors) for the element to click on to get to the next page

#### Limit (optional)

* Number of pages to loop


# Loop

Runs commands a specified number of times

#### Number of times to loop

* Number of iterations to run the commands


# Loop List Items

Runs commands for each item in a list

#### List

* Variable for list (i.e. Javascript array) to loop through

#### Store current item in variable

* Variable that will be set with the current list item


# If

Runs commands based on conditions

#### Conditions

See [Conditions](/guides/conditions) page

### Use cases

If you're looping through a collection of elements and want to click on a button that only exists for some elements, you can use `If` with the "Element is visible" type to only run the `Click` command if the button exists.


# Else

Conditionally runs commands if an [`If`](/reference/browserflow-commands/control-flow/if) condition is not met


# While

Runs commands while conditions are met

#### Condition

See [Conditions](/guides/conditions) page


# End

Marks the end of control flow commands


# Break

Terminates the current loop

#### Use cases

* When updating a spreadsheet with the newest items from a list, avoid duplicates by stopping when an existing item is found
  * Demo flow: [Top Product Hunt Posts](https://browserflow.app/shared/62650a62-1857-442c-896c-6e4609e4f01c)


# Tabs


# Create Tab

Creates a new tab

#### URL

* URL of new tab


# Get Active Tab ID

Gets ID of the active tab

#### Store result in variable

* Variable to store the ID of the active tab


# Select Tab

Focuses an existing tab

#### Query Type

* URL
  * Select tab by the tab's current URL
* Tab ID
  * Select tab by its ID

#### Query

* If Query Type is URL
  * URL of the tab to select
    * Matches the first tab that contains the URL as a substring (e.g. "google.com" matches a tab with "mail.google.com")
* If Query Type is Tab ID
  * ID of the tab to select (see [Get Active Tab ID](/reference/browserflow-commands/tabs/get-active-tab-id))

#### Create tab if needed (applicable if Query Type is URL)

* Creates a tab with the URL if one does not already exist


# Close Tab

Closes an existing tab

#### Query Type

* Active Tab
  * Closes the active tab
* URL
  * Closes the tab matching the URL
* Tab ID
  * Closes the tab by its ID

#### Query

* If Query Type is URL
  * URL of the tab to select
    * Matches the first tab that contains the URL as a substring (e.g. "google.com" matches a tab with "mail.google.com")
* If Query Type is Tab ID
  * ID of the tab to select (see [Get Active Tab ID](/reference/browserflow-commands/tabs/get-active-tab-id))


# Utilities


# Run Script

Runs Javascript in the current page

#### Code

* Any variable that begins with `$` is automatically exported for use in other commands
  * e.g. `const $meow = 3`
* Variables are serialized as [JSON](https://www.json.org/json-en.html) and thus support the following data types:
  * Primitives (number, string, boolean)
  * Arrays
  * JSON objects

### Examples

#### Replacing Text

```javascript
// Assume variable $numberOfComments has the value "12 comments"
// You want to extract just the numerical count

$numberOfComments = $numberOfComments.replace(" comments", "");

// $numberOfComments is now "12"
```

#### Splitting Text

```javascript
// Assume variable $location has the value "San Francisco, CA"
// You want to split up the city and the state

const [$city, $state] = $location.split(", ");

// $city is "San Francisco", $state is "CA"
```

#### Extracting Page HTML

```javascript
const $html = document.documentElement.outerHTML;
```

### Execution context

The code is executed in the context of the current page which means that the page's DOM is accessible


# Get Date

Gets the current date with the specified format

#### Pattern

* Pattern to specify the format of the date
  * See <https://date-fns.org/docs/format>

#### Store result in variable

* Variable to store the formatted date


# Wait

Pauses the flow for a given time

#### Type

* Time
  * Wait for a specified time
* Wait until resumed
  * Wait until resumed by the user
    * Useful as a breakpoint (i.e. pausing the flow at a particular point)

#### Seconds (applicable if Type is Time)

* Number of seconds to wait for


# Wait for Element

Waits for an element to appear or disappear

#### Selector

* [Selector](/guides/selectors) for the element to wait for

#### Condition

* Wait until exists
  * Wait until element exists on the page (not necessarily visible)
* Wait until visible
  * Wait until element is visible on the page
* Wait until hidden
  * Wait until element is removed or is hidden on the page

#### Max seconds to wait (optional)

* Maximum number of seconds to wait for the element to meet the condition
  * If the condition is not met in time, the flow will continue
* A value of 0 will cause Browserflow to wait indefinitely until the condition is met


# Show Alert

Displays a message and waits for confirmation

**Message**

* Message to show in the alert

### Use cases

The `Show Alert` command is useful for inserting human actions in an automation.

For example, you may want to review the results before each submission in a data entry automation.

Or if there are actions that cannot be fully automated, `Show Alert` can be used to perform those actions manually before continuing the flow.


# Make HTTP Request

Makes an HTTP request

#### URL

* URL to send the HTTP request

#### Method

* HTTP method (GET, POST, PUT, PATCH, or DELETE)

#### Query string

* Query string to be added to the URL (e.g. <http://example.com/**?name=dk\\&age=29>\*\*)

#### Headers

* HTTP headers
  * Note: The `Content-Type` header is set automatically if the Body Type is JSON or Form

#### Body type

* Type of the request body
  * None
    * Request has no body
  * JSON
    * You can either put in a literal JSON object or use `JSON.stringify` in a Run Script command to generate the JSON
    * The `Content-Type` header is automatically set to `application/json`
  * Form
    * The `Content-Type` header is automatically set to `application/x-www-form-urlencoded`
  * Raw
    * The `Content-Type` header is NOT automatically set and must be added to the Headers field

#### Body (applicable if Body Type is not None)

* Request body

#### Variable to assign response

* Name of the variable to store the response
  * The response is a plain object with three properties:
    * `status`: The status of the response
    * `headers`: The headers of the response
    * `data`: The body of the response
  * Tip: When building a flow that uses Make HTTP Request, use the [Variables tab in the console](/guides/debugging-a-flow#console) to inspect the HTTP response


# Assert

Throws an error if the condition is not met

#### **Conditions**

See [Conditions](/guides/conditions) page

### Use cases

#### Use case: Verify intermediate results during a flow

Asserts can be used to verify that certain steps in a flow completed successfully. For example, if your flow submits a form, you can use `Assert` to check that some success text (e.g. "Your form was submitted successfully!") appears on the page.

#### Use case: End-to-end testing

Asserts can be used to test functionality in websites and web apps. For example, if you wanted to create a test to ensure that clicking the "Sign up" button on your home page takes the user to the sign up page, you can use `Assert` to check the result of [Get Page URL](/reference/browserflow-commands/extract-data/get-page-url) after clicking the button.

### Video demo

{% embed url="<https://www.loom.com/share/d57dc6f416204733b83fce48ab1ada62>" %}


# Run Flow

Runs a flow

#### Flow

* Flow to run


# Comment

Explains how a part of the flow works

#### Comment

* Additional information to help explain the flow


# Solve Captcha

Solves a CAPTCHA (Cloud only)

Browserflow will automatically detect a CAPTCHA on the page and solve it

### Credits

Solving a CAPTCHA uses an additional 30 seconds of runtime


# Getting help

### Where to ask for help

If you need help building a flow, post in the `#help` channel in the [Browserflow Discord](https://discord.com/invite/W3WUK58aSW).

If you believe you've found a bug in Browserflow, post in the `#bugs` channel in the Browserflow Discord.

### Information to include

When asking for help, please provide enough information for someone to be able to run your flow on their machine. Please include the following information:

* What are you trying to automate?
* What are you having trouble with?
* A screen recording of you running the flow (e.g. Loom)
* [A link to your flow](/guides/sharing-a-flow)
  * If you are not able to share your flow due to confidential information or the page requiring login access, please create a demo flow that demonstrates the issue.
* Links to connected spreadsheets (if applicable)
  * Please make sure the sheet is publicly accessible, or if the content is sensitive, please create a copy with dummy information


# Common errors

### Unable to run flow due to another extension <a href="#other-extensions" id="other-extensions"></a>

This error occurs when another Chrome extension injects content into the page that interferes with Browserflow.

How to resolve this issue:

1. Disable extensions from `chrome://extensions` until Browserflow is able to run successfully on the page
2. Email the name of the problematic extension to <support@browserflow.app> so that Browserflow can handle it in the future without disabling the extension.


# Updating to the latest version

{% hint style="info" %}
Browserflow will periodically update automatically, but sometimes you may need to manually update to the latest version (e.g. installing a flow created on a newer version, using flows from multiple devices)
{% endhint %}

1. Open chrome://extensions
2. Enable "Developer Mode"

   <figure><img src="/files/V6KJvBgd1yl7GDaZ700e" alt=""><figcaption></figcaption></figure>
3. Click "Update"

   <figure><img src="/files/Uf1gVLc3bfClQ0fe1JZ0" alt=""><figcaption></figcaption></figure>
4. You now have the latest version! You can see the current version on the top right of the extension description.

   <figure><img src="/files/Mbcppr3cqG686DqSQ5CR" alt=""><figcaption></figcaption></figure>


