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

# How to Integrate Undici with ZenRows

> Use Undici HTTP client with ZenRows Universal Scraper API to build high-performance Node.js web scrapers with anti-bot bypass and proxy support.

Extract web data with enterprise-grade performance using Undici's HTTP/1.1 client and ZenRows' Universal Scraper API. This guide demonstrates how to leverage Undici's superior performance with ZenRows' robust scraping infrastructure to build high-speed web scraping applications.

## What Is Undici?

<a href="https://github.com/nodejs/undici" target="_blank" rel="noopener noreferrer nofollow">Undici</a> is a fast, reliable HTTP/1.1 client written from scratch for Node.js. It provides significant performance improvements over traditional HTTP clients, such as Axios and node-fetch, making it ideal for high-throughput scraping applications. Undici supports advanced features like HTTP/1.1 pipelining, connection pooling, and multiple request methods.

### Key Benefits of Integrating Undici with ZenRows

The undici-zenrows integration brings the following advantages:

* **Superior Performance**: Undici delivers up to 3x better performance compared to traditional HTTP clients, making your scraping operations faster and more efficient.
* **Advanced Connection Management**: Built-in connection pooling and HTTP/1.1 pipelining capabilities optimize resource usage for high-volume scraping.
* **Enterprise-Grade Scraping Reliability**: Combine Undici's robust HTTP handling with ZenRows' scraping infrastructure.
* **Multiple Request Methods**: Choose from `request`, `fetch`, `stream`, or `pipeline` <a href="https://github.com/nodejs/undici?tab=readme-ov-file#common-api-methods" target="_blank" rel="noopener noreferrer nofollow">API methods</a> based on your specific <a href="https://github.com/nodejs/undici?tab=readme-ov-file#performance-comparison" target="_blank" rel="noopener noreferrer nofollow">use case requirements</a>.
* **Memory Efficient**: Stream-based processing reduces memory overhead for large-scale scraping operations.
* **TypeScript Support**: Full TypeScript support for a better development experience and type safety.

## Getting Started: Basic Usage

Let's start with a simple example that uses Undici to scrape the <a href="https://www.scrapingcourse.com/antibot-challenge" target="_blank" rel="noopener noreferrer nofollow">Antibot Challenge</a> page through ZenRows' Universal Scraper API.

### Step 1: Install Undici

Install the `undici` package using npm:

```bash theme={null}
npm install undici
```

### Step 2: Set Up Your Project

You'll need your ZenRows API key, which you can get from the <a href="https://app.zenrows.com/builder" target="_blank" rel="noopener noreferrer nofollow">Request builder dashboard</a>.

<img src="https://static.zenrows.com/content/zenrows_request_builder_only_091c0ee08c.png" alt="ZenRows Request Builder Only" />

