Skip to main content
GitResolve separates page-fetching concerns from link extraction through the BrowserProvider interface. This lets you choose between a lightweight plain-fetch approach and a full headless browser without changing any other code. The createProvider factory handles automatic detection so most applications never need to instantiate a provider class directly.

createProvider

Creates and returns the best available BrowserProvider. Providers are tested for availability before being returned, so the result is always usable.

Parameters

ProviderName
Optional explicit provider name. When specified, createProvider attempts to use only that provider. If the requested provider is unavailable, the function throws rather than silently falling back.

Returns

Promise<BrowserProvider> — a ready-to-use provider instance.

Resolution order

  1. preferred argument — if supplied, that provider is attempted. Throws Error("Requested provider '${preferred}' is not available") if unavailable.
  2. BROWSER_PROVIDER environment variable — if set to a valid ProviderName, behaves as if preferred was passed (including the throw-on-unavailable behaviour).
  3. Automatic fallback chainpuppeteerbrowserlessfetch. The first provider that reports isAvailable() === true is returned.
FetchProvider.isAvailable() always returns true (built into Node.js 18+), so the automatic fallback chain never exhausts all options. If neither Puppeteer nor a Browserless instance is reachable, FetchProvider is returned as the ultimate fallback.

Examples

ProviderName type


BrowserProvider interface

The contract that all three provider classes — and any custom provider — must implement.
string (readonly)
Human-readable identifier for the provider. Used in scrapePortfolio warning messages. Values for the built-in providers: 'fetch', 'puppeteer', 'browserless'.
(url: string, options?: BrowserProviderOptions) => Promise<string>
Fetches a URL and returns the fully rendered HTML as a string. For FetchProvider this is the raw server response. For PuppeteerProvider and BrowserlessProvider this is the post-JavaScript-execution DOM serialisation.
() => Promise<boolean>
Returns true if the provider can be used in the current environment. FetchProvider always returns true. PuppeteerProvider attempts a dynamic import of puppeteer. BrowserlessProvider attempts a GET /json/version health check with a 3-second timeout.
() => Promise<void>
Releases any held resources. For PuppeteerProvider this closes the managed browser instance. For FetchProvider and BrowserlessProvider this is a no-op. Always call cleanup() in a finally block.

BrowserProviderOptions

Options accepted by getPageContent to control navigation behaviour.
number
Navigation timeout in milliseconds. Defaults differ by provider:
'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'
When to consider the navigation complete. Applies only to PuppeteerProvider and BrowserlessProviderFetchProvider ignores this option since fetch has no page lifecycle events.

Provider classes

FetchProvider

Uses Node.js built-in fetch to download HTML. No extra dependencies, no browser process. Works on any static site or server-rendered page. Does not execute JavaScript.
  • Best for: Static portfolio sites, GitHub Pages sites, server-rendered Rails/Django/Next.js apps with SSR.
  • Not suitable for: SPAs that render links via React, Vue, Angular, or similar client-side routing.
  • Sends a realistic User-Agent header (Mozilla/5.0 (compatible; ClyrisBot/1.0)) to avoid bot-blocking on common static hosts.

PuppeteerProvider

Launches a headless Chromium browser via Puppeteer. One browser instance is reused across multiple getPageContent calls within the same provider instance.
puppeteer is a peer dependency and is not installed automatically. Run npm install puppeteer to enable this provider. PuppeteerProvider.isAvailable() returns false when puppeteer cannot be imported.
  • Launches Chrome with --no-sandbox --disable-setuid-sandbox flags (required for most CI/container environments).
  • Each page is opened in a new tab and closed after getPageContent returns.
  • Call provider.cleanup() to close the browser and free resources.

BrowserlessProvider

Uses the Browserless /content REST endpoint for full JS rendering without managing a local browser process. Ideal for serverless environments and autoscaled pipelines.
The base URL is resolved in this order:
  1. Constructor argument baseUrl
  2. BROWSERLESS_URL environment variable
  3. Default: http://localhost:3000
isAvailable() performs a GET {baseUrl}/json/version health check with a 3-second timeout. cleanup() is a no-op since the provider is stateless REST.

Custom provider

You can implement your own provider by satisfying the BrowserProvider interface. This is useful for injecting a mock in tests or integrating an alternative rendering service.