diff --git a/.changeset/thirty-squids-relax.md b/.changeset/thirty-squids-relax.md
new file mode 100644
index 000000000000..6e6b633d0641
--- /dev/null
+++ b/.changeset/thirty-squids-relax.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fix imports using ?raw and ?url not working when `experimental.assets` is enabled
diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts
index 2ea3bf8179f9..9a8f3e3ad9d3 100644
--- a/packages/astro/src/assets/vite-plugin-assets.ts
+++ b/packages/astro/src/assets/vite-plugin-assets.ts
@@ -24,6 +24,9 @@ import { hashTransform, propsToFilename } from './utils/transformToPath.js';
 
 const resolvedVirtualModuleId = '\0' + VIRTUAL_MODULE_ID;
 
+const rawRE = /(?:\?|&)raw(?:&|$)/;
+const urlRE = /(\?|&)url(?:&|$)/;
+
 export default function assets({
 	settings,
 	logging,
@@ -233,6 +236,11 @@ export default function assets({
 				resolvedConfig = viteConfig;
 			},
 			async load(id) {
+				// If our import has the `?raw` or `?url` Vite query params, we'll let Vite handle it
+				if (rawRE.test(id) || urlRE.test(id)) {
+					return;
+				}
+
 				const cleanedUrl = removeQueryString(id);
 				if (/\.(jpeg|jpg|png|tiff|webp|gif|svg)$/.test(cleanedUrl)) {
 					const meta = await emitESMImage(id, this.meta.watchMode, this.emitFile, settings);
diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js
index 69f94403ef10..b6b48270eebc 100644
--- a/packages/astro/test/core-image.test.js
+++ b/packages/astro/test/core-image.test.js
@@ -116,6 +116,33 @@ describe('astro:image', () => {
 			});
 		});
 
+		describe('vite-isms', () => {
+			/**
+			 * @type {cheerio.CheerioAPI}
+			 */
+			let $;
+			before(async () => {
+				let res = await fixture.fetch('/vite');
+				let html = await res.text();
+				$ = cheerio.load(html);
+			});
+
+			it('support ?url imports', () => {
+				let $url = $('#url');
+				expect($url.text()).to.equal('string');
+			});
+
+			it('support ?raw imports', () => {
+				let $raw = $('#raw');
+				expect($raw.text()).to.equal('string');
+			});
+
+			it('support glob import as raw', () => {
+				let $raw = $('#glob-import');
+				expect($raw.text()).to.equal('string');
+			});
+		});
+
 		describe('remote', () => {
 			describe('working', () => {
 				let $;
diff --git a/packages/astro/test/fixtures/core-image/src/pages/vite.astro b/packages/astro/test/fixtures/core-image/src/pages/vite.astro
new file mode 100644
index 000000000000..6bf78a93420d
--- /dev/null
+++ b/packages/astro/test/fixtures/core-image/src/pages/vite.astro
@@ -0,0 +1,10 @@
+---
+import imageRaw from "../assets/penguin1.jpg?raw";
+import imageUrl from "../assets/penguin1.jpg?url";
+
+const globImport = import.meta.glob('../assets/penguin1.jpg', { as: 'raw', eager: true })
+---
+
+<div id="url">{typeof imageUrl}</div>
+<div id="raw">{typeof imageRaw}</div>
+<div id="glob-import">{typeof globImport['../assets/penguin1.jpg']}</div>