-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Astro Info
Astro v5.16.3
Vite v6.4.1
Node v22.21.1
System Linux (x64)
Package Manager npm
Output static
Adapter none
Integrations none
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
Description
When @assets points to a directory outside the project root (one level up), images imported from it and rendered via astro:assets (either <Image> or getImage) fail in dev with a 500 from the /_image endpoint.
The same images, when used via a plain <img src={asset.src}>, work fine in dev.
Build (astro build) also works: the generated HTML references hashed files under /_astro/... and loads correctly.
So the problem appears to be specific to the dev image service when @assets points to an external directory outside the project root.
Minimal reproduction
-
Create a fresh Astro project:
npm create astro@latest my-app -- --template minimal --install --no-git --skip-houston
-
Make
shared-assetsas an external to the project directory:
mkdir shared-assets
cat > shared-assets/logo.svg << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 200 60">
<rect width="100%" height="100%" fill="none"/>
<circle cx="30" cy="30" r="20" fill="#1f8ceb"/>
<path d="M46 22 L62 30 L46 38 Z" fill="#0b6abf" opacity="0.9"/>
<text x="90" y="36" font-family="sans-serif"
font-size="20" fill="#111" dominant-baseline="middle">Astro</text>
</svg>
EOF- Make sure Vite is allowed to read outside the project root, i.e. in
astro.config.mjs:
cat > my-app/astro.config.mjs << 'EOF'
import { defineConfig } from "astro/config";
import { fileURLToPath } from "node:url";
// Resolve alias paths
const assetsPath = fileURLToPath(new URL("../shared-assets", import.meta.url));
export default defineConfig({
vite: {
resolve: {
alias: {
"@assets": assetsPath,
},
},
server: {
fs: {
allow: ['.', '../..'],
},
},
},
});
EOF- In
src/pages/index.astroadd an image imported from@assetsand rendered viaastro:assets:
cat > my-app/src/pages/index.astro << 'EOF'
---
import { Image, getImage } from "astro:assets";
import logo from "@assets/logo.svg";
---
<html>
<body>
<!-- This one goes through /_image -->
<Image src={logo} width={140} alt="logo via astro:assets" />
<!-- This one uses Vite /@fs and works -->
<img src={logo.src} width="140" alt="logo via img src" />
</body>
</html>
EOF- Run dev server:
(cd my-app && npm run dev -- --host 0.0.0.0)- Open the page in the browser and check the Network tab.
Expected behavior
- Both images load successfully in dev.
- The
<Image>(orgetImage) call uses the/_imageendpoint without errors, even though@assetsreference an external directory.
Actual behavior
-
The
<img src={logo.src}>version works in dev. -
The
<Image src={logo}>/getImage({ src: logo })version fails:-
The browser requests something like:
<img src="/_image?href=%2F%40fs%2Ftmp%2Ft2%2Fshared-assets%2Flogo.svg%..."
-
The dev server responds with 500 for that /_image request.
-
-
No such problem in
astro buildoutput: the generated HTML references a static file under/_astro/...and it loads correctly (tested withastro build && astro preview).
So the behavior is inconsistent:
- dev + external
@assets+astro:assets→ 500 from /_image - dev + external
@assets+ plain<img src={asset.src}>→ OK - build + external
@assets+astro:assets→ OK
Environment
- Astro: 5.16.3
- Node: v22.21.1
- Npm: 10.9.4
- OS: Linux (also likely reproducible on other OSes as well)
Additional context
- In my real project,
@assetswould be a reference to a shared assets folder in the parent workspace (monorepo). - Dev server already allows going up via
vite.server.fs.allow = ['.', '../..']. - The broken dev URL encodes a path under
/@fs/tmp/t2/shared-assets/logo.svginto the href query parameter of /_image, which seems to trip whatever path/FS checks the image service uses. - Using
<img src={asset.src}>everywhere is a viable workaround, but it would be great ifastro:assetsworked with assets located in an upper-level directory (via alias) in dev the same way it does in build. - The issue seems to be strongly related with the astro:assets image service returns 500 in dev when src/assets is a symlink #14937
What's the expected result?
- Both images load successfully in dev.
- The
<Image>(orgetImage) call uses the/_imageendpoint without errors, even though@assetsreference an external directory.
see
https://stackblitz.com/edit/github-fkzyjbhb?file=src%2Fpages%2Findex.astro
N.B. stackblitz does not allow to create parent dirs, so there is a ER app there
Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-fkzyjbhb?file=src%2Fpages%2Findex.astro
Participation
- I am willing to submit a pull request for this issue.