<Note>
  You can explore different parameter configurations using the [Request Playground dashboard](https://app.zenrows.com/builder), then apply those settings in your Undici implementation. For a complete list of available parameters and their descriptions, refer to the [API Reference documentation](/universal-scraper-api/api-reference).
</Note>

Create a new file and import the necessary modules.

```javascript Node.js theme={null}
// npm install undici
import { request } from "undici";

// set your ZenRows API key
const ZENROWS_API_KEY = "YOUR_ZENROWS_API_KEY";
const targetUrl = "https://www.scrapingcourse.com/antibot-challenge";
```

### Step 3: Make Your First Request

Use Undici's `request` method to call ZenRows' Universal Scraper API:

```javascript Node.js theme={null}
// npm install undici
import { request } from "undici";

// set your ZenRows API key
const ZENROWS_API_KEY = "YOUR_ZENROWS_API_KEY";
const targetUrl = "https://www.scrapingcourse.com/antibot-challenge";

async function scrapeWithUndici() {
  try {
    const { body } = await request("https://api.zenrows.com/v1/", {
      method: "GET",
      query: {
        url: targetUrl,
        apikey: ZENROWS_API_KEY,
        js_render: "true",
        premium_proxy: "true",
      },
    });

    // get the HTML content
    const htmlContent = await body.text();
    console.log(htmlContent);
  } catch (error) {
    console.error("Scraping failed:", error.message);
  }
}

// execute the scraper
scrapeWithUndici();
```

<Tip>
  Understanding the Parameters

  In the code above, we're using two key parameters to handle the antibot:

  `js_render: "true"`: Activates JavaScript execution to handle dynamic content and render the page completely

  `premium_proxy: "true"`: Routes requests through high-quality residential IP addresses to avoid detection

  These parameters work together to bypass sophisticated antibots. For a comprehensive list of all available parameters and their usage, check the parameter overview table.
</Tip>

Replace `YOUR_ZENROWS_API_KEY` with your actual API key and run the script:

```bash theme={null}
node scraper.js
```

The script will successfully bypass the antibot and return the HTML content:

```html Output theme={null}
<html lang="en">
<head>
    <!-- ... -->
    <title>Antibot Challenge - ScrapingCourse.com</title>
    <!-- ... -->
</head>
<body>
    <!-- ... -->
    <h2>
        You bypassed the Antibot challenge! :D
    </h2>
    <!-- other content omitted for brevity -->
</body>
</html>
```

Perfect! You've successfully integrated Undici with ZenRows to bypass antibot protection.

## Complete Example: E-commerce Product Scraper

Now let's build a complete scraper for an e-commerce site to demonstrate practical use cases with Undici and ZenRows.

### Step 1: Scrape the E-commerce Site

Let's start by scraping an <a href="https://www.scrapingcourse.com/ecommerce/" target="_blank" rel="noopener noreferrer nofollow">e-commerce demo</a> site to see how Undici handles real-world scenarios. We'll extract the complete HTML content of the page:

```javascript Node.js theme={null}
// npm install undici
import { request } from "undici";

// set your ZenRows API key
const ZENROWS_API_KEY = "YOUR_ZENROWS_API_KEY";
const targetUrl = "https://www.scrapingcourse.com/ecommerce/";

async function scrapeEcommerceSite() {
  try {
    const { body } = await request("https://api.zenrows.com/v1/", {
      method: "GET",
      query: {
        url: targetUrl,
        apikey: ZENROWS_API_KEY,
      },
    });

    // get the HTML content
    const htmlContent = await body.text();
    console.log(htmlContent);
  } catch (error) {
    console.error("Scraping failed:", error.message);
  }
}

// execute the scraper
scrapeEcommerceSite();
```

This will return the complete HTML content of the e-commerce page.

```html Output theme={null}
<!DOCTYPE html>
<html lang="en-US">
<head>
    <!--- ... --->
  
    <title>Ecommerce Test Site to Learn Web Scraping - ScrapingCourse.com</title>
    
  <!--- ... --->
</head>
<body class="home archive ...">
    <p class="woocommerce-result-count">Showing 1-16 of 188 results</p>
    <ul class="products columns-4">

        <!--- ... --->

    </ul>
</body>
</html>
```

### Step 2: Parse the Scraped Data

Now that you can successfully scrape the site, let's extract specific product information using CSS selectors. We'll use ZenRows' [`css_extractor`](/universal-scraper-api/features/css-extractor) parameter to get structured data:

```javascript Node.js theme={null}
// npm install undici
import { request } from "undici";

// set your ZenRows API key
const ZENROWS_API_KEY = "YOUR_ZENROWS_API_KEY";
const targetUrl = "https://www.scrapingcourse.com/ecommerce/";

async function scrapeEcommerceSite() {
  try {
    const { body } = await request("https://api.zenrows.com/v1/", {
      method: "GET",
      query: {
        url: targetUrl,
        apikey: ZENROWS_API_KEY,
        css_extractor: JSON.stringify({
          "product-names": ".product-name",
        }),
      },
    });

    // get the product data
    const productData = await body.json();
    console.log(productData);
  } catch (error) {
    console.error("Scraping failed:", error.message);
  }
}

// execute the scraper
scrapeEcommerceSite();
```

The response will be a JSON object containing the extracted product names:

```html Output theme={null}
{
  "product-names": [
    "Abominable Hoodie",
    "Adrienne Trek Jacket",
    // ...
    "Ariel Roll Sleeve Sweatshirt",
    "Artemis Running Short"
  ]
}
```

### Step 3: Export Data to CSV

Finally, save the scraped product data to a CSV file for further analysis:

```javascript Node.js theme={null}
// npm install undici
import { request } from "undici";
import { writeFileSync } from "fs";

// set your ZenRows API key
const ZENROWS_API_KEY = "YOUR_ZENROWS_API_KEY";
const targetUrl = "https://www.scrapingcourse.com/ecommerce/";

async function scrapeEcommerceSite() {
  try {
    const { body } = await request("https://api.zenrows.com/v1/", {
      method: "GET",
      query: {
        url: targetUrl,
        apikey: ZENROWS_API_KEY,
        css_extractor: JSON.stringify({
          "product-names": ".product-name",
        }),
      },
    });

    // get the product data
    const productData = await body.json();
    const productNames = productData["product-names"];

    // create CSV content
    let csvContent = "Product Name\n";
    productNames.forEach((name) => {
      csvContent += `"${name}"\n`;
    });

    // write to CSV file
    writeFileSync("products.csv", csvContent, "utf8");
    console.log(
      `Successfully exported ${productNames.length} products to products.csv`
    );
  } catch (error) {
    console.error("Scraping failed:", error.message);
  }
}

// execute the scraper
scrapeEcommerceSite();
```

Run the script and you'll get a CSV file containing all the product names:

<img src="https://static.zenrows.com/content/e_commerce_demo_csv_output_7d69cb1354.png" alt="e_commerce demo csv" />

Congratulations! You now have a complete working scraper that can extract product data from an e-commerce site and export it to a CSV file.

## Next Steps

You now have a complete foundation for high-performance web scraping with Undici and ZenRows. Here are some recommended next steps to optimize your scraping operations:

* <a href="https://github.com/nodejs/undici" target="_blank" rel="noopener noreferrer nofollow">Undici Documentation</a>: Explore Undici's advanced features like HTTP/1.1 pipelining, custom dispatchers, and performance optimizations.
* [Complete API Reference](/universal-scraper-api/api-reference): Explore all available ZenRows parameters and advanced configuration options to customize your Undici requests for specific use cases.
* [JavaScript Instructions Guide](/universal-scraper-api/features/js-instructions): Learn how to perform complex page interactions like form submissions, infinite scrolling, and multi-step workflows using ZenRows' browser automation.
* [Output Formats and Data Extraction](/universal-scraper-api/features/output): Master advanced data extraction with CSS selectors, convert responses to Markdown or PDF, and capture screenshots using Undici's streaming capabilities.

## Getting Help

Request failures can happen for various reasons when using Undici with ZenRows. For detailed [troubleshooting guidance](/universal-scraper-api/troubleshooting/troubleshooting-guide), visit our comprehensive troubleshooting guide and check <a href="https://github.com/nodejs/undici" target="_blank" rel="noopener noreferrer nofollow">Undici's documentation</a> for HTTP client-specific issues.

If you're still facing issues despite following the troubleshooting tips, our support team is available to help you. Use the chatbox in the [Request Playground](https://app.zenrows.com/builder) dashboard or <a href="mailto:success@zenrows.com" rel="nofollow">contact us via email</a> to get personalized help from ZenRows experts.

When contacting support, always include the `X-Request-Id` from your [response headers](/universal-scraper-api/api-reference#response-headers) to help us diagnose issues quickly.

## Frequently Asked Questions (FAQ)

<Accordion title="How do I handle websites that block my Undici requests?">
  Enable both `js_render` and `premium_proxy` parameters in your ZenRows API calls. This combination offers the highest success rate against sophisticated antibot protection by simulating real browser behavior and utilizing high-quality residential IP addresses.
</Accordion>

<Accordion title="How do I handle JavaScript-heavy websites with Undici and ZenRows?">
  Enable the `js_render` parameter in your ZenRows API calls. This uses a real browser to execute JavaScript and capture the fully rendered page. Combine with Undici's efficient request handling for optimal performance on modern web applications.
</Accordion>

<Accordion title="Can I use Undici's streaming capabilities with ZenRows?">
  Absolutely! Undici's `stream()` and `pipeline()` methods work perfectly with ZenRows. This is especially useful for processing large responses efficiently without loading everything into memory.
</Accordion>

<Accordion title="What's the difference between undici.request() and undici.fetch() with ZenRows?">
  `undici.request()` provides better performance and more control over the request/response lifecycle, while `undici.fetch()` offers a more familiar API similar to browser fetch. For maximum performance with ZenRows, use `undici.request()`.
</Accordion>

<Accordion title="How do I extract specific data from pages using Undici and ZenRows?">
  Use the `css_extractor` parameter in your ZenRows API calls to extract content using CSS selectors directly. The response will be JSON instead of HTML, making it easier to process with Undici.
</Accordion>

<Accordion title="Can I use Undici with ZenRows for real-time monitoring?">
  Yes! Undici's performance characteristics make it excellent for real-time monitoring. Use session management with ZenRows' `session_id` parameter and implement efficient polling with Undici's connection pooling.
</Accordion>

<Accordion title="Does Undici work with ZenRows' advanced features like screenshots and PDF outputs?">
  Yes! All ZenRows features work with Undici.
</Accordion>
