Skip to content

feat: add remotePatterns support for external storage providers#2

Merged
edmogeor merged 6 commits into
mainfrom
feat/remote-patterns
Jun 22, 2026
Merged

feat: add remotePatterns support for external storage providers#2
edmogeor merged 6 commits into
mainfrom
feat/remote-patterns

Conversation

@edmogeor

Copy link
Copy Markdown
Owner

Closes #1.

What

Adds a remotePatterns config option so the plugin can optimize images served from external upload providers (S3, Google Cloud Storage, etc.), mirroring next/image remotePatterns. Local /uploads/ paths remain allowed by default — no breaking change.

'next-image': {
  config: {
    remotePatterns: [
      { protocol: 'https', hostname: 'storage.googleapis.com' },
    ],
  },
},

How

  • Pattern matching (server/src/remote-pattern.ts) — faithful port of Next.js's matchRemotePattern/hasRemoteMatch, using the same picomatch engine so wildcard/edge-case behavior is identical.
  • Controller (controllers/image-optimize.ts) — replaces the flat /uploads/ check with Next.js's validation flow: reject protocol-relative //, keep /uploads/ for local, and for absolute URLs require http(s) + a matching remotePattern.
  • Service (services/image-optimize.ts) — fetches allow-listed remote images over HTTP (10s timeout, 50 MB cap) instead of only reading the local public/ dir.
  • Client loader (strapi-next-image/src/image-loader.ts) — previously stripped every absolute URL to a relative path, which silently defeated remotePatterns. Now strips only same-origin Strapi URLs and forwards cross-origin ones absolute. Requires the loader path/base to be set to your Strapi URL when using a separate frontend.

Notes

  • SSRF protection is preserved: absolute URLs are allow-list-only (400 "url" parameter is not allowed otherwise).
  • The remote download size cap is enforced after buffering the response body — it rejects oversized images but does not stream-abort mid-download. Fine for trusted, allow-listed origins; worth revisiting if that assumption changes.

Versioning

Both packages bumped 1.0.11.1.0; CHANGELOG updated.

Testing

  • New unit tests for matchRemotePattern/hasRemoteMatch, the config validator, controller allow-list branches, and loader cross-origin forwarding.
  • Full suites pass: 102 (plugin) + 132 (client). Both typechecks clean.

edmogeor added 6 commits June 22, 2026 18:48
Allow optimizing images served from external upload providers (S3, GCS,
etc.) by allow-listing their origins, mirroring next/image remotePatterns.
Local /uploads/ paths remain allowed by default, so no breaking change.

- Port matchRemotePattern/hasRemoteMatch from Next.js (picomatch engine)
- Add remotePatterns config option, type, and validator (default: [])
- Controller validates absolute URLs against the allow-list; service
  fetches allow-listed remote images over HTTP
- Client loader forwards cross-origin src absolute instead of stripping it

Closes #1
Share an ImageSource type and httpError helper between the remote and
local read paths; collapse the let+if/else in _optimizeAndCache into a
single const destructuring. Behavior unchanged.
Fallow flagged the config validator's cognitive complexity rising from
the inlined remotePatterns array/loop check. Extract it to a named helper
and add focused tests (the validator previously had zero coverage).
Convert JSDoc /** */ blocks to // line comments across both packages,
shorten verbose comments, and drop redundant WHAT comments. No behavior
change.
Bump both packages to 1.1.0 and add the CHANGELOG entry for the
remotePatterns feature (closes #1).
The readLocalImage/fetchRemoteImage refactor left `ext` destructured but
unused in _optimizeAndCache; drop it from ImageSource and both helpers.
tsc didn't flag it but eslint no-unused-vars did.
@edmogeor edmogeor merged commit 8e6b595 into main Jun 22, 2026
2 checks passed
@edmogeor edmogeor deleted the feat/remote-patterns branch June 22, 2026 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add remotePatterns support for external storage providers

1 participant