π‘ Intercept API β Block, Redirect, Mock, Modify Requests β
Intercept network requests before they leave the browser or modify responses as they come back. Perfect for mocking APIs, blocking trackers, caching responses, and debugging.
β οΈ Version Requirement: Binary v0.1.14+ | Library v0.0.20+
Overview β
The Intercept API gives you full control over network traffic:
| Action | Method | Use Case |
|---|---|---|
| Block | intercept.block() | Block ads, trackers, images |
| Redirect | intercept.redirect() | Point CDN to local mirror |
| Modify Headers | intercept.headers() | Add auth tokens, spoof headers |
| Mock Response | intercept.respond() | Fake API responses (static or dynamic) |
| Modify Response | intercept.modifyResponse() | Inject data into real responses |
β οΈ Important: Pattern matching must match the URL word for word (except for
*wildcards). Partial matches do NOT work.
Pattern Matching Rules β
| Pattern | Matches | Does NOT Match |
|---|---|---|
https://api.example.com/users | Exactly that URL | /users, api.example.com/users |
https://api.example.com/users* | https://api.example.com/users/123, https://api.example.com/users?page=1 | https://api.example.com/user |
*api.example.com* | Any URL containing api.example.com | URLs without that string |
/api/users | https://example.com/api/users (relative path works) | /api/user |
// β
Exact match β works
await piggy.site.intercept.respond("/api/users", mockResponse);
// β Partial match β will NOT match
// Request URL: https://api.example.com/users/123
// Pattern "/api/users" does NOT match "/api/users/123"
// β
Use wildcard for partial matching
await piggy.site.intercept.respond("/api/users*", mockResponse);
// Now matches /api/users, /api/users/123, /api/users?page=1Block Requests β
intercept.block(pattern) β
Blocks requests matching the pattern. Useful for ads, trackers, and unnecessary resources.
// Block Google Analytics
await piggy.site.intercept.block("*google-analytics.com*");
// Block all images
await piggy.site.intercept.block("*.png");
await piggy.site.intercept.block("*.jpg");
await piggy.site.intercept.block("*.jpeg");
await piggy.site.intercept.block("*.gif");
await piggy.site.intercept.block("*.webp");
// Block specific API
await piggy.site.intercept.block("*/api/analytics*");
// Block tracking domains
await piggy.site.intercept.block("*doubleclick.net*");
await piggy.site.intercept.block("*facebook.com/tr*");Shortcut: Block Images β
// Quick way to block all images
await piggy.site.blockImages();
// Unblock
await piggy.site.unblockImages();Redirect Requests β
intercept.redirect(pattern, redirectUrl) β
Redirects matching requests to a different URL.
// Redirect CDN to local mirror
await piggy.site.intercept.redirect(
"https://cdn.example.com/*",
"http://localhost:8080/$1"
);
// Redirect old API to new API
await piggy.site.intercept.redirect(
"*/api/v1/*",
"https://api.example.com/v2/$1"
);Modify Headers β
intercept.headers(pattern, headers) β
Adds or modifies request headers before they are sent.
// Add custom header to all requests
await piggy.site.intercept.headers("*", {
"X-Scraped-By": "Nothing-Browser",
"X-Request-ID": () => crypto.randomUUID()
});
// Override User-Agent for specific domain
await piggy.site.intercept.headers("*.twitter.com*", {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
});
// Add authentication header to API calls
await piggy.site.intercept.headers("*/api/*", {
"Authorization": `Bearer ${process.env.API_TOKEN}`
});Mock Responses β
intercept.respond(pattern, response) β
Serves a custom response instead of making the actual network request.
// Static response
await piggy.site.intercept.respond("/api/users", {
status: 200,
contentType: "application/json",
body: JSON.stringify({ users: [{ id: 1, name: "John" }] })
});
// Return 404 for specific endpoint
await piggy.site.intercept.respond("/api/secret/*", {
status: 404,
contentType: "application/json",
body: JSON.stringify({ error: "Not found" })
});
// Dynamic response based on request
await piggy.site.intercept.respond("/api/product/*", async (request) => {
const productId = request.url.match(/\/product\/(\d+)/)?.[1];
// Check local cache
const cached = await db.products.find(productId);
if (cached) {
return {
status: 200,
contentType: "application/json",
body: JSON.stringify(cached),
headers: { "X-Cache": "HIT" }
};
}
// Return null to let request through to real server
return null;
});Response Object Structure β
interface InterceptResponse {
status?: number; // default: 200
contentType?: string; // default: auto-detect
headers?: Record<string, string>;
body: string | Buffer;
}Modify Responses β
intercept.modifyResponse(pattern, handler) β
Modifies an existing response after it's received from the server.
// Inject custom field into API response
await piggy.site.intercept.modifyResponse("*/api/users*", async (response) => {
const data = await response.json();
data._scraped_at = Date.now();
data._source = "nothing-browser";
return {
body: JSON.stringify(data),
headers: { "X-Modified": "true" }
};
});
// Redact sensitive data
await piggy.site.intercept.modifyResponse("*/api/user/*", async (response) => {
const data = await response.json();
delete data.ssn;
delete data.credit_card;
data.email = data.email.replace(/(.{2}).*(@.*)/, "$1***$2");
return { body: JSON.stringify(data) };
});
// Modify HTML response
await piggy.site.intercept.modifyResponse("*.html", async (response) => {
let html = response.body;
// Remove popup scripts
html = html.replace(/<script[^>]*popup[^>]*>.*?<\/script>/gi, "");
return { body: html };
});ModifyResponse Handler β
interface ModifyResponse {
url: string;
method: string;
status: number;
headers: Record<string, string>;
body: string;
json(): Promise<any>;
}
// Return null to passthrough unchanged
// Return { status?, headers?, body? } to modifyClear Rules β
intercept.clear(type?) β
Clears all intercept rules.
// Clear all rules
await piggy.site.intercept.clear();
// Clear only block rules
await piggy.site.intercept.clear("block");
// Clear only redirect rules
await piggy.site.intercept.clear("redirect");
// Clear only respond rules
await piggy.site.intercept.clear("respond");
// Clear only modifyResponse rules
await piggy.site.intercept.clear("modifyResponse");
// Clear only headers rules
await piggy.site.intercept.clear("headers");Real-World Examples β
Example 1: Mock API for Testing β
// Mock product list API
await piggy.site.intercept.respond("/api/products", {
status: 200,
contentType: "application/json",
body: JSON.stringify({
products: [
{ id: 1, name: "Mock Product 1", price: 29.99 },
{ id: 2, name: "Mock Product 2", price: 49.99 }
]
})
});
// Mock specific product
await piggy.site.intercept.respond("/api/products/42", {
status: 200,
contentType: "application/json",
body: JSON.stringify({ id: 42, name: "Special Product", price: 99.99 })
});
// Mock error response
await piggy.site.intercept.respond("/api/error-endpoint", {
status: 500,
contentType: "application/json",
body: JSON.stringify({ error: "Internal server error" })
});Example 2: Block All Trackers β
// Block common tracking domains
const trackers = [
"*google-analytics.com*",
"*googletagmanager.com*",
"*doubleclick.net*",
"*facebook.com/tr*",
"*amazon-adsystem.com*",
"*scorecardresearch.com*",
"*adsrvr.org*",
"*criteo.com*",
"*taboola.com*",
"*outbrain.com*"
];
for (const tracker of trackers) {
await piggy.site.intercept.block(tracker);
}
console.log(`${trackers.length} trackers blocked`);Example 3: Cache API Responses with TTL β
const apiCache = new Map();
await piggy.site.intercept.respond("/api/products*", async (request) => {
const cached = apiCache.get(request.url);
if (cached && Date.now() < cached.expires) {
return {
status: 200,
contentType: "application/json",
body: cached.data,
headers: { "X-Cache": "HIT", "X-Cache-Age": String(Date.now() - cached.timestamp) }
};
}
return null; // Passthrough to be cached by modifyResponse
});
await piggy.site.intercept.modifyResponse("/api/products*", async (response) => {
const data = await response.json();
apiCache.set(response.url, {
data: JSON.stringify(data),
timestamp: Date.now(),
expires: Date.now() + 5 * 60 * 1000 // 5 minutes
});
return null; // No modification, just cache
});Example 4: Add Authentication Headers β
// Add token to all API requests
await piggy.site.intercept.headers("*/api/*", {
"Authorization": `Bearer ${process.env.API_TOKEN}`,
"X-Client-Version": "2.0.0"
});
// Add specific headers for external API
await piggy.site.intercept.headers("*external-api.com*", {
"X-API-Key": process.env.EXTERNAL_API_KEY,
"Accept": "application/json"
});Example 5: Mock Slow Network (Dynamic Response) β
await piggy.site.intercept.respond("/api/slow-endpoint", async () => {
// Simulate network delay
await new Promise(r => setTimeout(r, 3000));
return {
status: 200,
contentType: "application/json",
body: JSON.stringify({ message: "Slow response", latency: "3000ms" })
};
});Example 6: Inject Data into Real Responses β
await piggy.site.intercept.modifyResponse("*/api/feed*", async (response) => {
const data = await response.json();
// Inject analytics tracking
data.items = data.items.map(item => ({
...item,
_injected_at: Date.now(),
_tracking_id: crypto.randomUUID()
}));
return { body: JSON.stringify(data) };
});Example 7: Redirect CDN to Local β
// Redirect all CDN requests to local development server
await piggy.site.intercept.redirect(
"https://cdn.example.com/assets/*",
"http://localhost:3000/assets/$1"
);
// Redirect specific file
await piggy.site.intercept.redirect(
"https://cdn.example.com/config.json",
"http://localhost:3000/config.dev.json"
);Example 8: Conditional Mock Based on Request Body β
await piggy.site.intercept.respond("/api/login", async (request) => {
const body = JSON.parse(request.body || "{}");
if (body.username === "admin" && body.password === "secret") {
return {
status: 200,
contentType: "application/json",
body: JSON.stringify({ token: "mock-jwt-token", role: "admin" })
};
}
return {
status: 401,
contentType: "application/json",
body: JSON.stringify({ error: "Invalid credentials" })
};
});Pattern Matching Cheat Sheet β
| Pattern | Matches |
|---|---|
/api/users | Exactly /api/users |
/api/users* | /api/users, /api/users/123, /api/users?page=1 |
*api/users* | Any URL containing api/users |
https://example.com/api/* | Any URL starting with that base |
*.json | Any URL ending with .json |
* | Everything |
// β
Correct
await piggy.site.intercept.respond("/api/users*", mockResponse);
// β Will NOT match /api/users/123
await piggy.site.intercept.respond("/api/users", mockResponse);
// β
Correct for domain matching
await piggy.site.intercept.block("*google-analytics.com*");
// β Will NOT match subdomains
await piggy.site.intercept.block("google-analytics.com");API Reference β
Intercept Methods β
| Method | Parameters | Returns | Description |
|---|---|---|---|
intercept.block(pattern) | pattern: string | Promise<void> | Block matching requests |
intercept.redirect(pattern, redirectUrl) | pattern: string, redirectUrl: string | Promise<void> | Redirect to new URL |
intercept.headers(pattern, headers) | pattern: string, headers: Record<string,string> | Promise<void> | Add/modify request headers |
intercept.respond(pattern, response) | pattern: string, response: object | Function | Promise<void> | Serve custom response |
intercept.modifyResponse(pattern, handler) | pattern: string, handler: Function | Promise<void> | Modify existing response |
intercept.clear(type?) | type?: "block" | "redirect" | "respond" | "modifyResponse" | "headers" | Promise<void> | Clear rules |
Shortcuts β
| Method | Returns | Description |
|---|---|---|
blockImages() | Promise<void> | Block all images |
unblockImages() | Promise<void> | Unblock images |
Type Definitions β
interface InterceptRequest {
url: string;
method: string;
headers: Record<string, string>;
body?: string;
}
interface InterceptResponse {
status?: number;
contentType?: string;
headers?: Record<string, string>;
body: string | Buffer;
}
interface ModifyResponse {
url: string;
method: string;
status: number;
headers: Record<string, string>;
body: string;
json(): Promise<any>;
}
interface ModifyResponseResult {
status?: number;
headers?: Record<string, string>;
body?: string;
}Next Steps β
- Capture API β Capture requests without modifying
- Proxy API β Route traffic through proxies
- Cookies API β Manage cookies
Nothing Ecosystem Β· Ernest Tech House Β· Kenya Β· 2026