+
+
+
+
+
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/client-load.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/client-load.astro
new file mode 100644
index 000000000..f24d216be
--- /dev/null
+++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/client-load.astro
@@ -0,0 +1,12 @@
+---
+import ClickToNavigate from "../components/ClickToNavigate.jsx"
+import { ViewTransitions } from "astro:transitions";
+---
+
+
+
+
+
+
+
+
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-one.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-one.astro
new file mode 100644
index 000000000..a331e52e2
--- /dev/null
+++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-one.astro
@@ -0,0 +1,6 @@
+---
+import ListenerLayout from '../components/listener-layout.astro';
+---
+
+ Go to listener two
+
diff --git a/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-two.astro b/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-two.astro
new file mode 100644
index 000000000..35191a333
--- /dev/null
+++ b/packages/astro/e2e/fixtures/view-transitions/src/pages/listener-two.astro
@@ -0,0 +1,6 @@
+---
+import ListenerLayout from '../components/listener-layout.astro';
+---
+
+ Go to listener one
+
diff --git a/packages/astro/e2e/view-transitions.test.js b/packages/astro/e2e/view-transitions.test.js
index 31e3128f5..559592fba 100644
--- a/packages/astro/e2e/view-transitions.test.js
+++ b/packages/astro/e2e/view-transitions.test.js
@@ -230,6 +230,28 @@ test.describe('View Transitions', () => {
await expect(h, 'imported CSS updated').toHaveCSS('background-color', 'rgba(0, 0, 0, 0)');
});
+ test('No page rendering during swap()', async ({ page, astro }) => {
+ let transitions = 0;
+ page.on('console', (msg) => {
+ if (msg.type() === 'info' && msg.text() === 'transitionstart') ++transitions;
+ });
+
+ // Go to page 1
+ await page.goto(astro.resolveUrl('/listener-one'));
+ let p = page.locator('#totwo');
+ await expect(p, 'should have content').toHaveText('Go to listener two');
+ // on load a CSS transition is started triggered by a class on the html element
+ expect(transitions).toEqual(1);
+
+ // go to page 2
+ await page.click('#totwo');
+ p = page.locator('#toone');
+ await expect(p, 'should have content').toHaveText('Go to listener one');
+ // swap() resets that class, the after-swap listener sets it again.
+ // the temporarily missing class must not trigger page rendering
+ expect(transitions).toEqual(1);
+ });
+
test('click hash links does not do navigation', async ({ page, astro }) => {
// Go to page 1
await page.goto(astro.resolveUrl('/one'));
@@ -648,7 +670,7 @@ test.describe('View Transitions', () => {
expect(loads.length, 'There should be 2 page loads').toEqual(2);
});
- test('client:only styles are retained on transition', async ({ page, astro }) => {
+ test.skip('client:only styles are retained on transition', async ({ page, astro }) => {
const totalExpectedStyles = 7;
// Go to page 1
@@ -731,6 +753,21 @@ test.describe('View Transitions', () => {
await expect(p, 'should have content').toHaveText('Page 1');
});
+ test('Use the client side router in framework components', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/client-load'));
+
+ // the button is set to naviagte() to /two
+ const button = page.locator('#react-client-load-navigate-button');
+
+ await expect(button, 'should have content').toHaveText('Navigate to `/two`');
+
+ await button.click();
+
+ const p = page.locator('#two');
+
+ await expect(p, 'should have content').toHaveText('Page 2');
+ });
+
test('body inline scripts do not re-execute on navigation', async ({ page, astro }) => {
const errors = [];
page.addListener('pageerror', (err) => {
diff --git a/packages/astro/package.json b/packages/astro/package.json
index f8bd8a7dc..fd09d9ef8 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -1,6 +1,6 @@
{
"name": "astro",
- "version": "3.2.3",
+ "version": "3.2.4",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
"type": "module",
"author": "withastro",
diff --git a/packages/astro/src/assets/internal.ts b/packages/astro/src/assets/internal.ts
index 9cb48f588..310b746a8 100644
--- a/packages/astro/src/assets/internal.ts
+++ b/packages/astro/src/assets/internal.ts
@@ -111,7 +111,7 @@ export async function getImage(
src: imageURL,
attributes:
service.getHTMLAttributes !== undefined
- ? service.getHTMLAttributes(validatedOptions, imageConfig)
+ ? await service.getHTMLAttributes(validatedOptions, imageConfig)
: {},
};
}
diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts
index afd63716b..b63f693aa 100644
--- a/packages/astro/src/cli/add/index.ts
+++ b/packages/astro/src/cli/add/index.ts
@@ -50,7 +50,7 @@ const ALIASES = new Map([
]);
const ASTRO_CONFIG_STUB = `import { defineConfig } from 'astro/config';\n\nexport default defineConfig({});`;
const TAILWIND_CONFIG_STUB = `/** @type {import('tailwindcss').Config} */
-module.exports = {
+export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
@@ -74,7 +74,6 @@ const OFFICIAL_ADAPTER_TO_IMPORT_MAP: Record = {
vercel: '@astrojs/vercel/serverless',
cloudflare: '@astrojs/cloudflare',
node: '@astrojs/node',
- deno: '@astrojs/deno',
};
// Users might lack access to the global npm registry, this function
@@ -160,7 +159,7 @@ export async function add(names: string[], { flags }: AddOptions) {
'./tailwind.config.mjs',
'./tailwind.config.js',
],
- defaultConfigFile: './tailwind.config.cjs',
+ defaultConfigFile: './tailwind.config.mjs',
defaultConfigContent: TAILWIND_CONFIG_STUB,
});
}
diff --git a/packages/astro/src/core/build/css-asset-name.ts b/packages/astro/src/core/build/css-asset-name.ts
index 6e9e2a1c2..29fc14294 100644
--- a/packages/astro/src/core/build/css-asset-name.ts
+++ b/packages/astro/src/core/build/css-asset-name.ts
@@ -1,4 +1,4 @@
-import type { GetModuleInfo } from 'rollup';
+import type { GetModuleInfo, ModuleInfo } from 'rollup';
import crypto from 'node:crypto';
import npath from 'node:path';
@@ -6,20 +6,29 @@ import type { AstroSettings } from '../../@types/astro.js';
import { viteID } from '../util.js';
import { getTopLevelPages } from './graph.js';
+// These pages could be used as base names for the chunk hashed name, but they are confusing
+// and should be avoided it possible
+const confusingBaseNames = ['404', '500'];
+
// The short name for when the hash can be included
// We could get rid of this and only use the createSlugger implementation, but this creates
// slightly prettier names.
export function shortHashedName(id: string, ctx: { getModuleInfo: GetModuleInfo }): string {
const parents = Array.from(getTopLevelPages(id, ctx));
- const firstParentId = parents[0]?.[0].id;
- const firstParentName = firstParentId ? npath.parse(firstParentId).name : 'index';
+ return createNameHash(
+ getFirstParentId(parents),
+ parents.map(([page]) => page.id)
+ );
+}
+export function createNameHash(baseId: string | undefined, hashIds: string[]): string {
+ const baseName = baseId ? prettifyBaseName(npath.parse(baseId).name) : 'index';
const hash = crypto.createHash('sha256');
- for (const [page] of parents) {
- hash.update(page.id, 'utf-8');
+ for (const id of hashIds) {
+ hash.update(id, 'utf-8');
}
const h = hash.digest('hex').slice(0, 8);
- const proposedName = firstParentName + '.' + h;
+ const proposedName = baseName + '.' + h;
return proposedName;
}
@@ -34,7 +43,7 @@ export function createSlugger(settings: AstroSettings) {
.map(([page]) => page.id)
.sort()
.join('-');
- const firstParentId = parents[0]?.[0].id || indexPage;
+ const firstParentId = getFirstParentId(parents) || indexPage;
// Use the last two segments, for ex /docs/index
let dir = firstParentId;
@@ -45,7 +54,7 @@ export function createSlugger(settings: AstroSettings) {
break;
}
- const name = npath.parse(npath.basename(dir)).name;
+ const name = prettifyBaseName(npath.parse(npath.basename(dir)).name);
key = key.length ? name + sep + key : name;
dir = npath.dirname(dir);
i++;
@@ -76,3 +85,32 @@ export function createSlugger(settings: AstroSettings) {
return name;
};
}
+
+/**
+ * Find the first parent id from `parents` where its name is not confusing.
+ * Returns undefined if there's no parents.
+ */
+function getFirstParentId(parents: [ModuleInfo, number, number][]) {
+ for (const parent of parents) {
+ const id = parent[0].id;
+ const baseName = npath.parse(id).name;
+ if (!confusingBaseNames.includes(baseName)) {
+ return id;
+ }
+ }
+ // If all parents are confusing, just use the first one. Or if there's no
+ // parents, this will return undefined.
+ return parents[0]?.[0].id;
+}
+
+const charsToReplaceRe = /[.\[\]]/g;
+const underscoresRe = /_+/g;
+/**
+ * Prettify base names so they're easier to read:
+ * - index -> index
+ * - [slug] -> _slug_
+ * - [...spread] -> _spread_
+ */
+function prettifyBaseName(str: string) {
+ return str.replace(charsToReplaceRe, '_').replace(underscoresRe, '_');
+}
diff --git a/packages/astro/src/core/build/plugins/plugin-css.ts b/packages/astro/src/core/build/plugins/plugin-css.ts
index 85652e13b..5e24f85d2 100644
--- a/packages/astro/src/core/build/plugins/plugin-css.ts
+++ b/packages/astro/src/core/build/plugins/plugin-css.ts
@@ -1,5 +1,3 @@
-import * as crypto from 'node:crypto';
-import * as npath from 'node:path';
import type { GetModuleInfo } from 'rollup';
import { type ResolvedConfig, type Plugin as VitePlugin } from 'vite';
import { isBuildableCSSRequest } from '../../../vite-plugin-astro-server/util.js';
@@ -93,7 +91,7 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
if (new URL(pageInfo.id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG)) {
// Split delayed assets to separate modules
// so they can be injected where needed
- const chunkId = createNameHash(id, [id]);
+ const chunkId = assetName.createNameHash(id, [id]);
internals.cssModuleToChunkIdMap.set(id, chunkId);
return chunkId;
}
@@ -272,17 +270,6 @@ function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[] {
/***** UTILITY FUNCTIONS *****/
-function createNameHash(baseId: string, hashIds: string[]): string {
- const baseName = baseId ? npath.parse(baseId).name : 'index';
- const hash = crypto.createHash('sha256');
- for (const id of hashIds) {
- hash.update(id, 'utf-8');
- }
- const h = hash.digest('hex').slice(0, 8);
- const proposedName = baseName + '.' + h;
- return proposedName;
-}
-
function* getParentClientOnlys(
id: string,
ctx: { getModuleInfo: GetModuleInfo },
diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts
index 09f42a9b5..4c8b71ba8 100644
--- a/packages/astro/src/runtime/server/hydration.ts
+++ b/packages/astro/src/runtime/server/hydration.ts
@@ -15,10 +15,13 @@ export interface HydrationMetadata {
componentExport: { value: string };
}
+type Props = Record;
+
interface ExtractedProps {
isPage: boolean;
hydration: HydrationMetadata | null;
- props: Record;
+ props: Props;
+ propsWithoutTransitionAttributes: Props;
}
const transitionDirectivesToCopyOnIsland = Object.freeze([
@@ -29,13 +32,14 @@ const transitionDirectivesToCopyOnIsland = Object.freeze([
// Used to extract the directives, aka `client:load` information about a component.
// Finds these special props and removes them from what gets passed into the component.
export function extractDirectives(
- inputProps: Record,
+ inputProps: Props,
clientDirectives: SSRResult['clientDirectives']
): ExtractedProps {
let extracted: ExtractedProps = {
isPage: false,
hydration: null,
props: {},
+ propsWithoutTransitionAttributes: {},
};
for (const [key, value] of Object.entries(inputProps)) {
if (key.startsWith('server:')) {
@@ -96,10 +100,14 @@ export function extractDirectives(
}
} else {
extracted.props[key] = value;
+ if (!transitionDirectivesToCopyOnIsland.includes(key)) {
+ extracted.propsWithoutTransitionAttributes[key] = value;
+ }
}
}
for (const sym of Object.getOwnPropertySymbols(inputProps)) {
extracted.props[sym] = inputProps[sym];
+ extracted.propsWithoutTransitionAttributes[sym] = inputProps[sym];
}
return extracted;
diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts
index 158a88a07..002f4ebaf 100644
--- a/packages/astro/src/runtime/server/render/component.ts
+++ b/packages/astro/src/runtime/server/render/component.ts
@@ -92,7 +92,10 @@ async function renderFrameworkComponent(
displayName,
};
- const { hydration, isPage, props } = extractDirectives(_props, clientDirectives);
+ const { hydration, isPage, props, propsWithoutTransitionAttributes } = extractDirectives(
+ _props,
+ clientDirectives
+ );
let html = '';
let attrs: Record | undefined = undefined;
@@ -217,7 +220,7 @@ async function renderFrameworkComponent(
({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call(
{ result },
Component,
- props,
+ propsWithoutTransitionAttributes,
children,
metadata
));
@@ -242,7 +245,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call(
{ result },
Component,
- props,
+ propsWithoutTransitionAttributes,
children,
metadata
));
diff --git a/packages/astro/src/transitions/router.ts b/packages/astro/src/transitions/router.ts
index 1049f92d1..c21392e3a 100644
--- a/packages/astro/src/transitions/router.ts
+++ b/packages/astro/src/transitions/router.ts
@@ -13,9 +13,14 @@ type Events = 'astro:page-load' | 'astro:after-swap';
// only update history entries that are managed by us
// leave other entries alone and do not accidently add state.
const persistState = (state: State) => history.state && history.replaceState(state, '');
-export const supportsViewTransitions = !!document.startViewTransition;
+
+const inBrowser = import.meta.env.SSR === false;
+
+export const supportsViewTransitions = inBrowser && !!document.startViewTransition;
+
export const transitionEnabledOnThisPage = () =>
- !!document.querySelector('[name="astro-view-transitions-enabled"]');
+ inBrowser && !!document.querySelector('[name="astro-view-transitions-enabled"]');
+
const samePage = (otherLocation: URL) =>
location.pathname === otherLocation.pathname && location.search === otherLocation.search;
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
@@ -40,26 +45,27 @@ const announce = () => {
60
);
};
+
const PERSIST_ATTR = 'data-astro-transition-persist';
-const parser = new DOMParser();
-// explained at its usage
-let noopEl: HTMLDivElement;
-if (import.meta.env.DEV) {
- noopEl = document.createElement('div');
-}
+
+let parser: DOMParser;
// The History API does not tell you if navigation is forward or back, so
// you can figure it using an index. On pushState the index is incremented so you
// can use that to determine popstate if going forward or back.
let currentHistoryIndex = 0;
-if (history.state) {
- // we reloaded a page with history state
- // (e.g. history navigation from non-transition page or browser reload)
- currentHistoryIndex = history.state.index;
- scrollTo({ left: history.state.scrollX, top: history.state.scrollY });
-} else if (transitionEnabledOnThisPage()) {
- history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, '');
+
+if (inBrowser) {
+ if (history.state) {
+ // we reloaded a page with history state
+ // (e.g. history navigation from non-transition page or browser reload)
+ currentHistoryIndex = history.state.index;
+ scrollTo({ left: history.state.scrollX, top: history.state.scrollY });
+ } else if (transitionEnabledOnThisPage()) {
+ history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, '');
+ }
}
+
const throttle = (cb: (...args: any[]) => any, delay: number) => {
let wait = false;
// During the waiting time additional events are lost.
@@ -151,18 +157,24 @@ function isInfinite(animation: Animation) {
const updateHistoryAndScrollPosition = (toLocation: URL, replace: boolean, intraPage: boolean) => {
const fresh = !samePage(toLocation);
+ let scrolledToTop = false;
if (toLocation.href !== location.href) {
if (replace) {
history.replaceState({ ...history.state }, '', toLocation.href);
} else {
history.replaceState({ ...history.state, intraPage }, '');
- history.pushState({ index: ++currentHistoryIndex, scrollX, scrollY }, '', toLocation.href);
+ history.pushState(
+ { index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
+ '',
+ toLocation.href
+ );
}
// now we are on the new page for non-history navigations!
// (with history navigation page change happens before popstate is fired)
// freshly loaded pages start from the top
if (fresh) {
scrollTo({ left: 0, top: 0, behavior: 'instant' });
+ scrolledToTop = true;
}
}
if (toLocation.hash) {
@@ -171,7 +183,9 @@ const updateHistoryAndScrollPosition = (toLocation: URL, replace: boolean, intra
// that won't reload the page but instead scroll to the fragment
location.href = toLocation.href;
} else {
- scrollTo({ left: 0, top: 0, behavior: 'instant' });
+ if (!scrolledToTop) {
+ scrollTo({ left: 0, top: 0, behavior: 'instant' });
+ }
}
};
@@ -198,22 +212,6 @@ async function updateDOM(
const href = el.getAttribute('href');
return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
}
- // What follows is a fix for an issue (#8472) with missing client:only styles after transition.
- // That problem exists only in dev mode where styles are injected into the page by Vite.
- // Returning a noop element ensures that the styles are not removed from the old document.
- // Guarding the code below with the dev mode check
- // allows tree shaking to remove this code in production.
- if (import.meta.env.DEV) {
- if (el.tagName === 'STYLE' && el.dataset.viteDevId) {
- const devId = el.dataset.viteDevId;
- // If this same style tag exists, remove it from the new page
- return (
- newDocument.querySelector(`style[data-vite-dev-id="${devId}"]`) ||
- // Otherwise, keep it anyways. This is client:only styles.
- noopEl
- );
- }
- }
return null;
};
@@ -349,6 +347,8 @@ async function transition(
toLocation = new URL(response.redirected);
}
+ parser ??= new DOMParser();
+
const newDocument = parser.parseFromString(response.html, response.mediaType);
// The next line might look like a hack,
// but it is actually necessary as noscript elements
@@ -385,7 +385,22 @@ async function transition(
}
}
+let navigateOnServerWarned = false;
+
export function navigate(href: string, options?: Options) {
+ if (inBrowser === false) {
+ if (!navigateOnServerWarned) {
+ // instantiate an error for the stacktrace to show to user.
+ const warning = new Error(
+ 'The view transtions client API was called during a server side render. This may be unintentional as the navigate() function is expected to be called in response to user interactions. Please make sure that your usage is correct.'
+ );
+ warning.name = 'Warning';
+ console.warn(warning);
+ navigateOnServerWarned = true;
+ }
+ return;
+ }
+
// not ours
if (!transitionEnabledOnThisPage()) {
location.href = href;
@@ -403,58 +418,61 @@ export function navigate(href: string, options?: Options) {
}
}
-if (supportsViewTransitions || getFallback() !== 'none') {
- addEventListener('popstate', (ev) => {
- if (!transitionEnabledOnThisPage() && ev.state) {
- // The current page doesn't have View Transitions enabled
- // but the page we navigate to does (because it set the state).
- // Do a full page refresh to reload the client-side router from the new page.
- // Scroll restauration will then happen during the reload when the router's code is re-executed
- if (history.scrollRestoration) {
- history.scrollRestoration = 'manual';
- }
- location.reload();
- return;
- }
-
- // History entries without state are created by the browser (e.g. for hash links)
- // Our view transition entries always have state.
- // Just ignore stateless entries.
- // The browser will handle navigation fine without our help
- if (ev.state === null) {
- if (history.scrollRestoration) {
- history.scrollRestoration = 'auto';
- }
- return;
- }
-
- // With the default "auto", the browser will jump to the old scroll position
- // before the ViewTransition is complete.
+function onPopState(ev: PopStateEvent) {
+ if (!transitionEnabledOnThisPage() && ev.state) {
+ // The current page doesn't have View Transitions enabled
+ // but the page we navigate to does (because it set the state).
+ // Do a full page refresh to reload the client-side router from the new page.
+ // Scroll restauration will then happen during the reload when the router's code is re-executed
if (history.scrollRestoration) {
history.scrollRestoration = 'manual';
}
+ location.reload();
+ return;
+ }
- const state: State = history.state;
- if (state.intraPage) {
- // this is non transition intra-page scrolling
- scrollTo(state.scrollX, state.scrollY);
- } else {
- const nextIndex = state.index;
- const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
- currentHistoryIndex = nextIndex;
- transition(direction, new URL(location.href), {}, state);
+ // History entries without state are created by the browser (e.g. for hash links)
+ // Our view transition entries always have state.
+ // Just ignore stateless entries.
+ // The browser will handle navigation fine without our help
+ if (ev.state === null) {
+ if (history.scrollRestoration) {
+ history.scrollRestoration = 'auto';
}
- });
+ return;
+ }
- addEventListener('load', onPageLoad);
- // There's not a good way to record scroll position before a back button.
- // So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
- const updateState = () => {
- persistState({ ...history.state, scrollX, scrollY });
- };
+ // With the default "auto", the browser will jump to the old scroll position
+ // before the ViewTransition is complete.
+ if (history.scrollRestoration) {
+ history.scrollRestoration = 'manual';
+ }
- if ('onscrollend' in window) addEventListener('scrollend', updateState);
- else addEventListener('scroll', throttle(updateState, 300));
-
- markScriptsExec();
+ const state: State = history.state;
+ if (state.intraPage) {
+ // this is non transition intra-page scrolling
+ scrollTo(state.scrollX, state.scrollY);
+ } else {
+ const nextIndex = state.index;
+ const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
+ currentHistoryIndex = nextIndex;
+ transition(direction, new URL(location.href), {}, state);
+ }
+}
+
+if (inBrowser) {
+ if (supportsViewTransitions || getFallback() !== 'none') {
+ addEventListener('popstate', onPopState);
+ addEventListener('load', onPageLoad);
+ // There's not a good way to record scroll position before a back button.
+ // So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
+ const updateState = () => {
+ persistState({ ...history.state, scrollX, scrollY });
+ };
+
+ if ('onscrollend' in window) addEventListener('scrollend', updateState);
+ else addEventListener('scroll', throttle(updateState, 300));
+
+ markScriptsExec();
+ }
}
diff --git a/packages/astro/test/fixtures/view-transitions/astro.config.mjs b/packages/astro/test/fixtures/view-transitions/astro.config.mjs
new file mode 100644
index 000000000..8a6f1951c
--- /dev/null
+++ b/packages/astro/test/fixtures/view-transitions/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import react from '@astrojs/react';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [react()],
+});
diff --git a/packages/astro/test/fixtures/view-transitions/package.json b/packages/astro/test/fixtures/view-transitions/package.json
index bc6790df4..41cee5081 100644
--- a/packages/astro/test/fixtures/view-transitions/package.json
+++ b/packages/astro/test/fixtures/view-transitions/package.json
@@ -3,6 +3,9 @@
"version": "0.0.0",
"private": true,
"dependencies": {
- "astro": "workspace:*"
+ "astro": "workspace:*",
+ "@astrojs/react": "workspace:*",
+ "react": "^18.1.0",
+ "react-dom": "^18.1.0"
}
}
diff --git a/packages/astro/test/fixtures/view-transitions/src/components/Island.css b/packages/astro/test/fixtures/view-transitions/src/components/Island.css
new file mode 100644
index 000000000..fb21044d7
--- /dev/null
+++ b/packages/astro/test/fixtures/view-transitions/src/components/Island.css
@@ -0,0 +1,11 @@
+.counter {
+ display: grid;
+ font-size: 2em;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ margin-top: 2em;
+ place-items: center;
+}
+
+.counter-message {
+ text-align: center;
+}
diff --git a/packages/astro/test/fixtures/view-transitions/src/components/Island.jsx b/packages/astro/test/fixtures/view-transitions/src/components/Island.jsx
new file mode 100644
index 000000000..cde384980
--- /dev/null
+++ b/packages/astro/test/fixtures/view-transitions/src/components/Island.jsx
@@ -0,0 +1,19 @@
+import React, { useState } from 'react';
+import './Island.css';
+
+export default function Counter({ children, count: initialCount, id }) {
+ const [count, setCount] = useState(initialCount);
+ const add = () => setCount((i) => i + 1);
+ const subtract = () => setCount((i) => i - 1);
+
+ return (
+ <>
+
+
+
{count}
+
+
+
{children}
+ >
+ );
+}
diff --git a/packages/astro/test/fixtures/view-transitions/src/pages/hasIsland.astro b/packages/astro/test/fixtures/view-transitions/src/pages/hasIsland.astro
new file mode 100644
index 000000000..378afb180
--- /dev/null
+++ b/packages/astro/test/fixtures/view-transitions/src/pages/hasIsland.astro
@@ -0,0 +1,10 @@
+---
+import Island from '../components/Island.jsx';
+---
+
+
+
+
+
+
+
diff --git a/packages/astro/test/view-transitions.test.js b/packages/astro/test/view-transitions.test.js
index 6d4d19cbb..008a6e09f 100644
--- a/packages/astro/test/view-transitions.test.js
+++ b/packages/astro/test/view-transitions.test.js
@@ -22,4 +22,14 @@ describe('View Transitions styles', () => {
expect($('head style')).to.have.a.lengthOf(3);
});
+
+ it('should not duplicate transition attributes on island contents', async () => {
+ let res = await fixture.fetch('/hasIsland');
+ let html = await res.text();
+ let $ = cheerio.load(html);
+ expect($('astro-island[data-astro-transition-persist]')).to.have.a.lengthOf(1);
+ expect(
+ $('astro-island[data-astro-transition-persist] > [data-astro-transition-persist]')
+ ).to.have.a.lengthOf(0);
+ });
});
diff --git a/packages/integrations/cloudflare/CHANGELOG.md b/packages/integrations/cloudflare/CHANGELOG.md
index 9dd7772cc..c17ebb2d3 100644
--- a/packages/integrations/cloudflare/CHANGELOG.md
+++ b/packages/integrations/cloudflare/CHANGELOG.md
@@ -1,5 +1,17 @@
# @astrojs/cloudflare
+## 7.5.2
+
+### Patch Changes
+
+- [#8766](https://github.com/withastro/astro/pull/8766) [`054c5c644`](https://github.com/withastro/astro/commit/054c5c6447d79dd4ea7ab6ce0f9ec836abebd211) Thanks [@jadbox](https://github.com/jadbox)! - Adds `cloudflare:sockets` compile support
+
+- [#8788](https://github.com/withastro/astro/pull/8788) [`0ab6bad7d`](https://github.com/withastro/astro/commit/0ab6bad7dffd413c975ab00e545f8bc150f6a92f) Thanks [@alexanderniebuhr](https://github.com/alexanderniebuhr)! - Adds support for `node:crypto`
+
+- Updated dependencies [[`160d1cd75`](https://github.com/withastro/astro/commit/160d1cd755e70af1d8ec294d01dd2cb32d60db50), [`30de32436`](https://github.com/withastro/astro/commit/30de324361bc261956eb9fc08fe60a82ff602a9b), [`c4a7ec425`](https://github.com/withastro/astro/commit/c4a7ec4255e7acb9555cb8bb74ea13c5fbb2ac17), [`c24f70d91`](https://github.com/withastro/astro/commit/c24f70d91601dd3a6b5a84f04d61824e775e9b44), [`93b092266`](https://github.com/withastro/astro/commit/93b092266febfad16a48575f8eee12d5910bf071), [`29cdfa024`](https://github.com/withastro/astro/commit/29cdfa024886dd581cb207586f7dfec6966bdd4e), [`eaed844ea`](https://github.com/withastro/astro/commit/eaed844ea8f2f52e0c9caa40bb3ec7377e10595f)]:
+ - astro@3.2.4
+ - @astrojs/underscore-redirects@0.3.1
+
## 7.5.1
### Patch Changes
diff --git a/packages/integrations/cloudflare/README.md b/packages/integrations/cloudflare/README.md
index 10a381a7b..7ca92152b 100644
--- a/packages/integrations/cloudflare/README.md
+++ b/packages/integrations/cloudflare/README.md
@@ -169,7 +169,7 @@ default: `false`
Whether or not to import `.wasm` files [directly as ES modules](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration) using the `.wasm?module` import syntax.
-Add `wasmModuleImports: true` to `astro.config.mjs` to enable this functionality in both the Cloudflare build and the Astro dev server. Read more about [using Wasm modules](#use-wasm-modules)
+Add `wasmModuleImports: true` to `astro.config.mjs` to enable this functionality in both the Cloudflare build and the Astro dev server. Read more about [using Wasm modules](#use-wasm-modules).
```diff lang="js"
// astro.config.mjs
@@ -221,7 +221,7 @@ Currently supported bindings:
- [Cloudflare Workers KV](https://developers.cloudflare.com/kv/)
- [Cloudflare Durable Objects](https://developers.cloudflare.com/durable-objects/)
-You can access the runtime from Astro components through `Astro.locals` inside any .astro` file.
+You can access the runtime from Astro components through `Astro.locals` inside any `.astro` file.
```astro
---
@@ -339,6 +339,7 @@ Astro's Cloudflare adapter allows you to use any Node.js runtime API supported b
- assert
- AsyncLocalStorage
- Buffer
+- Crypto
- Diagnostics Channel
- EventEmitter
- path
@@ -357,6 +358,10 @@ import { Buffer } from 'node:buffer';
Additionally, you'll need to enable the Compatibility Flag in Cloudflare. The configuration for this flag may vary based on where you deploy your Astro site. For detailed guidance, please refer to the [Cloudflare documentation on enabling Node.js compatibility](https://developers.cloudflare.com/workers/runtime-apis/nodejs).
+## Cloudflare module support
+
+All Cloudflare namespaced packages (e.g. `cloudflare:sockets`) are allowlisted for use. Note that the package `cloudflare:sockets` does not work locally without using Wrangler dev mode.
+
## Preview with Wrangler
To use [`wrangler`](https://developers.cloudflare.com/workers/wrangler/) to run your application locally, update the preview script:
diff --git a/packages/integrations/cloudflare/package.json b/packages/integrations/cloudflare/package.json
index b7ecc2c69..f9527bc76 100644
--- a/packages/integrations/cloudflare/package.json
+++ b/packages/integrations/cloudflare/package.json
@@ -1,7 +1,7 @@
{
"name": "@astrojs/cloudflare",
"description": "Deploy your site to Cloudflare Workers/Pages",
- "version": "7.5.1",
+ "version": "7.5.2",
"type": "module",
"types": "./dist/index.d.ts",
"author": "withastro",
@@ -48,7 +48,7 @@
"vite": "^4.4.9"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3"
+ "astro": "workspace:^3.2.4"
},
"devDependencies": {
"@types/iarna__toml": "^2.0.2",
diff --git a/packages/integrations/cloudflare/src/entrypoints/server.advanced.ts b/packages/integrations/cloudflare/src/entrypoints/server.advanced.ts
index 957c1791d..c7c8e8466 100644
--- a/packages/integrations/cloudflare/src/entrypoints/server.advanced.ts
+++ b/packages/integrations/cloudflare/src/entrypoints/server.advanced.ts
@@ -1,4 +1,8 @@
-import type { Request as CFRequest, ExecutionContext } from '@cloudflare/workers-types';
+import type {
+ Request as CFRequest,
+ CacheStorage,
+ ExecutionContext,
+} from '@cloudflare/workers-types';
import type { SSRManifest } from 'astro';
import { App } from 'astro/app';
import { getProcessEnvProxy, isNode } from '../util.js';
@@ -16,7 +20,7 @@ export interface AdvancedRuntime {
waitUntil: (promise: Promise) => void;
env: Env & T;
cf: CFRequest['cf'];
- caches: typeof caches;
+ caches: CacheStorage;
};
}
@@ -50,7 +54,7 @@ export function createExports(manifest: SSRManifest) {
},
env: env,
cf: request.cf,
- caches: caches,
+ caches: caches as unknown as CacheStorage,
},
};
diff --git a/packages/integrations/cloudflare/src/entrypoints/server.directory.ts b/packages/integrations/cloudflare/src/entrypoints/server.directory.ts
index 3542279b0..6f573fe71 100644
--- a/packages/integrations/cloudflare/src/entrypoints/server.directory.ts
+++ b/packages/integrations/cloudflare/src/entrypoints/server.directory.ts
@@ -1,4 +1,4 @@
-import type { Request as CFRequest, EventContext } from '@cloudflare/workers-types';
+import type { Request as CFRequest, CacheStorage, EventContext } from '@cloudflare/workers-types';
import type { SSRManifest } from 'astro';
import { App } from 'astro/app';
import { getProcessEnvProxy, isNode } from '../util.js';
@@ -6,13 +6,12 @@ import { getProcessEnvProxy, isNode } from '../util.js';
if (!isNode) {
process.env = getProcessEnvProxy();
}
-
export interface DirectoryRuntime {
runtime: {
waitUntil: (promise: Promise) => void;
env: EventContext['env'] & T;
cf: CFRequest['cf'];
- caches: typeof caches;
+ caches: CacheStorage;
};
}
@@ -48,7 +47,7 @@ export function createExports(manifest: SSRManifest) {
},
env: context.env,
cf: request.cf,
- caches: caches,
+ caches: caches as unknown as CacheStorage,
},
};
diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts
index 59cd92ce3..36da696bb 100644
--- a/packages/integrations/cloudflare/src/index.ts
+++ b/packages/integrations/cloudflare/src/index.ts
@@ -283,6 +283,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
'node:assert',
'node:async_hooks',
'node:buffer',
+ 'node:crypto',
'node:diagnostics_channel',
'node:events',
'node:path',
@@ -290,6 +291,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
'node:stream',
'node:string_decoder',
'node:util',
+ 'cloudflare:*',
],
entryPoints: pathsGroup,
outbase: absolutePagesDirname,
@@ -364,6 +366,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
'node:assert',
'node:async_hooks',
'node:buffer',
+ 'node:crypto',
'node:diagnostics_channel',
'node:events',
'node:path',
@@ -371,6 +374,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
'node:stream',
'node:string_decoder',
'node:util',
+ 'cloudflare:*',
],
entryPoints: [entryPath],
outfile: buildPath,
diff --git a/packages/integrations/markdoc/package.json b/packages/integrations/markdoc/package.json
index 440aa42c6..c317d369b 100644
--- a/packages/integrations/markdoc/package.json
+++ b/packages/integrations/markdoc/package.json
@@ -75,7 +75,7 @@
"zod": "3.21.1"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3"
+ "astro": "workspace:^3.2.4"
},
"devDependencies": {
"@astrojs/markdown-remark": "workspace:*",
diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json
index 2e90eda93..8192ad4c0 100644
--- a/packages/integrations/mdx/package.json
+++ b/packages/integrations/mdx/package.json
@@ -51,7 +51,7 @@
"vfile": "^5.3.7"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3"
+ "astro": "workspace:^3.2.4"
},
"devDependencies": {
"@types/chai": "^4.3.5",
diff --git a/packages/integrations/node/package.json b/packages/integrations/node/package.json
index 6b896706d..28cc2fe45 100644
--- a/packages/integrations/node/package.json
+++ b/packages/integrations/node/package.json
@@ -37,7 +37,7 @@
"server-destroy": "^1.0.1"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3"
+ "astro": "workspace:^3.2.4"
},
"devDependencies": {
"@types/node": "^18.17.8",
diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json
index 6efeca706..545bb666d 100644
--- a/packages/integrations/svelte/package.json
+++ b/packages/integrations/svelte/package.json
@@ -48,7 +48,7 @@
"vite": "^4.4.9"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3",
+ "astro": "workspace:^3.2.4",
"svelte": "^3.55.0 || ^4.0.0"
},
"engines": {
diff --git a/packages/integrations/tailwind/CHANGELOG.md b/packages/integrations/tailwind/CHANGELOG.md
index 6f4431c21..5810ea59b 100644
--- a/packages/integrations/tailwind/CHANGELOG.md
+++ b/packages/integrations/tailwind/CHANGELOG.md
@@ -1,5 +1,14 @@
# @astrojs/tailwind
+## 5.0.2
+
+### Patch Changes
+
+- [#8638](https://github.com/withastro/astro/pull/8638) [`160d1cd75`](https://github.com/withastro/astro/commit/160d1cd755e70af1d8ec294d01dd2cb32d60db50) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - The `@astrojs/tailwind` integration now creates a `tailwind.config.mjs` file by default
+
+- Updated dependencies [[`160d1cd75`](https://github.com/withastro/astro/commit/160d1cd755e70af1d8ec294d01dd2cb32d60db50), [`30de32436`](https://github.com/withastro/astro/commit/30de324361bc261956eb9fc08fe60a82ff602a9b), [`c4a7ec425`](https://github.com/withastro/astro/commit/c4a7ec4255e7acb9555cb8bb74ea13c5fbb2ac17), [`c24f70d91`](https://github.com/withastro/astro/commit/c24f70d91601dd3a6b5a84f04d61824e775e9b44), [`93b092266`](https://github.com/withastro/astro/commit/93b092266febfad16a48575f8eee12d5910bf071), [`29cdfa024`](https://github.com/withastro/astro/commit/29cdfa024886dd581cb207586f7dfec6966bdd4e), [`eaed844ea`](https://github.com/withastro/astro/commit/eaed844ea8f2f52e0c9caa40bb3ec7377e10595f)]:
+ - astro@3.2.4
+
## 5.0.1
### Patch Changes
diff --git a/packages/integrations/tailwind/README.md b/packages/integrations/tailwind/README.md
index ecbe37d1a..6cbfd7ada 100644
--- a/packages/integrations/tailwind/README.md
+++ b/packages/integrations/tailwind/README.md
@@ -94,7 +94,7 @@ https://user-images.githubusercontent.com/4033662/169918388-8ed153b2-0ba0-4b24-b
### Configuring Tailwind
-If you used the Quick Install instructions and said yes to each prompt, you'll see a `tailwind.config.cjs` file in your project's root directory. Use this file for your Tailwind configuration changes. You can learn how to customize Tailwind using this file [in the Tailwind docs](https://tailwindcss.com/docs/configuration).
+If you used the Quick Install instructions and said yes to each prompt, you'll see a `tailwind.config.mjs` file in your project's root directory. Use this file for your Tailwind configuration changes. You can learn how to customize Tailwind using this file [in the Tailwind docs](https://tailwindcss.com/docs/configuration).
If it isn't there, you add your own `tailwind.config.(js|cjs|mjs)` file to the root directory and the integration will use its configurations. This can be great if you already have Tailwind configured in another project and want to bring those settings over to this one.
@@ -178,8 +178,8 @@ error The `text-special` class does not exist. If `text-special` is a custom c
[Instead of using `@layer` directives in a global stylesheet](https://tailwindcss.com/docs/functions-and-directives#using-apply-with-per-component-css), define your custom styles by adding a plugin to your Tailwind config to fix it:
```js
-// tailwind.config.cjs
-module.exports = {
+// tailwind.config.mjs
+export default {
// ...
plugins: [
function ({ addComponents, theme }) {
diff --git a/packages/integrations/tailwind/package.json b/packages/integrations/tailwind/package.json
index 17bca109f..b4fce54af 100644
--- a/packages/integrations/tailwind/package.json
+++ b/packages/integrations/tailwind/package.json
@@ -1,7 +1,7 @@
{
"name": "@astrojs/tailwind",
"description": "Use Tailwind CSS to style your Astro site",
- "version": "5.0.1",
+ "version": "5.0.2",
"type": "module",
"types": "./dist/index.d.ts",
"author": "withastro",
@@ -43,7 +43,7 @@
"vite": "^4.4.9"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3",
+ "astro": "workspace:^3.2.4",
"tailwindcss": "^3.0.24"
},
"publishConfig": {
diff --git a/packages/integrations/tailwind/src/index.ts b/packages/integrations/tailwind/src/index.ts
index 700f16937..daee5f857 100644
--- a/packages/integrations/tailwind/src/index.ts
+++ b/packages/integrations/tailwind/src/index.ts
@@ -50,7 +50,7 @@ async function getViteConfiguration(
type TailwindOptions = {
/**
* Path to your tailwind config file
- * @default 'tailwind.config.js'
+ * @default 'tailwind.config.mjs'
*/
configFile?: string;
/**
diff --git a/packages/integrations/vercel/package.json b/packages/integrations/vercel/package.json
index b10ec83df..ecca04a1a 100644
--- a/packages/integrations/vercel/package.json
+++ b/packages/integrations/vercel/package.json
@@ -61,7 +61,7 @@
"web-vitals": "^3.4.0"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3"
+ "astro": "workspace:^3.2.4"
},
"devDependencies": {
"@types/set-cookie-parser": "^2.4.3",
diff --git a/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts b/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts
index f7cbe9c1d..f964fe0cf 100644
--- a/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts
+++ b/packages/integrations/vercel/test/hosted/hosted-astro-project/src/env.d.ts
@@ -1 +1 @@
-///
+///
diff --git a/packages/integrations/vue/package.json b/packages/integrations/vue/package.json
index f50cdd01d..496e38665 100644
--- a/packages/integrations/vue/package.json
+++ b/packages/integrations/vue/package.json
@@ -56,7 +56,7 @@
"vue": "^3.3.4"
},
"peerDependencies": {
- "astro": "workspace:^3.2.3",
+ "astro": "workspace:^3.2.4",
"vue": "^3.2.30"
},
"engines": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b3cd607a8..559cfeadf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -125,7 +125,7 @@ importers:
examples/basics:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/blog:
@@ -140,13 +140,13 @@ importers:
specifier: ^3.0.1
version: link:../../packages/integrations/sitemap
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/component:
devDependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/framework-alpine:
@@ -161,7 +161,7 @@ importers:
specifier: ^3.12.3
version: 3.12.3
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/framework-lit:
@@ -173,7 +173,7 @@ importers:
specifier: ^0.2.1
version: 0.2.1
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
lit:
specifier: ^2.8.0
@@ -197,7 +197,7 @@ importers:
specifier: ^3.0.1
version: link:../../packages/integrations/vue
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
preact:
specifier: ^10.17.1
@@ -227,7 +227,7 @@ importers:
specifier: ^1.2.1
version: 1.2.1(preact@10.17.1)
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
preact:
specifier: ^10.17.1
@@ -245,7 +245,7 @@ importers:
specifier: ^18.2.7
version: 18.2.7
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
react:
specifier: ^18.2.0
@@ -260,7 +260,7 @@ importers:
specifier: ^3.0.2
version: link:../../packages/integrations/solid
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
solid-js:
specifier: ^1.7.11
@@ -272,7 +272,7 @@ importers:
specifier: ^4.0.3
version: link:../../packages/integrations/svelte
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
svelte:
specifier: ^4.2.0
@@ -284,7 +284,7 @@ importers:
specifier: ^3.0.1
version: link:../../packages/integrations/vue
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
vue:
specifier: ^3.3.4
@@ -296,13 +296,13 @@ importers:
specifier: ^6.0.3
version: link:../../packages/integrations/node
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/integration:
devDependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/middleware:
@@ -311,7 +311,7 @@ importers:
specifier: ^6.0.3
version: link:../../packages/integrations/node
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
html-minifier:
specifier: ^4.0.0
@@ -320,19 +320,19 @@ importers:
examples/minimal:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/non-html-pages:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/portfolio:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/ssr:
@@ -344,7 +344,7 @@ importers:
specifier: ^4.0.3
version: link:../../packages/integrations/svelte
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
svelte:
specifier: ^4.2.0
@@ -356,10 +356,10 @@ importers:
specifier: ^6.0.3
version: link:../../packages/integrations/node
'@astrojs/tailwind':
- specifier: ^5.0.1
+ specifier: ^5.0.2
version: link:../../packages/integrations/tailwind
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/with-markdoc:
@@ -368,7 +368,7 @@ importers:
specifier: ^0.5.2
version: link:../../packages/integrations/markdoc
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/with-markdown-plugins:
@@ -377,7 +377,7 @@ importers:
specifier: ^3.2.1
version: link:../../packages/markdown/remark
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
hast-util-select:
specifier: ^5.0.5
@@ -398,7 +398,7 @@ importers:
examples/with-markdown-shiki:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
examples/with-mdx:
@@ -410,7 +410,7 @@ importers:
specifier: ^3.0.1
version: link:../../packages/integrations/preact
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
preact:
specifier: ^10.17.1
@@ -425,7 +425,7 @@ importers:
specifier: ^0.5.0
version: 0.5.0(nanostores@0.9.3)(preact@10.17.1)
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
nanostores:
specifier: ^0.9.3
@@ -440,13 +440,13 @@ importers:
specifier: ^1.1.1
version: link:../../packages/integrations/mdx
'@astrojs/tailwind':
- specifier: ^5.0.1
+ specifier: ^5.0.2
version: link:../../packages/integrations/tailwind
'@types/canvas-confetti':
specifier: ^1.6.0
version: 1.6.0
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
autoprefixer:
specifier: ^10.4.15
@@ -464,7 +464,7 @@ importers:
examples/with-vite-plugin-pwa:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
vite-plugin-pwa:
specifier: 0.16.4
@@ -476,7 +476,7 @@ importers:
examples/with-vitest:
dependencies:
astro:
- specifier: ^3.2.3
+ specifier: ^3.2.4
version: link:../../packages/astro
vitest:
specifier: ^0.34.2
@@ -3531,9 +3531,18 @@ importers:
packages/astro/test/fixtures/view-transitions:
dependencies:
+ '@astrojs/react':
+ specifier: workspace:*
+ version: link:../../../../integrations/react
astro:
specifier: workspace:*
version: link:../../..
+ react:
+ specifier: ^18.1.0
+ version: 18.2.0
+ react-dom:
+ specifier: ^18.1.0
+ version: 18.2.0(react@18.2.0)
packages/astro/test/fixtures/virtual-astro-file:
dependencies: