Releases: withastro/astro
[email protected]
Patch Changes
-
#11171
ff8004f
Thanks @Princesseuh! - Guard globalThis.astroAsset usage in proxy code to avoid errors in wonky situations -
#11178
1734c49
Thanks @theoephraim! - ImprovesisPromise
utility to check the presence ofthen
on an object before trying to access it - which can cause undesired side-effects on Proxy objects -
#11183
3cfa2ac
Thanks @66Leo66! - Suggestpnpm dlx
instead ofpnpx
in update check. -
#11147
2d93902
Thanks @kitschpatrol! - Fixes invalid MIME types in Picture source elements for jpg and svg extensions, which was preventing otherwise valid source variations from being shown by the browser -
#11141
19df89f
Thanks @ematipico! - Fixes an internal error that prevented theAstroContainer
to render theContent
component.You can now write code similar to the following to render content collections:
const entry = await getEntry(collection, slug); const { Content } = await entry.render(); const content = await container.renderToString(Content);
-
#11170
ba20c71
Thanks @matthewp! - Retain client scripts in content cache
@astrojs/[email protected]
Minor Changes
- #11164
cf9b2ff
Thanks @scottnath! - Removes deprecatedtemplate
attribute and replaces deprecated domparser function
[email protected]
Patch Changes
-
#11138
98e0372
Thanks @ematipico! - You can now passprops
when rendering a component using the Container APIs:import { experimental_AstroContainer as AstroContainer } from 'astro/contaienr'; import Card from '../src/components/Card.astro'; const container = await AstroContainer.create(); const result = await container.renderToString(Card, { props: { someState: true, }, });
@astrojs/[email protected]
Patch Changes
- #11139
aaf0635
Thanks @Princesseuh! - Fixes @astrojs/upgrade not using the package manager that was used to install the project to install dependencies
[email protected]
[email protected]
Minor Changes
-
#11051
12a1bcc
Thanks @ematipico! - Introduces an experimental Container API to render.astro
components in isolation.This API introduces three new functions to allow you to create a new container and render an Astro component returning either a string or a Response:
create()
: creates a new instance of the container.renderToString()
: renders a component and return a string.renderToResponse()
: renders a component and returns theResponse
emitted by the rendering phase.
The first supported use of this new API is to enable unit testing. For example, with
vitest
, you can create a container to render your component with test data and check the result:import { experimental_AstroContainer as AstroContainer } from 'astro/container'; import { expect, test } from 'vitest'; import Card from '../src/components/Card.astro'; test('Card with slots', async () => { const container = await AstroContainer.create(); const result = await container.renderToString(Card, { slots: { default: 'Card content', }, }); expect(result).toContain('This is a card'); expect(result).toContain('Card content'); });
For a complete reference, see the Container API docs.
For a feature overview, and to give feedback on this experimental API, see the Container API roadmap discussion.
-
#11021
2d4c8fa
Thanks @ematipico! - The CSRF protection feature that was introduced behind a flag in v4.6.0 is no longer experimental and is available for general use.To enable the stable version, add the new top-level
security
option inastro.config.mjs
. If you were previously using the experimental version of this feature, also delete the experimental flag:export default defineConfig({ - experimental: { - security: { - csrfProtection: { - origin: true - } - } - }, + security: { + checkOrigin: true + } })
Enabling this setting performs a check that the
"origin"
header, automatically passed by all modern browsers, matches the URL sent by each Request.This check is executed only for pages rendered on demand, and only for the requests
POST
,PATCH
,DELETE
andPUT
with one of the following"content-type"
headers:'application/x-www-form-urlencoded'
,'multipart/form-data'
,'text/plain'
.If the
"origin"
header doesn't match the pathname of the request, Astro will return a 403 status code and won't render the page.For more information, see the
security
configuration docs. -
#11022
be68ab4
Thanks @ematipico! - Thei18nDomains
routing feature introduced behind a flag in v3.4.0 is no longer experimental and is available for general use.This routing option allows you to configure different domains for individual locales in entirely server-rendered projects using the @astrojs/node or @astrojs/vercel adapter with a
site
configured.If you were using this feature, please remove the experimental flag from your Astro config:
import { defineConfig } from 'astro' export default defineConfig({ - experimental: { - i18nDomains: true, - } })
If you have been waiting for stabilization before using this routing option, you can now do so.
Please see the internationalization docs for more about this feature.
-
#11071
8ca7c73
Thanks @bholmesdev! - Adds two new functionsexperimental_getActionState()
andexperimental_withState()
to support the React 19useActionState()
hook when using Astro Actions. This introduces progressive enhancement when calling an Action with thewithState()
utility.This example calls a
like
action that accepts apostId
and returns the number of likes. Pass this action to theexperimental_withState()
function to apply progressive enhancement info, and apply touseActionState()
to track the result:import { actions } from 'astro:actions'; import { experimental_withState } from '@astrojs/react/actions'; export function Like({ postId }: { postId: string }) { const [state, action, pending] = useActionState( experimental_withState(actions.like), 0 // initial likes ); return ( <form action={action}> <input type="hidden" name="postId" value={postId} /> <button disabled={pending}>{state} ❤️</button> </form> ); }
You can also access the state stored by
useActionState()
from your actionhandler
. Callexperimental_getActionState()
with the API context, and optionally apply a type to the result:import { defineAction, z } from 'astro:actions'; import { experimental_getActionState } from '@astrojs/react/actions'; export const server = { like: defineAction({ input: z.object({ postId: z.string(), }), handler: async ({ postId }, ctx) => { const currentLikes = experimental_getActionState<number>(ctx); // write to database return currentLikes + 1; }, }), };
-
#11101
a6916e4
Thanks @linguofeng! - Updates Astro's code for adapters to use the headerx-forwarded-for
to initialize theclientAddress
.To take advantage of the new change, integration authors must upgrade the version of Astro in their adapter
peerDependencies
to4.9.0
. -
#11071
8ca7c73
Thanks @bholmesdev! - Adds compatibility for Astro Actions in the React 19 beta. Actions can be passed to aform action
prop directly, and Astro will automatically add metadata for progressive enhancement.import { actions } from 'astro:actions'; function Like() { return ( <form action={actions.like}> {/* auto-inserts hidden input for progressive enhancement */} <button type="submit">Like</button> </form> ); }
Patch Changes
-
#11088
9566fa0
Thanks @bholmesdev! - Allow actions to be called on the server. This allows you to call actions as utility functions in your Astro frontmatter, endpoints, and server-side UI components.Import and call directly from
astro:actions
as you would for client actions:--- // src/pages/blog/[postId].astro import { actions } from 'astro:actions'; await actions.like({ postId: Astro.params.postId }); ---
-
#11112
29a8650
Thanks @bholmesdev! - Deprecate thegetApiContext()
function. API Context can now be accessed from the second parameter to your Actionhandler()
:// src/actions/index.ts import { defineAction, z, - getApiContext, } from 'astro:actions'; export const server = { login: defineAction({ input: z.object({ id: z.string }), + handler(input, context) { const user = context.locals.auth(input.id); return user; } }), }
@astrojs/[email protected]
@astrojs/[email protected]
Minor Changes
-
#11055
b92de22
Thanks @niklas-wortmann! - Updates thedevtools
type to allow passingVueDevToolsOptions
For more customization, you can pass options that the Vue DevTools Vite Plugin supports. (Note:
appendTo
is not supported.) For example, you can setlaunchEditor
to your preferred editor if you are not using Visual Studio Code:import { defineConfig } from 'astro/config'; import vue from '@astrojs/vue'; export default defineConfig({ // ... integrations: [ vue({ devtools: { launchEditor: 'webstorm' }, }), ], });
@astrojs/[email protected]
Minor Changes
-
#11071
8ca7c73
Thanks @bholmesdev! - Adds two new functionsexperimental_getActionState()
andexperimental_withState()
to support the React 19useActionState()
hook when using Astro Actions. This introduces progressive enhancement when calling an Action with thewithState()
utility.This example calls a
like
action that accepts apostId
and returns the number of likes. Pass this action to theexperimental_withState()
function to apply progressive enhancement info, and apply touseActionState()
to track the result:import { actions } from 'astro:actions'; import { experimental_withState } from '@astrojs/react/actions'; export function Like({ postId }: { postId: string }) { const [state, action, pending] = useActionState( experimental_withState(actions.like), 0 // initial likes ); return ( <form action={action}> <input type="hidden" name="postId" value={postId} /> <button disabled={pending}>{state} ❤️</button> </form> ); }
You can also access the state stored by
useActionState()
from your actionhandler
. Callexperimental_getActionState()
with the API context, and optionally apply a type to the result:import { defineAction, z } from 'astro:actions'; import { experimental_getActionState } from '@astrojs/react/actions'; export const server = { like: defineAction({ input: z.object({ postId: z.string(), }), handler: async ({ postId }, ctx) => { const currentLikes = experimental_getActionState<number>(ctx); // write to database return currentLikes + 1; }, }), };
[email protected]
Patch Changes
-
#11073
f5c8fee
Thanks @matthewp! - Prevent cache content from being left in dist folderWhen
contentCollectionsCache
is enabled temporary cached content is copied into theoutDir
for processing. This fixes it so that this content is cleaned out, along with the rest of the temporary build JS. -
#11054
f6b171e
Thanks @bholmesdev! - Respect error status when handling Actions with a progressive fallback. -
#11092
bfe9c73
Thanks @duckycoding-dev! - Changeslot
attribute ofIntrinsicAttributes
to match the definition ofHTMLAttributes
's ownslot
attribute of typestring | undefined | null
-
#10875
b5f95b2
Thanks @W1M0R! - Fixes a typo in a JSDoc annotation -
#11111
a5d79dd
Thanks @bholmesdev! - Fix unexpectedheaders
warning on prerendered routes when using Astro Actions. -
#11081
af42e05
Thanks @V3RON! - Correctly position inspection tooltip in RTL modeWhen RTL mode is turned on, the inspection tooltip tend to overflow the window on the left side.
Additional check has been added to prevent that.