Configure Firecrawl web scraping API across development, staging, and production environments. Use when setting up multi-environment scraping pipelines, managing credit budgets per env, or configuring different crawl limits and rate limits per deployment tier. Trigger with phrases like "firecrawl environments", "firecrawl staging", "firecrawl dev prod", "firecrawl environment setup", "firecrawl config by env".
From firecrawl-packnpx claudepluginhub nickloveinvesting/nick-love-plugins --plugin firecrawl-packThis skill is limited to using the following tools:
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Details PluginEval's skill quality evaluation: 3 layers (static, LLM judge), 10 dimensions, rubrics, formulas, anti-patterns, badges. Use to interpret scores, improve triggering, calibrate thresholds.
Firecrawl's credit-based pricing model makes environment separation critical. Development should use conservative crawl limits to avoid burning production credits during testing.
| Environment | API Key | Crawl Limit | Concurrency | Credit Budget |
|---|---|---|---|---|
| Development | Dev key or self-hosted | 10 pages max | 1 | Minimal |
| Staging | Staging key | 100 pages max | 2 | Limited |
| Production | Prod key | Configured per task | Full | Monitored |
// config/firecrawl.ts
import FirecrawlApp from "@mendable/firecrawl-js";
type Env = "development" | "staging" | "production";
interface FirecrawlConfig {
apiKey: string;
apiUrl?: string; // override for self-hosted
maxPagesPerCrawl: number; // hard limit per crawl job
maxDepth: number;
concurrency: number;
waitFor: number; // ms to wait for JS rendering
}
const configs: Record<Env, FirecrawlConfig> = {
development: {
apiKey: process.env.FIRECRAWL_API_KEY_DEV || "fc-localdev",
apiUrl: process.env.FIRECRAWL_API_URL_DEV, // point to self-hosted if available
maxPagesPerCrawl: 10, // strict limit in dev to protect credits
maxDepth: 2,
concurrency: 1,
waitFor: 2000, # 2000: 2 seconds in ms
},
staging: {
apiKey: process.env.FIRECRAWL_API_KEY_STAGING!,
maxPagesPerCrawl: 100,
maxDepth: 3,
concurrency: 2,
waitFor: 3000, # 3000: 3 seconds in ms
},
production: {
apiKey: process.env.FIRECRAWL_API_KEY_PROD!,
maxPagesPerCrawl: 500, // per-task limit, set lower for specific jobs # HTTP 500 Internal Server Error
maxDepth: 5,
concurrency: 5,
waitFor: 3000, # 3 seconds in ms
},
};
export function getFirecrawlConfig(): FirecrawlConfig {
const env = (process.env.NODE_ENV || "development") as Env;
return configs[env] || configs.development;
}
export function getFirecrawlClient(): FirecrawlApp {
const cfg = getFirecrawlConfig();
return new FirecrawlApp({
apiKey: cfg.apiKey,
...(cfg.apiUrl ? { apiUrl: cfg.apiUrl } : {}),
});
}
# docker-compose.dev.yml - Run Firecrawl locally in dev
version: "3.8"
services:
firecrawl:
image: mendableai/firecrawl:latest
ports:
- "3002:3002" # 3002 = configured value
environment:
- USE_DB_AUTHENTICATION=false
- PORT=3002
Set FIRECRAWL_API_URL_DEV=http://localhost:3002 and any API key in .env.local to use local instance with no credit consumption.
// lib/firecrawl-service.ts
import { getFirecrawlClient, getFirecrawlConfig } from "../config/firecrawl";
export async function safeScrape(url: string, options?: any) {
const firecrawl = getFirecrawlClient();
const cfg = getFirecrawlConfig();
return firecrawl.scrapeUrl(url, {
formats: ["markdown"],
onlyMainContent: true,
waitFor: cfg.waitFor,
...options,
});
}
export async function safeCrawl(url: string, customLimit?: number) {
const firecrawl = getFirecrawlClient();
const cfg = getFirecrawlConfig();
const limit = Math.min(customLimit ?? cfg.maxPagesPerCrawl, cfg.maxPagesPerCrawl);
return firecrawl.asyncCrawlUrl(url, {
limit,
maxDepth: cfg.maxDepth,
scrapeOptions: { formats: ["markdown"], onlyMainContent: true },
});
}
# .env.local (development)
FIRECRAWL_API_KEY_DEV=fc-dev-abc123
FIRECRAWL_API_URL_DEV=http://localhost:3002 # 3002: optional self-hosted
# GitHub Actions - Staging environment
FIRECRAWL_API_KEY_STAGING=fc-staging-def456
# GitHub Actions - Production environment
FIRECRAWL_API_KEY_PROD=fc-prod-xyz789
# .github/workflows/deploy.yml
jobs:
test-scraping:
environment: staging
env:
FIRECRAWL_API_KEY_STAGING: ${{ secrets.FIRECRAWL_API_KEY_STAGING }}
NODE_ENV: staging
steps:
- run: node scripts/test-firecrawl.js
# Uses staging config: 100-page limit, staging API key
deploy:
environment: production
env:
FIRECRAWL_API_KEY_PROD: ${{ secrets.FIRECRAWL_API_KEY_PROD }}
NODE_ENV: production
| Issue | Cause | Solution |
|---|---|---|
| Credits depleted in dev | No page limit in dev config | Always set maxPagesPerCrawl: 10 for development |
| Self-hosted not responding | Docker container not running | Check docker-compose up firecrawl |
402 Payment Required | Production credits exhausted | Monitor credit balance before large jobs |
| Different results per env | waitFor mismatch | Standardize JS wait time or test with prod settings |
import { getFirecrawlConfig } from "./config/firecrawl";
const cfg = getFirecrawlConfig();
console.log(`Max pages: ${cfg.maxPagesPerCrawl}, depth: ${cfg.maxDepth}`);
console.log(`API URL: ${cfg.apiUrl || "https://api.firecrawl.dev"}`);
set -euo pipefail
# Check current credit balance
curl -s "https://api.firecrawl.dev/v1/team/credits" \
-H "Authorization: Bearer $FIRECRAWL_API_KEY_PROD" | jq .credits_remaining
For deployment configuration, see firecrawl-deploy-integration.