Popsicle HTTP Redirects Middleware
Popsicle Redirects is a middleware package for the Popsicle HTTP client library, designed to automatically follow HTTP redirects (e.g., 301, 302, 307, 308). It abstracts away the complexity of handling redirect chains, allowing developers to configure the maximum number of redirects and define custom confirmation logic for non-idempotent redirects (307/308). The current stable version is 1.1.1. The project appears to follow an as-needed release cadence for bug fixes and minor improvements, typically tied to the `servie` ecosystem. Its primary differentiator is its integration into the `popsicle` middleware pattern, providing a specific solution for redirect handling within that client.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'use')
cause Attempting to use `redirects` without providing a valid middleware function, or incorrectly chaining it with `popsicle.request`.fixEnsure `redirects` is called with a compatible middleware, typically `transport()` from `popsicle`, and then correctly chained in the `request.use()` call: `request.use(redirects(transport()))`. -
Error: Too many redirects
cause The HTTP request encountered more redirects than the configured `maxRedirects` limit (default is 5).fixIncrease the `maxRedirects` option if more redirects are expected, or investigate the target URL for excessive or cyclic redirects. Example: `redirects(transport(), { maxRedirects: 10 })`. -
TS2345: Argument of type 'typeof import("...")' is not assignable to parameter of type 'Middleware'.cause Incorrectly importing or using the `redirects` function as a default import, or attempting to pass `redirects` directly where a middleware is expected without calling it.fixEnsure `redirects` is imported as a named export (`import { redirects } from 'popsicle-redirects';`) and called with the `transport()` function: `request.use(redirects(transport()))`.
Warnings
- breaking When upgrading to v1.1.1, ensure your application does not rely on cookies being forwarded during cross-origin redirects. This version introduced a security fix that discards cookies when redirected away to a different origin, preventing potential information leakage.
- gotcha Previous versions (prior to v1.0.1) could enter an infinite redirect loop if a malformed or cyclic redirect chain was encountered due to a flaw in request cloning.
- gotcha The `redirects` function expects a 'throwback' compatible middleware, typically `popsicle`'s `transport()` function. Passing nothing or an incompatible middleware will result in runtime errors.
- gotcha By default, 307 (Temporary Redirect) and 308 (Permanent Redirect) status codes, which typically preserve the request method, are not automatically followed unless explicitly confirmed. The default `confirmRedirect` option returns `false`.
Install
-
npm install popsicle-redirects -
yarn add popsicle-redirects -
pnpm add popsicle-redirects
Imports
- redirects
const { redirects } = require('popsicle-redirects');import { redirects } from 'popsicle-redirects'; - redirects (default import)
import redirects from 'popsicle-redirects';
import { redirects } from 'popsicle-redirects'; - Middleware Integration
import { redirects } from 'popsicle-redirects'; const redirectMiddleware = redirects();import { redirects } from 'popsicle-redirects'; import { transport } from 'popsicle'; const redirectMiddleware = redirects(transport()); // Add redirectMiddleware to your Popsicle request chain
Quickstart
import { request } from 'popsicle';
import { redirects } from 'popsicle-redirects';
import { transport } from 'popsicle';
async function fetchDataWithRedirects() {
const httpClient = request
.use(redirects(transport())) // Integrate the redirects middleware
.use(async (request, next) => {
// Example of custom middleware or error handling
try {
const response = await next(request);
if (!response.ok) {
console.error(`HTTP Error: ${response.status} ${response.statusText}`);
}
return response;
} catch (error) {
console.error('Request failed:', error.message);
throw error;
}
});
try {
const response = await httpClient.get('http://example.com/redirect-to-target');
const data = await response.text();
console.log('Response data:', data);
} catch (error) {
console.error('Failed to fetch:', error.message);
}
}
fetchDataWithRedirects();