Skip to main content

Best BQL Practices

We recommend you use the following best practices to make the most out of BQL. This guide covers essential patterns that will make your browser automation more reliable and maintainable.

Prefer Variables Over Hardcoded Values

Use GraphQL variables to keep your BQL operations reusable and easy to maintain. Variables let you parameterize values like URLs, selectors, and input data, so you can avoid hardcoding and repeating them across queries.

# Avoiding concatenating strings by using GraphQL variables
mutation LoginUser($email: String!, $password: String!, $loginUrl: String!) {
goto(url: $loginUrl, waitUntil: firstContentfulPaint) {
status
}

typeEmail: type(
selector: "input[type='email']"
text: $email
) {
time
}

typePassword: type(
selector: "input[type='password']"
text: $password
) {
time
}

submitLogin: click(selector: "button[type='submit']") {
x
y
}
}

Then, send a variables object in your JSON payload read more about them here

{
"email": "user@example.com",
"password": "securepassword123",
"loginUrl": "https://example.com/login"
}

Prefer Semantic Selectors Over Flaky CSS Classes

Prefer semantic selectors for more reliable automations. Use stable HTML attributes, roles, or other meaningful selectors that are less likely to change, and avoid relying on CSS classes that can break with UI updates.

mutation AddProductToCart($url: String!) {
goto(url: $url, waitUntil: networkIdle) {
status
}
# Use HTML attributes for more reliable scraping
click(selector: "[data-testid='add-to-cart-button']") {
selector
}
# Use HTML roles instead of classes for waiting for a particular selector
waitForSelector(
selector: "[role='status'][aria-label='cart-item-count']"
visible: true
) {
selector
}
html(visible: true) {
html
}
}

Reject Unnecessary Resources

Block unnecessary resources to improve performance. Use the reject mutation to prevent loading ads, images, videos, and other non-essential requests, reducing bandwidth usage and speeding up execution. It's important to keep in mind that reducing bandwidth usage may reduce your proxy cost if they are enabled, however they could also trigger bot detection on some sites.

# Make sure to enable the Adblock parameter in the editor!
mutation Search($url: String!, $query: String!) {
# Reject images, styles and media right away
reject(
type: [image, stylesheet, media]
) {
time
}
goto(url: $url, waitUntil: networkIdle) {
status
}
type(text: $query, selector: "input[name='q']") {
selector
}
click(selector: "button[type='submit']") {
selector
}
waitForNavigation {
status
}
html(visible: true) {
html
}
}

Summary

The tl; dr is:

  • Use variables instead of hardcoded values
  • Use semantic selectors instead of CSS classes
  • Block unnecessary resources to improve performance