diff --git a/.changeset/warm-mangos-dance.md b/.changeset/warm-mangos-dance.md
new file mode 100644
index 000000000000..f73664e699d0
--- /dev/null
+++ b/.changeset/warm-mangos-dance.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/image': patch
+---
+
+Support relative protocol image URL
diff --git a/packages/integrations/image/src/build/ssg.ts b/packages/integrations/image/src/build/ssg.ts
index 4e017bbb4faf..2382797c1416 100644
--- a/packages/integrations/image/src/build/ssg.ts
+++ b/packages/integrations/image/src/build/ssg.ts
@@ -54,6 +54,10 @@ function webToCachePolicyResponse({ status, headers: _headers }: Response): Cach
async function loadRemoteImage(src: string) {
try {
+ if (src.startsWith('//')) {
+ src = `https:${src}`;
+ }
+
const req = new Request(src);
const res = await fetch(req);
diff --git a/packages/integrations/image/src/lib/get-image.ts b/packages/integrations/image/src/lib/get-image.ts
index 5e7f4d0a4eab..3e32e6f3ed17 100644
--- a/packages/integrations/image/src/lib/get-image.ts
+++ b/packages/integrations/image/src/lib/get-image.ts
@@ -140,12 +140,14 @@ export async function getImage(
? _loader.serializeTransform(resolved)
: globalThis.astroImage.defaultLoader.serializeTransform(resolved);
+ const imgSrc =
+ !isLocalImage && resolved.src.startsWith('//') ? `https:${resolved.src}` : resolved.src;
let src: string;
- if (/^[\/\\]?@astroimage/.test(resolved.src)) {
- src = `${resolved.src}?${searchParams.toString()}`;
+ if (/^[\/\\]?@astroimage/.test(imgSrc)) {
+ src = `${imgSrc}?${searchParams.toString()}`;
} else {
- searchParams.set('href', resolved.src);
+ searchParams.set('href', imgSrc);
src = `/_image?${searchParams.toString()}`;
}
diff --git a/packages/integrations/image/src/loaders/squoosh.ts b/packages/integrations/image/src/loaders/squoosh.ts
index 455d476d83e5..87d6e26ec1ad 100644
--- a/packages/integrations/image/src/loaders/squoosh.ts
+++ b/packages/integrations/image/src/loaders/squoosh.ts
@@ -89,6 +89,8 @@ class SquooshService extends BaseSSRService {
if (autorotate) {
operations.push(autorotate);
}
+ } else if (transform.src.startsWith('//')) {
+ transform.src = `https:${transform.src}`;
}
if (transform.width || transform.height) {
diff --git a/packages/integrations/image/src/utils/paths.ts b/packages/integrations/image/src/utils/paths.ts
index 556505704f99..ac6dccffc1f5 100644
--- a/packages/integrations/image/src/utils/paths.ts
+++ b/packages/integrations/image/src/utils/paths.ts
@@ -2,7 +2,7 @@ import { TransformOptions } from '../loaders/index.js';
import { shorthash } from './shorthash.js';
export function isRemoteImage(src: string) {
- return /^http(s?):\/\//.test(src);
+ return /^(https?:)?\/\//.test(src);
}
function removeQueryString(src: string) {
diff --git a/packages/integrations/image/test/fixtures/squoosh-service/src/pages/index.astro b/packages/integrations/image/test/fixtures/squoosh-service/src/pages/index.astro
index f5e4badfe719..25feb1716156 100644
--- a/packages/integrations/image/test/fixtures/squoosh-service/src/pages/index.astro
+++ b/packages/integrations/image/test/fixtures/squoosh-service/src/pages/index.astro
@@ -14,5 +14,7 @@ import { Image } from '@astrojs/image/components';
+
+