{"id":16491,"library":"popsicle-redirects","title":"Popsicle HTTP Redirects Middleware","description":"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.","status":"active","version":"1.1.1","language":"javascript","source_language":"en","source_url":"git://github.com/serviejs/popsicle-redirects","tags":["javascript","popsicle","redirect","301","302","http","typescript"],"install":[{"cmd":"npm install popsicle-redirects","lang":"bash","label":"npm"},{"cmd":"yarn add popsicle-redirects","lang":"bash","label":"yarn"},{"cmd":"pnpm add popsicle-redirects","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, likely required for the underlying middleware functionality (though `popsicle` uses `servie` internally, `popsicle-redirects` might directly expose `servie`-compatible interfaces or rely on its types/utilities).","package":"servie","optional":false}],"imports":[{"note":"The library primarily promotes ESM usage. While CommonJS `require` might work with transpilation or specific Node.js configurations, direct `import` is the idiomatic way.","wrong":"const { redirects } = require('popsicle-redirects');","symbol":"redirects","correct":"import { redirects } from 'popsicle-redirects';"},{"note":"The `redirects` function is a named export, not a default export. Attempting a default import will result in `undefined`.","wrong":"import redirects from 'popsicle-redirects';","symbol":"redirects (default import)","correct":"import { redirects } from 'popsicle-redirects';"},{"note":"The `redirects` function expects a 'throwback' compatible middleware function as an argument, typically the `transport()` function from `popsicle` itself, or another middleware capable of handling the initial request.","wrong":"import { redirects } from 'popsicle-redirects';\nconst redirectMiddleware = redirects();","symbol":"Middleware Integration","correct":"import { redirects } from 'popsicle-redirects';\nimport { transport } from 'popsicle';\n\nconst redirectMiddleware = redirects(transport());\n// Add redirectMiddleware to your Popsicle request chain"}],"quickstart":{"code":"import { request } from 'popsicle';\nimport { redirects } from 'popsicle-redirects';\nimport { transport } from 'popsicle';\n\nasync function fetchDataWithRedirects() {\n  const httpClient = request\n    .use(redirects(transport())) // Integrate the redirects middleware\n    .use(async (request, next) => {\n      // Example of custom middleware or error handling\n      try {\n        const response = await next(request);\n        if (!response.ok) {\n          console.error(`HTTP Error: ${response.status} ${response.statusText}`);\n        }\n        return response;\n      } catch (error) {\n        console.error('Request failed:', error.message);\n        throw error;\n      }\n    });\n\n  try {\n    const response = await httpClient.get('http://example.com/redirect-to-target');\n    const data = await response.text();\n    console.log('Response data:', data);\n  } catch (error) {\n    console.error('Failed to fetch:', error.message);\n  }\n}\n\nfetchDataWithRedirects();","lang":"typescript","description":"This quickstart demonstrates how to integrate `popsicle-redirects` into a `popsicle` client to automatically follow HTTP redirects, including basic error handling."},"warnings":[{"fix":"Review existing code for assumptions about cookie forwarding during redirects. If cookie forwarding is explicitly required for specific same-origin scenarios after a redirect, consider implementing custom logic or ensuring redirects remain within the same origin.","message":"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.","severity":"breaking","affected_versions":">=1.1.1"},{"fix":"Upgrade to `popsicle-redirects@1.0.1` or later to resolve the infinite redirect loop issue. Always ensure your redirect chain eventually terminates or configure a `maxRedirects` option to prevent excessive loops.","message":"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.","severity":"gotcha","affected_versions":"<1.0.1"},{"fix":"Always initialize `redirects` with a valid transport middleware, e.g., `redirects(transport())` when used with `popsicle`.","message":"The `redirects` function expects a 'throwback' compatible middleware, typically `popsicle`'s `transport()` function. Passing nothing or an incompatible middleware will result in runtime errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"To enable following 307/308 redirects, provide a custom `confirmRedirect` function in the options: `redirects(transport(), { confirmRedirect: () => true })` or implement more sophisticated logic.","message":"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`.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure `redirects` is called with a compatible middleware, typically `transport()` from `popsicle`, and then correctly chained in the `request.use()` call: `request.use(redirects(transport()))`.","cause":"Attempting to use `redirects` without providing a valid middleware function, or incorrectly chaining it with `popsicle.request`.","error":"TypeError: Cannot read properties of undefined (reading 'use')"},{"fix":"Increase the `maxRedirects` option if more redirects are expected, or investigate the target URL for excessive or cyclic redirects. Example: `redirects(transport(), { maxRedirects: 10 })`.","cause":"The HTTP request encountered more redirects than the configured `maxRedirects` limit (default is 5).","error":"Error: Too many redirects"},{"fix":"Ensure `redirects` is imported as a named export (`import { redirects } from 'popsicle-redirects';`) and called with the `transport()` function: `request.use(redirects(transport()))`.","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.","error":"TS2345: Argument of type 'typeof import(\"...\")' is not assignable to parameter of type 'Middleware'."}],"ecosystem":"npm"}