#122684e9a3ac Thanks @ematipico! - The command astro add vercel now updates the configuration file differently, and adds @astrojs/vercel as module to import.
This is a breaking change because it requires the version 8.* of @astrojs/vercel.
#1223190ae100 Thanks @bluwy! - Updates the automatic charset=utf-8 behavior for Markdown pages, where instead of responding with charset=utf-8 in the Content-Type header, Astro will now automatically add the <meta charset="utf-8"> tag instead.
This behaviour only applies to Markdown pages (.md or similar Markdown files located within src/pages/) that do not use Astro’s special layout frontmatter property. It matches the rendering behaviour of other non-content pages, and retains the minimal boilerplate needed to write with non-ASCII characters when adding individual Markdown pages to your site.
If your Markdown pages use the layout frontmatter property, then HTML encoding will be handled by the designated layout component instead, and the <meta charset="utf-8"> tag will not be added to your page by default.
If you require charset=utf-8 to render your page correctly, make sure that your layout components contain the <meta charset="utf-8"> tag. You may need to add this if you have not already done so.
🍿 Minor Changes
#12243eb41d13 Thanks @florian-lefebvre! - Improves defineConfig type safety. TypeScript will now error if a group of related configuration options do not have consistent types. For example, you will now see an error if your language set for i18n.defaultLocale is not one of the supported locales specified in i18n.locales.
#1215093351bc Thanks @bluwy! - Adds support for passing values other than "production" or "development" to the --mode flag (e.g. "staging", "testing", or any custom value) to change the value of import.meta.env.MODE or the loaded .env file. This allows you take advantage of Vite’s mode feature.
Also adds a new --devOutput flag for astro build that will output a development-based build.
Note that changing the mode does not change the kind of code transform handled by Vite and Astro:
In astro dev, Astro will transform code with debug information.
In astro build, Astro will transform code with the most optimized output and removes debug information.
In astro build --devOutput (new flag), Astro will transform code with debug information like in astro dev.
This enables various usecases like:
Terminal window
# Run the dev server connected to a "staging" API
astrodev--modestaging
# Build a site that connects to a "staging" API
astrobuild--modestaging
# Build a site that connects to a "production" API with additional debug information
astrobuild--devOutput
# Build a site that connects to a "testing" API
astrobuild--modetesting
The different modes can be used to load different .env files, e.g. .env.staging or .env.production, which can be customized for each environment, for example with different API_URL environment variable values.
🐞 Patch Changes
#123027196c24 Thanks @ematipico! - Fixes an issue where the origin check middleware run for prendered pages
#12341c1786d6 Thanks @ematipico! - Fixes and issue where Astro.currentLocale always returned the default locale when consumed inside a server island.
#1227025192a0 Thanks @ematipico! - Fixes a bug where the params weren’t correctly computed when rendering URLs with non-English characters
#123389ca89b3 Thanks @situ2001! - Resets NODE_ENV to ensure install command run in dev mode
#122869d6bcdb Thanks @florian-lefebvre! - Fixes a case where a warning for experimental astro:env support would be shown when using an adapter but not actually using astro:env
Changes the default page rendering behavior of Astro components in containers, and adds a new option partial: false to render full Astro pages as before.
Previously, the Container API was rendering all Astro components as if they were full Astro pages containing <!DOCTYPE html> by default. This was not intended, and now by default, all components will render as page partials: only the contents of the components without a page shell.
To render the component as a full-fledged Astro page, pass a new option called partial: false to renderToString() and renderToResponse():
import { experimental_AstroContainer as AstroContainer } from'astro/container';
import Card from'../src/components/Card.astro';
constcontainer= AstroContainer.create();
await container.renderToString(Card); // the string will not contain `<!DOCTYPE html>`
await container.renderToString(Card, { partial: false }); // the string will contain `<!DOCTYPE html>`
#1216915fa9ba Thanks @ematipico! - Fixes a bug where configured redirects were incorrectly constructed when reading the file system.
This caused an issue where configuring a redirect in astro.config.mjs like { /old: /new }, failed to trigger the correct redirect in the dev server.
#1216915fa9ba Thanks @ematipico! - Fixes a bug where the dev server was not providing a consistent user experience for configured redirects.
With the fix, when you configure a redirect in astro.config.mjs like this { /old: "/new" }, the dev server return an HTML response that matches the one emitted by a static build.
#1222379ffa5d Thanks @ArmandPhilippot! - Fixes a false positive reported by the dev toolbar Audit app where a label was considered missing when associated with a button
The button element can be used with a label (e.g. to create a switch) and should not be reported as an accessibility issue when used as a child of a label.
#12199c351352 Thanks @ematipico! - Fixes a regression in the computation of Astro.currentLocale
#12222fb55695 Thanks @ematipico! - Fixes an issue where the edge middleware couldn’t correctly compute the client IP address when calling ctx.clientAddress()
Using document.scripts is unsafe because if the application has a name="scripts" this will shadow the built-in document.scripts. Fix is to use getElementsByTagName to ensure we’re only grabbing real scripts.
#121732d10de5 Thanks @ematipico! - Fixes a bug where Astro Actions couldn’t redirect to the correct pathname when there was a rewrite involved.
The following example configures Shiki to highlight cjs code blocks using the javascript syntax highlighter:
import { defineConfig } from'astro/config';
exportdefaultdefineConfig({
markdown: {
shikiConfig: {
langAlias: {
cjs: 'javascript',
},
},
},
});
Then in your Markdown, you can use the alias as the language for a code block for syntax highlighting:
```cjs
'use strict';
functioncommonJs() {
return'I am a commonjs file';
}
```
#119843ac2263 Thanks @chaegumi! - Adds a new build.concurreny configuration option to specify the number of pages to build in parallel
In most cases, you should not change the default value of 1.
Use this option only when other attempts to reduce the overall rendering time (e.g. batch or cache long running tasks like fetch calls or data access) are not possible or are insufficient.
Use this option only if the refactors are not possible. If the number is set too high, the page rendering may slow down due to insufficient memory resources and because JS is single-threaded.
[!WARNING]
This feature is stable and is not considered experimental. However, this feature is only intended to address difficult performance issues, and breaking changes may occur in a minor release to keep this option as performant as possible.
astro.config.mjs
import { defineConfig } from'astro';
exportdefaultdefineConfig({
build: {
concurrency: 2,
},
});
🐞 Patch Changes
#12160c6fd1df Thanks @louisescher! - Fixes a bug where astro.config.mts and astro.config.cts weren’t reloading the dev server upon modifications.
#12130e96bcae Thanks @thehansys! - Fixes a bug in the parsing of x-forwarded-\*Request headers, where multiple values assigned to those headers were not correctly parsed.
Now, headers like x-forwarded-proto: https,http are correctly parsed.
HTTP/2 doesn’t support status message, so setting this was logging a warning.
#12151bb6d37f Thanks @ematipico! - Fixes an issue where Astro.currentLocale wasn’t incorrectly computed when the defaultLocale belonged to a custom locale path.
#11979423dfc1 Thanks @bluwy! - Bumps vite dependency to v6.0.0-beta.2. The version is pinned and will be updated as new Vite versions publish to prevent unhandled breaking changes. For the full list of Vite-specific changes, see its changelog.
#12100abf9a89 Thanks @astrobot-houston! - Refactors legacy content and data collections to use the Content Layer API glob() loader for better performance and to support backwards compatibility. Also introduces the legacy.collections flag for projects that are unable to update to the new behavior immediately.
:warning: BREAKING CHANGE FOR LEGACY CONTENT COLLECTIONS :warning:
By default, collections that use the old types (content or data) and do not define a loader are now implemented under the hood using the Content Layer API’s built-in glob() loader, with extra backward-compatibility handling.
In order to achieve backwards compatibility with existing content collections, the following have been implemented:
a glob loader collection is defined, with patterns that match the previous handling (matches src/content/<collection name>/**/*.md and other content extensions depending on installed integrations, with underscore-prefixed files and folders ignored)
When used in the runtime, the entries have an ID based on the filename in the same format as legacy collections
A slug field is added with the same format as before
A render() method is added to the entry, so they can be called using entry.render()
getEntryBySlug is supported
In order to achieve backwards compatibility with existing data collections, the following have been implemented:
a glob loader collection is defined, with patterns that match the previous handling (matches src/content/<collection name>/**/*{.json,.yaml} and other data extensions, with underscore-prefixed files and folders ignored)
Entries have an ID that is not slugified
getDataEntryById is supported
While this backwards compatibility implementation is able to emulate most of the features of legacy collections, there are some differences and limitations that may cause breaking changes to existing collections:
In previous versions of Astro, collections would be generated for all folders in src/content/, even if they were not defined in src/content/config.ts. This behavior is now deprecated, and collections should always be defined in src/content/config.ts. For existing collections, these can just be empty declarations (e.g. const blog = defineCollection({})) and Astro will implicitly define your legacy collection for you in a way that is compatible with the new loading behavior.
The special layout field is not supported in Markdown collection entries. This property is intended only for standalone page files located in src/pages/ and not likely to be in your collection entries. However, if you were using this property, you must now create dynamic routes that include your page styling.
Sort order of generated collections is non-deterministic and platform-dependent. This means that if you are calling getCollection(), the order in which entries are returned may be different than before. If you need a specific order, you should sort the collection entries yourself.
image().refine() is not supported. If you need to validate the properties of an image you will need to do this at runtime in your page or component.
the key argument of getEntry(collection, key) is typed as string, rather than having types for every entry.
A new legacy configuration flag legacy.collections is added for users that want to keep their current legacy (content and data) collections behavior (available in Astro v2 - v4), or who are not yet ready to update their projects:
astro.config.mjs
import { defineConfig } from'astro/config';
exportdefaultdefineConfig({
legacy: {
collections: true,
},
});
When set, no changes to your existing collections are necessary, and the restrictions on storing both new and old collections continue to exist: legacy collections (only) must continue to remain in src/content/, while new collections using a loader from the Content Layer API are forbidden in that folder.
#120797febf1f Thanks @ematipico! - params passed in getStaticPaths are no longer automatically decoded.
[changed]: params aren’t decoded anymore.
In Astro v4.x, params in were automatically decoded using decodeURIComponent.
Astro v5.0 doesn’t automatically decode params in getStaticPaths anymore, so you’ll need to manually decode them yourself if needed
What should I do?
If you were relying on the automatic decode, you’ll need to manually decode it using decodeURI.
Note that the use of decodeURIComponent) is discouraged for getStaticPaths because it decodes more characters than it should, for example /, ?, # and more.
---
export function getStaticPaths() {
return [
{ params: { id: decodeURI("%5Bpage%5D") } },
{ params: { id: "%5Bpage%5D" } },
]
}
const { id } = Astro.params;
---
🐞 Patch Changes
#1212755e9cd8 Thanks @ascorbic! - Prevents Vite emitting an error when restarting itself
#1210542037f3 Thanks @ascorbic! - Returns custom statusText that has been set in a Response
#12109ea22558 Thanks @ematipico! - Fixes a regression that was introduced by an internal refactor of how the middleware is loaded by the Astro application. The regression was introduced by #11550.
When the edge middleware feature is opted in, Astro removes the middleware function from the SSR manifest, and this wasn’t taken into account during the refactor.
#12106d3a74da Thanks @ascorbic! - Handles case where an immutable Response object is returned from an endpoint
#12090d49a537 Thanks @markjaquith! - Server islands: changes the server island HTML placeholder comment so that it is much less likely to get removed by HTML minifiers.
#1204721b5e80 Thanks @rgodha24! - Adds a new optional parser property to the built-in file() loader for content collections to support additional file types such as toml and csv.
The file() loader now accepts a second argument that defines a parser function. This allows you to specify a custom parser (e.g. toml.parse or csv-parse) to create a collection from a file’s contents. The file() loader will automatically detect and parse JSON and YAML files (based on their file extension) with no need for a parser.
This works with any type of custom file formats including csv and toml. The following example defines a content collection dogs using a .toml file.
[[dogs]]
id = "..."
age = "..."
[[dogs]]
id = "..."
age = "..."
After importing TOML’s parser, you can load the dogs collection into your project by passing both a file path and parser to the file() loader.
The parser argument also allows you to load a single collection from a nested JSON document. For example, this JSON file contains multiple collections:
{ "dogs": [{}], "cats": [{}] }
You can seperate these collections by passing a custom parser to the file() loader like so:
#1207161d248e Thanks @Princesseuh! - astro add no longer automatically sets output: 'server'. Since the default value of output now allows for server-rendered pages, it no longer makes sense to default to full server builds when you add an adapter
#119630a1036e Thanks @florian-lefebvre! - Adds a new createCodegenDir() function to the astro:config:setup hook in the Integrations API
In 4.14, we introduced the injectTypes utility on the astro:config:done hook. It can create .d.ts files and make their types available to user’s projects automatically. Under the hood, it creates a file in <root>/.astro/integrations/<normalized_integration_name>.
While the .astro directory has always been the preferred place to write code generated files, it has also been prone to mistakes. For example, you can write a .astro/types.d.ts file, breaking Astro types. Or you can create a file that overrides a file created by another integration.
In this release, <root>/.astro/integrations/<normalized_integration_name> can now be retrieved in the astro:config:setup hook by calling createCodegenDir(). It allows you to have a dedicated folder, avoiding conflicts with another integration or Astro itself. This directory is created by calling this function so it’s safe to write files to it directly:
Astro Content Layer API independently solves some of the caching and performance issues with legacy content collections that this strategy attempted to address. This feature has been replaced with continued work on improvements to the content layer. If you were using this experimental feature, you must now remove the flag from your Astro config as it no longer exists:
export default defineConfig({
experimental: {
contentCollectionsCache: true
}
})
The cacheManifest boolean argument is no longer passed to the astro:build:done integration hook:
#1203010a756a Thanks @ascorbic! - Resolves image paths in content layer with initial slash as project-relative
When using the image() schema helper, previously paths with an initial slash were treated as public URLs. This was to match the behavior of markdown images. However this is a change from before, where paths with an initial slash were treated as project-relative. This change restores the previous behavior, so that paths with an initial slash are treated as project-relative.
#120345b3ddfa Thanks @ematipico! - Fixes an issue where the middleware wasn’t called when a project uses 404.astro.
#12042243ecb6 Thanks @ematipico! - Fixes a problem in the Container API, where a polyfill wasn’t correctly applied. This caused an issue in some environments where crypto isn’t supported.
#1203826ea5e8 Thanks @ascorbic! - Resolves image paths in content layer with initial slash as project-relative
When using the image() schema helper, previously paths with an initial slash were treated as public URLs. This was to match the behavior of markdown images. However this is a change from before, where paths with an initial slash were treated as project-relative. This change restores the previous behavior, so that paths with an initial slash are treated as project-relative.