> ## Documentation Index
> Fetch the complete documentation index at: https://upstash.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tabs & Navigation

Tabs are the unit of work in the box browser. `box.browser` opens and lists them. Every page operation, from navigation to screenshots to AI actions, runs on a specific `Tab` handle.

## Open a tab

`tab.create` opens a tab, navigates it to a URL, and waits for the requested lifecycle state. The first call also boots Chromium if it is not running yet.

<CodeGroup>
  ```typescript box.ts theme={"system"}
  const tab = await box.browser.tab.create("https://upstash.com", {
    waitUntil: "domcontentloaded",
    timeout: 30_000,
  })

  console.log(tab.id, tab.url, tab.title)
  ```

  ```python box.py theme={"system"}
  tab = box.browser.tab.create(
      "https://upstash.com",
      wait_until="domcontentloaded",
      timeout=30_000,
  )

  print(tab.id, tab.url, tab.title)
  ```
</CodeGroup>

* `waitUntil`: when navigation counts as done. One of `"load"` (default), `"domcontentloaded"`, or `"networkidle"`.
* `timeout`: navigation timeout in milliseconds. Defaults to `30000`. Pass `0` to disable it.

## Navigate

`goto` navigates the tab and returns the resulting page's content (title, URL, text, and links):

<CodeGroup>
  ```typescript box.ts theme={"system"}
  const page = await tab.goto("https://upstash.com/docs")
  console.log(page.title, page.url)
  ```

  ```python box.py theme={"system"}
  page = tab.goto("https://upstash.com/docs")
  print(page.title, page.url)
  ```
</CodeGroup>

Unlike `tab.create`, `goto` has no `waitUntil` or `timeout` options. It waits for the page to load with a fixed 60 second deadline.

## List and re-attach

Tab handles are addressed by their Chrome DevTools Protocol target id, which stays stable across navigations. You can store a tab id and re-attach to the same tab later, even from a different process:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  // List the box's open tabs
  const tabs = await box.browser.listTabs()
  for (const t of tabs) {
    console.log(t.id, t.url, t.title)
  }

  // Re-attach to a tab by id (no network call)
  const same = box.browser.getTab(tab.id)
  await same.goto("https://news.ycombinator.com")
  ```

  ```python box.py theme={"system"}
  # List the box's open tabs
  tabs = box.browser.list_tabs()
  for t in tabs:
      print(t.id, t.url, t.title)

  # Re-attach to a tab by id (no network call)
  same = box.browser.get_tab(tab.id)
  same.goto("https://news.ycombinator.com")
  ```
</CodeGroup>

<Note>
  A handle's `url` and `title` fields are the last known values from
  `tab.create` or `listTabs`. They are not updated live. Use
  [`tab.content()`](/docs/box/overall/browser/reading-pages) to read the current
  state of the page.
</Note>

## Close a tab

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await tab.close()
  ```

  ```python box.py theme={"system"}
  tab.close()
  ```
</CodeGroup>

Multiple tabs can be open at once. Each is independent, and operations on one do not affect the others. This is useful for comparing pages side by side or running [AI tasks](/docs/box/overall/browser/ai-actions) against several pages in sequence.
