
🍿 Minor Changes
-
#17302
5f4dc03Thanks @astrobot-houston! - Adds a newdeferRenderoption to theglob()content loaderWhen 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.mdxfiles already use.This reduces memory usage during
astro buildfor large collections whose rendered output is much larger than the source — for example, Markdown that uses heavy rehype plugins likerehype-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
deferRenderisfalse, preserving the existing behavior of rendering entries eagerly during sync so their rendered HTML can be cached across builds. -
#17296
30698a2Thanks @ematipico! - Adds a new experimentalcollectionStorageoption for controlling how the content layer persists its data storeBy 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
44c4989Thanks @ematipico! - Adds support for the more specific CSP directivesscript-src-elem,script-src-attr,style-src-elem, andstyle-src-attrthrough a newkindoption.Previously,
CSPwas only scoped to genericscript-src/style-srcdirectives. Now each source or hash can be scoped to a narrower directive — for example, to allow inlinestyleattributes (such as those fromdefine:varsor Shiki) without loosening the policy for your<style>and<link>elements.Scoping sources and hashes in your config
Each entry in
resourcesandhashescan be an object with akindproperty. Depending on whether you usescriptDirectiveorstyleDirective,"element"targetsscript-src-elemorstyle-src-elem,"attribute"targetsscript-src-attrorstyle-src-attr, and"default"(the same as a bare string or hash) targetsscript-srcorstyle-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
kindoption 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
84814d4Thanks @astrobot-houston! - Adds a newformat()option to thepaginateutility. Theformat()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
.htmlextension, you can useformat()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 itemsreturn paginate(allPokemon, {pageSize: 10,format: (url) => `${url}.html`,});}const { page } = Astro.props;--- -
#17331
7db6420Thanks @matthewp! - Adds a--ignore-lockflag toastro devfor 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, orastro dev logs.--ignore-lockcannot 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.Terminal window astro dev --ignore-lock -
#17389
16de021Thanks @florian-lefebvre! - Allows passing URL entrypoints when configuring the loggerMatching 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
4407483Thanks @astrobot-houston! - Fixes the JSON logger crashing withprocess is not definedin non-Node runtimes like Cloudflare’s workerd. The JSON logger now usesconsole.log/console.errorinstead ofprocess.stdout/process.stderr, matching the pattern already used by the console logger. -
#17391
186a1e7Thanks @florian-lefebvre! - Fixes a case where an integration could not update the logger withupdateConfig() -
#17394
d9f99e1Thanks @matthewp! - Fixes element-specific CSP directives to preserve the existing behavior of configured script and style resources -
#17374
b2d1b3eThanks @astrobot-houston! - Fixes dev server returning 404 for?urlimported assets when accessed via browser navigation -
#17390
ed71eafThanks @florian-lefebvre! - Removes an unused and undocumented generic from theAstroLoggerDestinationtype -
#17393
092da56Thanks @matthewp! - Hardens generated transition styles, development metadata, and server island URLs when embedding dynamic values