Using an HTTP Proxy with the Uniform SDK and CLI

Last updated: June 22, 2026

Problem Statement

Behind a corporate firewall, outbound HTTPS requests to Uniform's endpoints (https://uniform.app — Management API, https://uniform.global — Edge Delivery API) are blocked, and your Next.js app fails with fetch failed errors such as ECONNRESET or UND_ERR_CONNECT_TIMEOUT. Route these requests through your corporate HTTP proxy as follows.

Solution

1. Configure the Uniform CLI

The CLI is used under the hood (e.g. to download the Context manifest at app start). Set the standard proxy variable before running CLI commands or starting your app:

export HTTPS_PROXY=http://your-proxy-server:8080

2. Configure the SDK — Next.js Page Router

Node.js does not automatically route fetch() through HTTP_PROXY/HTTPS_PROXY. SDK clients accept a custom fetch, so install https-proxy-agent:

npm install https-proxy-agent

Create a proxy-aware fetch and pass it to every SDK client (RouteClient, CanvasClient, ContentClient, etc.):

import { HttpsProxyAgent } from "https-proxy-agent";
import { RouteClient } from "@uniformdev/canvas";

function proxyFetch(input: RequestInfo | URL, init?: RequestInit) {
  if (process.env.HTTPS_PROXY) {
    const agent = new HttpsProxyAgent(process.env.HTTPS_PROXY);
    return fetch(input, { ...init, agent } as any);
  }
  return fetch(input, init);
}

export const routeClient = new RouteClient({
  apiKey: process.env.UNIFORM_API_KEY,
  projectId: process.env.UNIFORM_PROJECT_ID,
  fetch: proxyFetch,
});

3. Configure the SDK — Next.js App Router

The App Router uses native fetch() internally — you cannot pass a custom fetch, and Next.js overrides the global fetch dispatcher (acknowledged limitation). Instead, override globalThis.fetch in an instrumentation file, which runs at server start.

npm install undici

Create instrumentation.ts in your src/ directory (or project root without src/):

// src/instrumentation.ts
export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs" && process.env.HTTPS_PROXY) {
    const undici = await import("undici");
    const proxyAgent = new undici.ProxyAgent({
      uri: process.env.HTTPS_PROXY,
    });

    const originalFetch = globalThis.fetch;
    globalThis.fetch = ((input: any, init?: any) => {
      const url =
        typeof input === "string"
          ? input
          : input instanceof URL
            ? input.toString()
            : input.url;
      const isLocal =
        url?.includes("localhost") || url?.includes("127.0.0.1");

      if (isLocal) {
        return originalFetch(input, init);
      }

      return originalFetch(input, {
        ...init,
        dispatcher: proxyAgent,
      } as any);
    }) as typeof fetch;

    console.log(
      "[proxy] Routing external fetch requests through " + process.env.HTTPS_PROXY
    );
  }
}

undici.setGlobalDispatcher() alone is unreliable — Next.js 15 overrides the global dispatcher internally. Patching globalThis.fetch with a per-request dispatcher covers all external requests; the NEXT_RUNTIME check keeps undici out of client bundles. On Next.js 14 and earlier, enable instrumentation via experimental: { instrumentationHook: true } in next.config.ts.

4. Run the app

export HTTPS_PROXY=http://your-proxy-server:8080
export NO_PROXY=localhost,127.0.0.1
npm run dev

If your proxy performs SSL inspection (MITM), also trust its CA certificate: export NODE_EXTRA_CA_CERTS=/path/to/corporate-proxy-ca-cert.pem

Environment variables reference

Variable

Purpose

Example

HTTPS_PROXY

Proxy server URL for HTTPS requests

http://10.0.0.113:9090

HTTP_PROXY

Proxy server URL for HTTP requests

http://10.0.0.113:9090

NO_PROXY

Hosts that bypass the proxy (comma-separated)

localhost,127.0.0.1

NODE_EXTRA_CA_CERTS

CA certificate path for SSL-inspecting proxies

/path/to/ca-cert.pem

Troubleshooting

Verify it works: on app start, look for [proxy] Routing external fetch requests through http://your-proxy-server:8080 in the logs.

Instrumentation not running on Next.js 14 or earlier: add experimental: { instrumentationHook: true } to your Next.js config (enabled by default in Next.js 15+).

Resources