Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/early-times-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/cloudflare': patch
---

Fixes duplicate logging showing up in some cases when prerendering pages
5 changes: 5 additions & 0 deletions .changeset/long-bushes-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes images not working in MDX when using the Cloudflare adapter in certain cases
2 changes: 1 addition & 1 deletion packages/astro/src/assets/utils/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function getProxyCode(options: ImageMetadata, isSSR: boolean): string {
}
${
!isSSR
? `if (target[name] !== undefined && globalThis.astroAsset) globalThis.astroAsset?.referencedImages.add(${stringifiedFSPath});`
? `if (target[name] !== undefined && globalThis.astroAsset) globalThis.astroAsset?.referencedImages?.add(${stringifiedFSPath});`
: ''
}
return target[name];
Expand Down
21 changes: 17 additions & 4 deletions packages/astro/src/content/vite-plugin-content-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,19 @@ export function astroContentAssetPropagationPlugin({
},
},
configureServer(server) {
if (!isRunnableDevEnvironment(server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr])) {
return;
const ssrEnv = server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
if (isRunnableDevEnvironment(ssrEnv)) {
environment = ssrEnv;
} else if (
isRunnableDevEnvironment(server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.astro])
) {
// When the ssr environment is not a RunnableDevEnvironment (e.g. when using the
// Cloudflare adapter which runs ssr in workerd), fall back to the 'astro' environment
// which is always a RunnableDevEnvironment available in dev.
environment = server.environments[
ASTRO_VITE_ENVIRONMENT_NAMES.astro
] as RunnableDevEnvironment;
}
environment = server.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr] as RunnableDevEnvironment;
},
transform: {
filter: {
Expand All @@ -96,7 +105,11 @@ export function astroContentAssetPropagationPlugin({
// so resolve collected styles and scripts here.
if (isAstroServerEnvironment(this.environment) && environment) {
if (!environment.moduleGraph.getModuleById(basePath)?.ssrModule) {
await environment.runner.import(basePath);
// Ignore errors here — when using a fallback environment (e.g. the 'astro'
// env when Cloudflare's ssr env is non-runnable), the module may already be
// loaded in the fallback env's graph even if this import throws due to
// concurrent bundle editing.
await environment.runner.import(basePath).catch(() => {});
}
const {
styles,
Expand Down
1 change: 1 addition & 0 deletions packages/integrations/cloudflare/src/prerenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export function createCloudflarePrerenderer({
outDir: fileURLToPath(serverDir),
},
root: fileURLToPath(root),
logLevel: 'error',
preview: {
host: 'localhost',
port: 0, // Let the OS pick a free port
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import mdx from '@astrojs/mdx';
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
integrations: [mdx()],
vite: {
plugins: [tailwindcss()],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@astrojs/cloudflare": "workspace:*",
"@astrojs/mdx": "workspace:*",
"@tailwindcss/vite": "^4.2.0",
"astro": "workspace:*",
"tailwindcss": "^4.2.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
---

<div class="mdx-styled-card">
<slot />
</div>

<style>
.mdx-styled-card {
border: 2px solid rebeccapurple;
padding: 1rem;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';

const posts = defineCollection({
loader: glob({ pattern: '**/*.mdx', base: './src/content/posts' }),
schema: z.object({
title: z.string(),
}),
});

export const collections = { posts };
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: Styled Post
---

import StyledCard from '../../components/StyledCard.astro';

<StyledCard>Hello from MDX</StyledCard>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
import { getEntry, render } from 'astro:content';

export const prerender = true;

export async function getStaticPaths() {
const { getCollection } = await import('astro:content');
const posts = await getCollection('posts');
return posts.map((post) => ({
params: { slug: post.id },
props: { post },
}));
}

const { post } = Astro.props;
const { Content } = await render(post);
---

<html lang="en">
<head>
<meta charset="utf-8" />
<title>{post.data.title}</title>
</head>
<body>
<Content />
</body>
</html>
65 changes: 63 additions & 2 deletions packages/integrations/cloudflare/test/prerender-styles.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,69 @@ describe('Prerendered page styles', () => {
it('includes Tailwind styles in prerendered page', async () => {
// With cloudflare adapter, prerendered pages are in dist/client/
const html = await fixture.readFile('/client/index.html');
// Check that the bg-amber-500 class has its styles included
assert.ok(html.includes('.bg-amber-500'), 'Expected .bg-amber-500 class to be in the HTML');
// Tailwind CSS is emitted as an external stylesheet linked from the HTML.
// Verify the HTML references a stylesheet and that the stylesheet contains the expected class.
assert.ok(html.includes('rel="stylesheet"'), 'Expected the HTML to reference a stylesheet');
const cssFiles = await fixture.glob('client/_astro/*.css');
assert.ok(cssFiles.length > 0, 'Expected at least one CSS file in _astro/');
let foundClass = false;
for (const cssFile of cssFiles) {
const css = await fixture.readFile('/' + cssFile);
if (css.includes('.bg-amber-500')) {
foundClass = true;
break;
}
}
assert.ok(foundClass, 'Expected .bg-amber-500 class to be in a generated CSS file');
});
});
});

describe('Styles from Astro components imported in MDX content collections', () => {
/** @type {import('../../../astro/test/test-utils').Fixture} */
let fixture;
let devServer;

before(async () => {
fixture = await loadFixture({
root: new URL('./fixtures/prerender-styles/', import.meta.url).toString(),
adapter: cloudflare(),
});
});

after(async () => {
await devServer?.stop();
await fixture.clean();
});

describe('dev', () => {
before(async () => {
devServer = await fixture.startDevServer();
});

it('includes styles from an Astro component imported in an MDX content collection entry', async () => {
const res = await fixture.fetch('/posts/styled');
const html = await res.text();
assert.ok(
html.includes('.mdx-styled-card'),
'Expected .mdx-styled-card styles from StyledCard.astro to be injected in the MDX page',
);
});
});

describe('build', () => {
before(async () => {
await devServer?.stop();
devServer = undefined;
await fixture.build();
});

it('includes styles from an Astro component imported in an MDX content collection entry', async () => {
const html = await fixture.readFile('/client/posts/styled/index.html');
assert.ok(
html.includes('.mdx-styled-card'),
'Expected .mdx-styled-card styles from StyledCard.astro to be in the built MDX page',
);
});
});
});
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading