Skip to content

fix(deps): update dependency astro to v7 [security]#279

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-astro-vulnerability
Open

fix(deps): update dependency astro to v7 [security]#279
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/npm-astro-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
astro (source) ^6.4.4^7.0.0 age adoption passing confidence

Astro: Host header SSRF in prerendered error page fetch

CVE-2026-54299 / GHSA-2pvr-wf23-7pc7

More information

Details

Summary

Astro SSR apps with prerendered error pages (/404 or /500 using export const prerender = true) fetch those pages over HTTP at runtime when an error occurs. The URL for this fetch is derived from request.url, which in turn gets its origin from the incoming Host header. When the Host header is not validated against allowedDomains, an attacker can point the fetch at an arbitrary host and read the response.

Who is affected

This affects SSR deployments that:

  1. Have a prerendered 404 or 500 page
  2. Use createRequestFromNodeRequest from astro/app/node with app.render() without overriding prerenderedErrorPageFetch — this includes custom servers built on the public API and third-party adapters

Not affected:

  • @astrojs/node >= 9.5.4 (reads error pages from disk)
  • @astrojs/cloudflare (uses the ASSETS binding)
  • The dev server (renders error pages in-process)
How it works

createRequestFromNodeRequest builds request.url from the raw Host / :authority header. The allowedDomains option is accepted but only gates X-Forwarded-For — it does not constrain the URL origin. (The public createRequest does fall back to localhost for unvalidated hosts; this internal builder did not.)

When app.render() encounters a 404 or 500 with a prerendered error route, default-handler.ts constructs the error page URL using the origin from request.url and fetches it via prerenderedErrorPageFetch, which defaults to global fetch. The response body is served to the client.

An attacker sends a request with Host: attacker-host:port, triggers an error (e.g., requesting a nonexistent path for a 404), and receives the response from the attacker-controlled host reflected back.

Remediation

The error page fetch origin is now validated against allowedDomains before use. When the host is validated, the original origin is preserved. Otherwise, it falls back to localhost. The fetch is also wrapped in a try/catch so that connection failures degrade gracefully to a plain error response.

Credit

5ud0 / Tarmo Technologies

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Astro: XSS via Unescaped Attribute Names in Spread Props

CVE-2026-54298 / GHSA-jrpj-wcv7-9fh9

More information

Details

Summary

The spreadAttributes function in Astro's server-side rendering pipeline iterates over object keys and passes them directly to addAttribute, which interpolates the key into the HTML output without escaping. When a developer uses the spread syntax {...props} on an HTML element and the object keys come from an untrusted source (API, CMS, URL parameters), an attacker can inject arbitrary HTML attributes including event handlers like onmousemove, onclick, or break out of the attribute context entirely to inject new elements.

Details

The vulnerable function is addAttribute at packages/astro/src/runtime/server/render/util.ts:81-141:

export function addAttribute(value: any, key: string, shouldEscape = true, tagName = '') {
    if (value == null) {
        return '';
    }
    
    return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); //  key interpolated not escaped
}

This function is called from spreadAttributes at packages/astro/src/runtime/server/index.ts:91-92:

for (const [key, value] of Object.entries(values)) {
    output += addAttribute(value, key, true, _name);
}

The toAttributeString function escapes the attribute value, but the attribute name key is never validated or escaped. An attacker can craft a JSON object with a key containing " characters to break out of the attribute context and inject event handlers.

Execution flow: User controlled object keys (from API, CMS, URL params) are spread onto element via {...props}. The compiler generates spreadAttributes(props) which iterates with Object.entries() and calls addAttribute(value, key). The key is interpolated as ` ${key}="${escapedValue}"`. A malicious key breaks attribute context, resulting in XSS.

POC

Create an SSR Astro page (src/pages/index.astro):

---
const props = JSON.parse(Astro.url.searchParams.get('props') || '{}');
---
<html>
<body>
  <h1>Hello</h1>
  <div {...props}>Move mouse here</div>
</body>
</html>

Enable SSR in astro.config.mjs (for URL based demo):

export default defineConfig({
  output: 'server'
});

Note: SSR is not required for the vulnerability to exist. In static builds (default), the attack vector is compromised data sources at build time (API, CMS, database). SSR simply makes the PoC easier to demonstrate via URL parameters.

Start the dev server and visit:

http://localhost:4321/?props={"x\" onmousemove=\"alert(document.cookie)\" y":""}

URL encoded:

http://localhost:4321/?props=%7B%22x%5C%22%20onmousemove%3D%5C%22alert(document.cookie)%5C%22%20y%22%3A%22%22%7D

View the HTML source. The output contains:

<div x" onmousemove="alert(document.cookie)" y="">Move mouse here</div>

The key x" onmousemove="alert(document.cookie)" y breaks out of the attribute context. Moving the mouse over the div executes the JavaScript.

Captura de tela 2026-06-02 005906
Impact

An attacker can execute arbitrary JavaScript in the context of a victim's browser session on any Astro application that spreads object props from untrusted sources onto HTML elements. This is a common pattern when integrating with external APIs or CMS systems. Exploitation enables session hijacking via cookie theft, credential theft by injecting fake login forms or keyloggers, defacement of the rendered page, and redirection to attacker controlled domains.

The vulnerability affects all Astro versions that support spread syntax on HTML elements and is exploitable in SSR, SSG (if build time data is compromised), and hybrid deployments.

Severity

  • CVSS Score: 4.2 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:L/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Astro: Reflected XSS via unescaped View Transition animation properties

GHSA-4g3v-8h47-v7g6

More information

Details

Summary

Astro's server-side View Transition CSS generator interpolates animation properties into an inline <style> element without escaping them for the CSS and HTML contexts.

An attacker-controlled value passed to an animation property such as duration can contain a </style> sequence, terminate the generated style element, and inject arbitrary HTML or JavaScript.

This is similar to GHSA-8hv8-536x-4wqp, but exploits a different injection point: unescaped View Transition animation values in a server-generated <style> element rather than an unescaped slot name in a hydration template.

Like GHSA-8hv8-536x-4wqp, exploitation requires an application to pass attacker-controlled data to an Astro API. However, the value is subsequently inserted into the HTML response without context-appropriate escaping by Astro.

Details

packages/astro/src/runtime/server/transition.ts

The generated stylesheet is wrapped in a <style> element and marked as HTML-safe:

const css = sheet.toString();
result._metadata.extraHead.push(markHTMLString(`<style>${css}</style>`));

Animation properties are added to the stylesheet without escaping:

if (anim.duration) {
  addAnimationProperty(builder, 'animation-duration', toTimeValue(anim.duration));
}

For string values, toTimeValue() returns the input unchanged:

export function toTimeValue(num: number | string) {
  return typeof num === 'number' ? num + 'ms' : num;
}

As a result, a duration value containing </style> can escape from the generated style element.

Other TransitionAnimation properties, including easing, direction, delay, fillMode, and name, are serialized by the same animation builder. The following PoC only relies on the official fade() helper and its duration option.

PoC

Using:

  • astro@7.0.9
  • @astrojs/node@11.0.2
astro.config.mjs
import node from '@&#8203;astrojs/node';
import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
src/pages/index.astro
---
import { fade } from 'astro:transitions';

const duration = Astro.url.searchParams.get('duration') ?? '300ms';
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>PoC</title>
  </head>
  <body>
    <div transition:animate={fade({ duration })}>
      Animated content
    </div>
  </body>
</html>
Payload:

open:

http://localhost:4321/?duration=%3C%2Fstyle%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E%3C!--

The browser interprets </style> as the end of the generated style element and executes the injected script. An alert dialog is displayed when the page is opened.

image
Impact

An attacker who can control a View Transition animation value can execute arbitrary JavaScript in the origin of the affected Astro application.

The query-based reflected XSS scenario affects on-demand/server-rendered routes, such as:

  • projects configured with output: "server";
  • pages using export const prerender = false;
  • other server-side data flows that pass attacker-controlled values into a View Transition animation definition.

Successful exploitation may allow access to sensitive page data and authenticated actions available to the victim.

Suggested Fix

Animation values should be serialized using context-appropriate CSS escaping or validation before being added to the generated stylesheet.

Additionally, content inserted into a raw <style> element must not be able to contain an HTML end-tag sequence such as </style>. The final generated CSS should be made safe for the HTML raw-text context before it is passed to markHTMLString().

Severity

  • CVSS Score: 5.3 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Astro: Cross-site scripting via unescaped transition:* directive values on hydrated islands

CVE-2026-59727 / GHSA-7pw4-f3q4-r2p2

More information

Details

Summary

When a transition:persist, transition:scope, or transition:persist-props directive is applied to a client-hydrated (client:*) component, Astro copied the directive value onto the rendered <astro-island> element without HTML-escaping it. If a developer reflects attacker-controlled input into one of these directives, an attacker can break out of the attribute and inject arbitrary HTML/JavaScript into the server-rendered output, resulting in reflected cross-site scripting (XSS).

Severity

Although a generic reflected XSS scores in the Medium range, exploitation here requires the application developer to have written a non-idiomatic pattern — passing untrusted, request-derived input directly into a transition directive. Astro applications that do not route untrusted input into these directives are unaffected. This mitigating precondition places the real-world severity at Low.

Details

In generateHydrateScript() (packages/astro/src/runtime/server/hydration.ts), every island property is HTML-escaped before serialization — the attrs, props, and opts assignments all pass through escapeHTML(). The transition directives, however, were copied verbatim:

transitionDirectivesToCopyOnIsland.forEach((name) => {
  if (typeof props[name] !== 'undefined') {
    island.props[name] = props[name]; // not escaped
  }
});

The <astro-island> element is serialized via renderElement('astro-island', island, false) with shouldEscape=false, and toAttributeString() returns the value unchanged in that mode. As a result there is no downstream re-escaping, and the raw directive value reaches the HTML response. This is the same output sink previously addressed for slot names in GHSA-8hv8-536x-4wqp.

The affected directives are:

  • data-astro-transition-scope (transition:scope)
  • data-astro-transition-persist (transition:persist)
  • data-astro-transition-persist-props (transition:persist-props)

Note that transition:persist is typed boolean | string, so passing a string value is a supported use of the API.

Proof of Concept

A component that reflects a query parameter into a transition directive:

---
const persist = Astro.url.searchParams.get('persist') ?? 'default';
---
<Island client:load transition:persist={persist} />

Request:

https://example.com/?persist="><img src=x onerror=alert(document.domain)>

Rendered output (before the fix):

<astro-island  data-astro-transition-persist=""><img src=x onerror=alert(document.domain)>></astro-island>

The " closes the attribute and the injected <img onerror=…> executes in the victim's browser.

Impact

Reflected XSS. An attacker who can induce a victim to visit a crafted URL can execute arbitrary script in the victim's session on the origin, subject to the requirement that the target application reflects untrusted input into one of the affected transition directives.

Affected Versions

astro >= 3.10.0, < 7.0.4 (introduced in 3.10.0, PR #​7861).

Patched Versions

astro >= 7.0.4. Fixed in PR #​17212 by HTML-escaping transition directive values before they are rendered onto the island element.

Workarounds

Do not pass untrusted or request-derived input into transition:persist, transition:scope, or transition:persist-props. If such input is required, HTML-escape or strictly validate it before passing it to the directive. Upgrading to astro@7.0.4 or later removes the need for manual mitigation.

Credits

Reported by @​jlgore.

Severity

  • CVSS Score: 2.1 / 10 (Low)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Astro: XSS via unescaped spread attribute names in renderHTMLElement (incomplete fix for CVE-2026-54298)

CVE-2026-59729 / GHSA-f48w-9m4c-m7f5

More information

Details

Summary

The fix for CVE-2026-54298 (GHSA-jrpj-wcv7-9fh9) added an INVALID_ATTR_NAME_CHAR guard to addAttribute() so that spread-prop attribute names containing "' >/= or whitespace are dropped. A second attribute-rendering path, renderHTMLElement() in packages/astro/src/runtime/server/render/dom.ts, has its own inline attribute loop that does not go through addAttribute() and was not updated. It interpolates the attribute name unescaped and only escapes the value, so untrusted prop keys spread onto a native-HTMLElement-subclass component can still break out of the attribute context, resulting in XSS.

Details

renderHTMLElement builds attributes directly:

for (const attr in props) {
  attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`;
}

The attribute name (attr) is interpolated raw; only the value is escaped via toAttributeString. By contrast, the hardened addAttribute in util.ts rejects invalid names:

if (INVALID_ATTR_NAME_CHAR.test(key)) { return ''; } // /[\s"'>/=]/

renderHTMLElement is reached from component.ts when the component is a native HTMLElement subclass:

if (!renderer && typeof HTMLElement === 'function' && componentIsHTMLElement(Component)) {
  const output = await renderHTMLElement(result, Component, _props, slots);
}

where _props carries spread props verbatim.

Reachability

The branch only runs when typeof HTMLElement === 'function' at SSR time. In default Node SSR HTMLElement is undefined, so the branch is dead. It becomes reachable when the SSR runtime exposes a global HTMLElement (Deno, Bun with a DOM shim, or jsdom/happy-dom in Node) and a class extending HTMLElement is used directly as an Astro component that receives untrusted-keyed spread props.

Proof of Concept

Given malicious spread props:

const maliciousProps = {
  'onmouseover=alert(document.domain) x': 'y',
  'x><script>alert(1)</script>': 'z',
};
  • addAttribute (post-fix) → <my-el></my-el> (key stripped — safe)
  • renderHTMLElement<my-el onmouseover=alert(document.domain) x="y" x><script>alert(1)</script>="z"></my-el> (handler + <script> injected — XSS)

Equivalent Astro template, served by an SSR runtime that defines a global HTMLElement:

---
import MyElement from '../MyElement.js'; // class MyElement extends HTMLElement {}
const userInput = Astro.url.searchParams;  // untrusted keys
---
<MyElement {...Object.fromEntries(userInput)} />
Impact

Cross-site scripting (CWE-79) via attribute-name breakout — the same vulnerability class as CVE-2026-54298, in a code path its fix did not cover. An attacker who controls the keys of an object spread onto a native-HTMLElement-subclass component can inject arbitrary event-handler attributes or sibling elements (including <script>) into the SSR output. Reachability is constrained by the runtime and component preconditions described above.

Severity

  • CVSS Score: 5.1 / 10 (Medium)
  • Vector String: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

withastro/astro (astro)

v7.1.0

Compare Source

Minor Changes
  • #​17302 5f4dc03 Thanks @​astrobot-houston! - Adds a new deferRender option to the glob() content loader

    When set to true, renderable entries (such as Markdown) are not rendered during content sync. Instead, rendering is deferred until the entry is actually rendered in a page, using the same on-demand path that .mdx files already use.

    This reduces memory usage during astro build for large collections whose rendered output is much larger than the source — for example, Markdown that uses heavy rehype plugins like rehype-katex. Such builds could previously run out of memory while storing the eagerly-rendered HTML for every entry.

    // src/content.config.ts
    import { defineCollection } from 'astro:content';
    import { glob } from 'astro/loaders';
    
    const docs = defineCollection({
      loader: glob({ pattern: '**/*.md', base: 'src/content/docs', deferRender: true }),
    });

    By default deferRender is false, preserving the existing behavior of rendering entries eagerly during sync so their rendered HTML can be cached across builds.

  • #​17296 30698a2 Thanks @​ematipico! - Adds a new experimental collectionStorage option for controlling how the content layer persists its data store

    By default, Astro serializes the entire content layer data store to a single file (.astro/data-store.json). For very large content collections, this file can grow large enough to hit platform file-size limits.

    Set experimental.collectionStorage: 'chunked' to instead split the data store across many smaller, content-addressed files inside a .astro/data-store/ directory, described by a manifest:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      experimental: {
        collectionStorage: 'chunked',
      },
    });

    Because each part file is named by a hash of its contents, unchanged parts keep the same name across builds and are not rewritten, and identical parts are deduplicated. The default value is 'single-file', which preserves the current behavior.

  • #​17214 44c4989 Thanks @​ematipico! - Adds support for the more specific CSP directives script-src-elem, script-src-attr, style-src-elem, and style-src-attr through a new kind option.

    Previously, CSP was only scoped to generic script-src/style-src directives. Now each source or hash can be scoped to a narrower directive — for example, to allow inline style attributes (such as those from define:vars or Shiki) without loosening the policy for your <style> and <link> elements.

Scoping sources and hashes in your config

Each entry in resources and hashes can be an object with a kind property. Depending on whether you use scriptDirective or styleDirective, "element" targets script-src-elem or style-src-elem, "attribute" targets script-src-attr or style-src-attr, and "default" (the same as a bare string or hash) targets script-src or style-src.

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  security: {
    csp: {
      scriptDirective: {
        resources: [{ resource: 'https://cdn.example.com', kind: 'element' }],
      },
      styleDirective: {
        resources: [{ resource: "'unsafe-inline'", kind: 'attribute' }],
      },
    },
  },
});
Scoping at runtime

The same kind option is available on the runtime CSP API, where the existing methods now also accept an object:

ctx.csp.insertScriptResource({ resource: 'https://cdn.example.com', kind: 'element' });
ctx.csp.insertStyleResource({ resource: "'unsafe-inline'", kind: 'attribute' });
  • #​17258 84814d4 Thanks @​astrobot-houston! - Adds a new format() option to the paginate utility. The format() option is a function that accepts the current URL of the page, and returns a new URL.

    For example, when your host only supports URLs using the .html extension, you can use format() to add it to the generated URLs:

    ---
    export async function getStaticPaths({ paginate }) {
      // Load your data with fetch(), getCollection(), etc.
      const response = await fetch(`https://pokeapi.co/api/v2/pokemon?limit=150`);
      const result = await response.json();
      const allPokemon = result.results;
    
      // Return a paginated collection of paths for all items
      return paginate(allPokemon, {
        pageSize: 10,
        format: (url) => `${url}.html`,
      });
    }
    
    const { page } = Astro.props;
    ---
  • #​17331 7db6420 Thanks @​matthewp! - Adds a --ignore-lock flag to astro dev for starting a dev server without checking or writing the lock file, so it can run alongside an already-running dev server for the same project.

    The new instance is not tracked by astro dev stop, astro dev status, or astro dev logs. --ignore-lock cannot be combined with --background (or an auto-detected AI agent environment, which runs dev servers in the background automatically) or --force, since those rely on the lock file.

    astro dev --ignore-lock
  • #​17389 16de021 Thanks @​florian-lefebvre! - Allows passing URL entrypoints when configuring the logger

    Matching other APIs like session drivers or font providers, the logger entrypoint can now be a URL:

    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      logger: {
        entrypoint: new URL('./logger.js', import.meta.url),
      },
    });
Patch Changes
  • #​17332 4407483 Thanks @​astrobot-houston! - Fixes the JSON logger crashing with process is not defined in non-Node runtimes like Cloudflare's workerd. The JSON logger now uses console.log/console.error instead of process.stdout/process.stderr, matching the pattern already used by the console logger.

  • #​17391 186a1e7 Thanks @​florian-lefebvre! - Fixes a case where an integration could not update the logger with updateConfig()

  • #​17394 d9f99e1 Thanks @​matthewp! - Fixes element-specific CSP directives to preserve the existing behavior of configured script and style resources

  • #​17374 b2d1b3e Thanks @​astrobot-houston! - Fixes dev server returning 404 for ?url imported assets when accessed via browser navigation

  • #​17390 ed71eaf Thanks @​florian-lefebvre! - Removes an unused and undocumented generic from the AstroLoggerDestination type

  • #​17393 092da56 Thanks @​matthewp! - Hardens generated transition styles, development metadata, and server island URLs when embedding dynamic values

v7.0.9

Compare Source

Patch Changes
  • #​17286 a249317 Thanks @​astrobot-houston! - Fixes the first browser visit after astro dev starts triggering an immediate full page reload

  • #​17369 a94d4a5 Thanks @​adamchal! - Fixes an issue where a client island could permanently fail to hydrate if the first attempt to load its component failed. Islands now reliably recover from transient import failures, which previously did not work for React components during astro dev.

v7.0.8

Compare Source

Patch Changes

v7.0.7

Compare Source

Patch Changes
  • #​17318 23a4120 Thanks @​astrobot-houston! - Fixes CSS module scoped-name hash mismatch in astro dev when using vite.css.transformer: 'lightningcss' with content collections. Previously, a component importing a CSS module and rendered via content collection render() would get different class name hashes in the element and the injected <style> tag, causing styles not to apply.

  • #​17323 4298883 Thanks @​ematipico! - Fixes a dev server memory leak which caused Node.js to emit warnings in the console.

  • #​17323 4298883 Thanks @​ematipico! - Fixes a dev server crash when a .html or /index.html suffixed request (such as those netlify dev probes as pretty-URL fallbacks) matched a dynamic endpoint route, causing a TypeError: Missing parameter error

  • #​17325 cebc404 Thanks @​astrobot-houston! - Fixes a bug where CSS @import rules could end up mid-stylesheet after inline CSS chunks were merged during build, causing browsers to silently ignore them

  • #​17323 4298883 Thanks @​ematipico! - Fixes a build regression that could leave unresolved preload markers in inlined scripts with external dynamic imports

  • Updated dependencies [4298883, 4298883]:

v7.0.6

Compare Source

Patch Changes
  • #​17261 79aa99c Thanks @​astrobot-houston! - Fixes a false deprecation warning for markdown.gfm and markdown.smartypants when using the Container API

  • #​17247 f94280d Thanks @​chatman-media! - Fixes route generation throwing "Missing parameter" (or silently dropping the segment) when a dynamic param's value is 0. The generator used truthy checks instead of checking for undefined, so paginate(posts, { params: { categoryId: 0 } }) would crash even though 0 is a perfectly valid param value.

  • #​17278 6f11739 Thanks @​astrobot-houston! - Fixes missing CSS for virtual style modules (e.g., responsive image layout styles) in dev mode when JavaScript is disabled

  • #​17250 0b30b35 Thanks @​matthewp! - Fixes the security.checkOrigin check so it is applied consistently to Astro Actions and on-demand endpoints, regardless of how the request pipeline is composed. Previously, the origin check could be skipped in the composable astro/hono pipeline depending on the order of the middleware() primitive (or when it was omitted).

  • #​17274 8c3579b Thanks @​astrobot-houston! - Fixes missing render() type overload for live collection entries. Previously, calling render() on a LiveDataEntry produced a TypeScript error when using only live.config.ts without a content.config.ts.

  • #​17257 4208297 Thanks @​astrobot-houston! - Fixes astro check failing to find @astrojs/check and typescript when astro is installed in a directory outside the project tree (e.g. pnpm virtual store)

  • #​17272 b428648 Thanks @​matthewp! - Fixes island component paths so that extensionless imports (e.g. import { Counter } from '../components/Counter') resolve to the real file on disk, matching Vite's extension order and directory index resolution. This makes the include/exclude options of JSX renderer integrations (React, Preact, Solid) match components imported without a file extension, and removes the spurious React 19 "Invalid hook call" warning logged on every request in dev when include was set alongside another JSX renderer

  • #​17279 2aeaa44 Thanks @​astrobot-houston! - Fixes a bug where <Picture inferSize> with a remote image could fail with FailedToFetchRemoteImageDimensions when the image server rate-limits requests (e.g. HTTP 429). Remote dimensions are now resolved once per render instead of once per output format.

  • #​17251 5240e26 Thanks @​matthewp! - Hardens the handling of attribute rendering when using with custom elements.

  • #​17248 429bd62 Thanks @​astrobot-houston! - Fixes a crash when using Astro's getViteConfig with Vitest browser mode (e.g., Storybook vitest runner). Astro now skips dev server setup inside Vitest, preventing errors.

  • #​17260 14524c0 Thanks @​matthewp! - Fixes a regression where a <script> inside a component rendered through Astro.slots.render() was hoisted out of its original position instead of staying next to its component content

  • Updated dependencies [eb6f97e]:

v7.0.5

Compare Source

Patch Changes
  • #​17242 9c05ba4 Thanks @​matthewp! - Fixes an error that could occur after the dev server restarts when using an adapter such as @astrojs/cloudflare, where a request would fail with a 500 referencing a missing pre-bundled dependency:

    The file does not exist at "node_modules/.vite/deps_ssr/astro_compiler-runtime.js?v=6419660d" which is in the optimize deps directory. The dependency might be incompatible with the dep optimizer. Try adding it to `optimizeDeps.exclude`.
    
  • #​17202 c6d254d Thanks @​matthewp! - Refactors path alias resolution to use Vite's native tsconfigPaths option

    This is an internal change with no expected impact on user projects. Astro now defers tsconfig and jsconfig paths alias resolution to Vite, keeping a small fallback for a few CSS cases Vite does not yet handle.

  • #​17123 72e29bd Thanks @​martrapp! - Fixes an issue where the ClientRouter wipes head elements after page transitions if the <head> contains a server:defer component.

  • #​17232 257505e Thanks @​matthewp! - Fixes a bug where <style> tags from components such as a content collection's Content could be silently dropped from the output when an await appeared before the component in an .astro file's markup.

  • #​17193 a7352fd Thanks @​jan-kubica! - Fixes the background dev server failing to start when astro is hoisted outside the project's node_modules (for example bun workspaces). The background process is now spawned from Astro's own resolved location instead of a path assumed under the project root.

  • #​17255 581d171 Thanks @​astrobot-houston! - Fixes prefetch not working for links inside server:defer components

v7.0.4

Compare Source

Patch Changes
  • #​17212 7ba0bb1 Thanks @​matthewp! - Ensures transition directive values are HTML-escaped when rendered on hydrated islands

  • #​17224 dc5e52f Thanks @​astrobot-houston! - Fixes trailing slash handling for dynamic file endpoints in dev mode. Dynamic file endpoints (e.g., src/pages/api/[name].json.ts) with trailingSlash: "always" incorrectly required a trailing slash in dev mode, returning 404 for /api/bar.json and 200 for /api/bar.json/.

  • #​17067 23f9446 Thanks @​fkatsuhiro! - Fixed a bug where the development toolbar did not output a warning even though the implicit ARIA role and the manually specified role were duplicated.

  • #​17234 d5fbee8 Thanks @​ocavue! - Adds support for sharp v0.35. pnpm users no longer need to approve sharp's build script (see allowBuilds) when on v0.35.

  • #​17223 5970ef4 Thanks @​astrobot-houston! - Fixes getCollection() returning empty in dev mode for large content collections (500k+ entries)

  • #​17184 799e5cd Thanks @​Princesseuh! - Upgrades the Rust compiler to the latest, which fixes some bugs. Refer to its changelog for more information.

  • #​17208 da8b573 Thanks @​matthewp! - Hardens forwarded header handling so the internal request helper validates X-Forwarded-Host against security.allowedDomains before trusting X-Forwarded-For for clientAddress. Previously it only checked that the header was present, which was inconsistent with the public createRequest helper. This aligns both code paths; behavior is unchanged for correctly configured proxies.

v7.0.3

Compare Source

Patch Changes
  • #​17189 24d2c9e Thanks @​astrobot-houston! - Fixes a bug where an error thrown inside one route's getStaticPaths() would prevent other valid routes from being matched in dev mode

  • #​16932 8f4a3db Thanks @​fkatsuhiro! - Fixes HMR for action files during development. Editing files in src/actions/ now takes effect on the next request without requiring a dev server restart.

  • #​17087 fb0ab02 Thanks @​jp-knj! - Fixes localized custom error pages in i18n projects so routes like /pt/404 are used for missing localized pages and return the correct status code

v7.0.2

Compare Source

Patch Changes

v7.0.1

Compare Source

Patch Changes
  • #​17151 ccceda3 Thanks @​matthewp! - Fixes astro dev incorrectly starting in background mode for Warp terminal users. Hybrid environments like Warp are no longer treated as AI agents for auto-background detection.

  • #​17158 164df87 Thanks @​ematipico! - Fixes astro dev --background --host not listing the network addresses. The background server start output and astro dev status now show every exposed network URL, matching the foreground dev server.

  • #​17141 d785b9d Thanks @​astrobot-houston! - Fixes responsive image CSS overriding user styles defined inside CSS @layer blocks. The generated image styles are now wrapped in @layer astro.images, ensuring they have lower cascade priority than user-defined layers.

  • #​17150 1a61386 Thanks @​matthewp! - Fixes astro dev --background failing on Windows with "Failed to spawn background dev server process"

v7.0.0

Compare Source

Major Changes
  • #​15819 cafec4e Thanks @​delucis! - Upgrade to Vite v8

  • #​16965 57ead0d Thanks @​Princesseuh! - Makes 'jsx' the default value for compressHTML

    Astro now strips whitespace from your HTML using JSX rules by default, the same way frameworks like React do. Whitespace and line breaks around elements are removed, but meaningful whitespace within a single line — like a space between two inline elements — is preserved. To keep a space that would otherwise be removed, write it explicitly in your source, for example with {" "}.

    This can change rendered output where whitespace between inline elements was previously meaningful. To keep Astro's earlier behavior, set compressHTML: true for HTML-aware compression, or compressHTML: false to preserve all whitespace.

  • #​16610 c63e7e4 Thanks [@​matthewp](https://redir

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/npm-astro-vulnerability branch 2 times, most recently from 0f04c84 to aaf4e34 Compare July 17, 2026 10:55
@renovate
renovate Bot force-pushed the renovate/npm-astro-vulnerability branch from aaf4e34 to 4f58ac7 Compare July 20, 2026 19:45
@renovate
renovate Bot force-pushed the renovate/npm-astro-vulnerability branch from 4f58ac7 to bd7f2ce Compare July 21, 2026 10:45
@renovate renovate Bot changed the title chore(deps): update dependency astro to v6.4.6 [security] fix(deps): update dependency astro to v7 [security] Jul 21, 2026
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.

0 participants