Changelog
All notable changes to next-api-layer are documented here.
v0.2.4 - June 3, 2026#
Fixed#
- Rate limiter double-counting bug:
createAuthProxyinvokedrateLimiter.check()twice per request — once at the gate and again when applying theX-RateLimit-*response headers. Every request was counted twice, effectively halving the configured limit (e.g. a limit of100behaved like50). The check result is now computed once and reused for both gating and header application.
Added#
skipPrefetchoption (RateLimitConfig.skipPrefetch, defaulttrue): Next.js<Link>prefetch requests no longer consume rate-limit tokens. Prefetches are detected vianext-router-prefetch,sec-purpose,purpose/x-purpose, andx-mozheaders. Set tofalseto count them.ipHeadersoption (RateLimitConfig.ipHeaders): Configure the ordered list of headers used to resolve the real client IP for rate-limit keying. Defaults to['cf-connecting-ip', 'true-client-ip', 'x-real-ip', 'x-forwarded-for'], adding first-class Cloudflare / proxy support. Thex-forwarded-forvalue correctly uses the first (client) hop.- New exported helpers:
getClientIp(req, headerPriority?)— resolve the real client IP behind proxies and CDNs.isPrefetchRequest(req)— detect Next.js prefetch requests.DEFAULT_IP_HEADERS— the default IP header priority list.
Notes#
- The built-in rate limiter remains in-memory (per-instance). For multi-instance / serverless deployments that need a shared counter, a pluggable Redis-backed store is planned for a future release (it requires an async store API and is intentionally deferred to avoid a breaking change).
Migration#
No code changes required. The double-count fix means your real effective limit
now matches the configured value — if you previously compensated by doubling
your max, you can restore it to the intended number.
v0.2.3 - April 20, 2026#
Fixed#
- Sanitization over-escaping bug: Plain text characters (
/,',`,=) were being HTML-escaped to entities like/,',=, which corrupted user-facing text in React/Vue/Angular apps (e.g.O'Reilly's Booksappeared asO'Reilly's Books). Modern frameworks already escape text at render time, so API-level entity escaping is redundant and harmful.
Changed#
- Default
modeis now'strip'(was'escape'). Removes HTML tags while preserving plain text characters. Matches the philosophy of DOMPurify and sanitize-html: operate at the tag level, not the character level. escapemode char set minimized to the OWASP minimum: only<,>,&,"are escaped. Apostrophes, slashes, backticks, and equals signs pass through unchanged (safe in text content; double-quoted HTML attributes make'safe too).stripmode now only removes well-formed tags (<letter...>/</letter...>). Bare<,>,&characters in text like5 < 10 and 20 > 3are preserved.SanitizationConfig.modeadded as a public, documented option:'strip' | 'escape' | 'allowList'.
Migration#
No code changes required for most apps — the new defaults produce safer, cleaner
output. If you explicitly set mode: 'escape' and relied on the old aggressive
char set, tag injection (<script>, <img onerror>, etc.) is still blocked,
but /, ', `, = now pass through. This is the correct behavior for
data bound to React/Vue/Angular text nodes.
Before / After#
v0.2.2 - April 17, 2026#
Added#
-
Enhanced Debug Body Logging: Smart request/response body logging with DX-focused features
logRequestBody- Log request payloads separately (default: false)logResponseBody- Log response data separately (default: false)maxStringLength- Per-field string truncation (default: 500)maxArrayItems- Array item limit with "... and N more" indicator (default: 10)maxDepth- Object nesting depth limit (default: 5)autoMask- Enable/disable sensitive field masking (default: true)sensitiveFields- Customize which fields to mask (password, token, secret, cvv, etc.)
-
Smart Binary Detection: Automatically detects and summarizes binary-like data
- Base64 strings shown as
[base64, 45KB] - Data URLs shown as
[data URL (image/png), 2.3MB] - Prevents terminal spam from large payloads
- Base64 strings shown as
-
Enhanced FormData Logging: Better visibility for file uploads
- File info:
[File: photo.jpg, 2.4MB, image/jpeg] - Sensitive fields masked in FormData
- Field count with "... and N more fields" indicator
- File info:
Changed#
logBodydeprecated in favor oflogRequestBody/logResponseBody(still works for backward compatibility)bodyPreviewLengthdeprecated in favor ofmaxStringLength(still works for backward compatibility)
Example#
v0.2.1 - April 16, 2026#
Fixed#
- URL field sanitization: URL values in API payloads are now preserved correctly
- Previously:
https://example.com→https//example.com - Now: URLs with safe protocols (https, http, mailto, tel, ftp) are preserved
- Relative paths (
/callback) are also preserved - XSS vectors (
javascript:,data:) are still sanitized
- Previously:
Improved#
- Documentation sync: Fixed mismatches between docs and TypeScript types
errorMessageskeys corrected:connectionError,serverError,timeout,noTokenmethodSpoofingobject config withfieldNameoption documentedswrConfigfullSWRConfigurationsupport noted
v0.2.0 - April 15, 2026#
Added#
-
Typed Error Classes: New error hierarchy for better error handling
ApiError- Base error class with code and timestampHttpError- HTTP errors with status code and statusTextTimeoutError- Request timeout errors with endpoint and timeout infoNetworkError- Network failures with cause trackingAuthError- Authentication errors with reason (no_token, invalid_token, expired_token)ValidationError- Validation errors with field-level error messagesRateLimitError- Rate limit errors with retryAfter, limit, remaining info- Type guards:
isApiError(),isHttpError(),isTimeoutError(),isNetworkError(),isAuthError(),isRateLimitError() - Utilities:
isRetryableStatus(),isRetryableError()
-
Retry Logic: Automatic retry for failed requests
createApiClient({ retry: { enabled: true, maxAttempts: 3 } })- Backoff strategies:
'exponential','linear','fixed' - Configurable retry conditions: status codes, network errors
- Per-request override:
api.get('/endpoint', { retry: false })
-
Debug Mode: Development logging for requests/responses
createApiClient({ debug: { enabled: true } })- Log requests, responses, timing, headers, body preview
- Custom logger support
-
Request Deduplication: Prevent duplicate in-flight requests
createApiClient({ dedupe: { enabled: true, methods: ['GET'] } })- Automatically returns same promise for identical concurrent requests
-
Request ID / Correlation: Request tracing headers
createApiClient({ requestId: { enabled: true } })- Custom header name and generator support
-
Next.js 16+ Support: Documentation and examples now support both:
proxy.tswithexport const proxy = authProxy(Next.js 16+)middleware.tswithexport default authProxy(Next.js 14-15)
Changed#
- BREAKING: methodSpoofing config: Now accepts
boolean | MethodSpoofingConfig - CLI: Uses native Node.js
readline/promises- zero runtime dependencies - CLI: New questions for protected routes and auth routes
Removed#
- prompts dependency: CLI now uses native Node.js APIs
Migration from v0.1.x#
- If using methodSpoofing as object - no changes needed
- CLI - regenerate config with
npx next-api-layer init(optional)
v0.1.11 - April 13, 2026#
Fixed#
- Non-ASCII characters in x-auth-user header: User data with Turkish (ğ, ş, ı, ö, ü, ç), German (ä, ö, ü, ß), or other non-ASCII characters now works correctly
- HTTP headers only support ISO-8859-1 (0-255), characters like
ğ(287) causedTypeError: Cannot convert argument to a ByteString - User data is now Base64 encoded in proxy and decoded in
getServerUser() - This is an internal change - no API changes required
- HTTP headers only support ISO-8859-1 (0-255), characters like
Migration from v0.1.10#
No breaking changes. Simply update your package:
v0.1.10 - April 10, 2026#
Fixed#
- login/register success detection:
login()andregister()functions now correctly returnsuccess: truewhen API responds with success- Previously returned
success: falsewhen response didn't include user data - Now checks
res.ok && json.success !== falseinstead of relying on user data presence - User data is now optional - if not in response, library fetches from
/meendpoint
- Previously returned
Added#
- parseAuthResponse prop: New optional prop for custom login/register response parsing
- Allows handling non-standard backend auth response formats
- Example:
parseAuthResponse={(json) => ({ success: json.ok, user: json.result?.user })}
- AuthResponseParsed type: Exported from
next-api-layer/clientfor TypeScript users
Migration from v0.1.9#
No breaking changes. Simply update your package:
v0.1.9 - April 10, 2026#
Fixed#
- i18n route matching:
protectedRoutes,authRoutes, andpublicRoutesnow correctly work withlocalePrefix: 'always'- Routes like
/tr/loginare now properly matched against config/login - Locale prefix is automatically stripped before route matching
- Works with any locale configured in
i18n.locales
- Routes like
Added#
- New
stripLocale()utility function exported fromnext-api-layer/proxy- Strips locale prefix from pathname for custom route comparisons
Migration from v0.1.8#
No breaking changes. Simply update your package:
v0.1.8 - April 9, 2026#
Fixed#
- x-locale header loss: Fixed issue where
x-localeheader was lost when usingi18n.middlewareoption- Header is now set as response header instead of request header
- Ensures locale is available in server components via
headers().get('x-locale')
Migration from v0.1.7#
No breaking changes. Simply update your package:
v0.1.7 - April 8, 2026#
Added#
- i18n Middleware Integration: New
middlewareoption inI18nConfigfor seamless integration with next-intl and similar libraries- Library calls your i18n middleware internally and merges responses automatically
- Preserves critical headers (
x-locale,x-auth-user,x-refreshed-token) across middleware chain - No more losing locale headers when using custom middleware hooks
Fixed#
- Header preservation:
afterAuthhook no longer loses library-set headers when calling external middleware functions
Example Usage#
Migration from v0.1.6#
No breaking changes. To use the new middleware integration, add the middleware option to your i18n config.
v0.1.6 - April 7, 2026#
Added#
- Per-request sanitization control: New options in
RequestOptionsfor fine-grained sanitization controlskipSanitize: boolean- Skip all sanitization for a specific requestskipSanitizeFields: string[]- Skip sanitization for specific fields only
patch()method now acceptsRequestOptionsparameter (was missing)
Example Usage#
Migration from v0.1.5#
No breaking changes. Simply update your package:
v0.1.5 - April 4, 2026#
Added#
- i18n Support: Automatic locale detection and injection for API requests
- Added
i18nconfig option tocreateAuthProxyfor locale detection from URL path - Added
i18nconfig option tocreateApiClientfor auto-appending?lang={locale}to requests - New
x-localeheader for passing locale from middleware to route handlers - Configurable
paramName(default:lang),locales, anddefaultLocale
- Added
Changed#
HEADERSconstant now includesLOCALE: 'x-locale'- Proxy handlers now extract locale from URL pathname and set
x-localeheader - API client reads
x-localeheader and appends locale query parameter to backend requests
Migration from v0.1.4#
No breaking changes. To enable i18n, add the config:
v0.1.4 - April 1, 2026#
Fixed#
- Empty cookie creation bug: Fixed an issue where
cookies.delete()was called on non-existent cookies, causing empty-value cookies to be set in the browser. Now all delete operations check for cookie existence before attempting deletion.
Added#
- New
safeDeleteCookiehelper function that only deletes cookies that actually exist in the request. - Updated
deleteAllAuthCookiesto acceptreqparameter for cookie existence checking.
Changed#
- All cookie delete operations now verify cookie existence before deletion to prevent phantom cookies.
Migration from v0.1.3#
No breaking changes. Simply update your package:
v0.1.3 - March 20, 2026#
Added#
- Initial stable release with proxy and API client functionality
- Guest token support with automatic creation
- Token validation and refresh mechanisms
- Rate limiting support
- CSRF protection
- Audit logging capabilities
- next-intl integration support
Features#
createAuthProxy- Main proxy function for Next.jscreateApiClient- Server-side API clientcreateProxyHandler- Flexible proxy handler for route handlersuseAuth- Client-side auth hookAuthProvider- React context providergetServerUser- Server-side user helper