release notes
release notes
Published 12/12/2025
Contains breaking changes#14306 141c4a2 Thanks @ematipico! - Changes the API for creating a custom entrypoint, replacing the createExports() function with a direct export pattern.
If you're using a custom entryPoint in your Cloudflare adapter config, update your existing worker file that uses createExports() to reflect the new, simplified pattern:
my-entry.ts
import type { SSRManifest } from 'astro';
import { App } from 'astro/app';
import { handle } from '@astrojs/cloudflare/handler';
import { DurableObject } from 'cloudflare:workers';
class MyDurableObject extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
}
export function createExports(manifest: SSRManifest) {
const app = new App(manifest);
return {
default: {
async fetch(request, env, ctx) {
await env.MY_QUEUE.send('log');
return handle(manifest, app, request, env, ctx);
},
async queue(batch, _env) {
let messages = JSON.stringify(batch.messages);
console.log(`consumed from our queue: ${messages}`);
},
} satisfies ExportedHandler<Env>,
MyDurableObject: MyDurableObject,
};
}
To create the same custom entrypoint using the updated API, export the following function instead:
my-entry.ts
import { handle } from '@astrojs/cloudflare/utils/handler';
export default {
async fetch(request, env, ctx) {
await env.MY_QUEUE.send("log");
return handle(manifest, app, request, env, ctx);
},
async queue(batch, _env) {
let messages = JSON.stringify(batch.messages);
console.log(`consumed from our queue: ${messages}`);
}
} satisfies ExportedHandler<Env>,
The manifest is now created internally by the adapter.
#14306 141c4a2 Thanks @ematipico! - Development server now runs in workerd
astro dev now runs your Cloudflare application using Cloudflare's workerd runtime instead of Node.js. This means your development environment is now a near-exact replica of your production environment—the same JavaScript engine, the same APIs, the same behavior. You'll catch issues during development that would have only appeared in production, and features like Durable Objects, Workers Analytics Engine, and R2 bindings work exactly as they do on Cloudflare's platform.
To accommodate this major change to your development environment, this update includes breaking changes to Astro.locals.runtime, removing some of its properties.
Update occurrences of Astro.locals.runtime as shown below:
Astro.locals.runtime no longer contains the env object. Instead, import it directly:
import { env } from 'cloudflare:workers';
Astro.locals.runtime no longer contains the cf object. Instead, access it directly from the request:
Astro.request.cf;
Astro.locals.runtime no longer contains the caches object. Instead, use the global caches object directly:
caches.default.put(request, response);
Astro.locals.runtime object is replaced with Astro.locals.cfContext which contains the Cloudflare ExecutionContext:
const cfContext = Astro.locals.cfContext;
#14306 141c4a2 Thanks @ematipico! - Adds support for astro preview command
Developers can now use astro preview to test their Cloudflare Workers application locally before deploying. The preview runs using Cloudflare's workerd runtime, giving you a staging environment that matches production exactly—including support for KV namespaces, environment variables, and other Cloudflare-specific features.
release notes
Published 12/12/2025
Contains breaking changes#14306 141c4a2 Thanks @ematipico! - Changes the API for creating a custom entrypoint, replacing the createExports() function with a direct export pattern.
If you're using a custom entryPoint in your Cloudflare adapter config, update your existing worker file that uses createExports() to reflect the new, simplified pattern:
my-entry.ts
import type { SSRManifest } from 'astro';
import { App } from 'astro/app';
import { handle } from '@astrojs/cloudflare/handler';
import { DurableObject } from 'cloudflare:workers';
class MyDurableObject extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
}
}
export function createExports(manifest: SSRManifest) {
const app = new App(manifest);
return {
default: {
async fetch(request, env, ctx) {
await env.MY_QUEUE.send('log');
return handle(manifest, app, request, env, ctx);
},
async queue(batch, _env) {
let messages = JSON.stringify(batch.messages);
console.log(`consumed from our queue: ${messages}`);
},
} satisfies ExportedHandler<Env>,
MyDurableObject: MyDurableObject,
};
}
To create the same custom entrypoint using the updated API, export the following function instead:
my-entry.ts
import { handle } from '@astrojs/cloudflare/utils/handler';
export default {
async fetch(request, env, ctx) {
await env.MY_QUEUE.send("log");
return handle(manifest, app, request, env, ctx);
},
async queue(batch, _env) {
let messages = JSON.stringify(batch.messages);
console.log(`consumed from our queue: ${messages}`);
}
} satisfies ExportedHandler<Env>,
The manifest is now created internally by the adapter.
#14306 141c4a2 Thanks @ematipico! - Development server now runs in workerd
astro dev now runs your Cloudflare application using Cloudflare's workerd runtime instead of Node.js. This means your development environment is now a near-exact replica of your production environment—the same JavaScript engine, the same APIs, the same behavior. You'll catch issues during development that would have only appeared in production, and features like Durable Objects, Workers Analytics Engine, and R2 bindings work exactly as they do on Cloudflare's platform.
To accommodate this major change to your development environment, this update includes breaking changes to Astro.locals.runtime, removing some of its properties.
Update occurrences of Astro.locals.runtime as shown below:
Astro.locals.runtime no longer contains the env object. Instead, import it directly:
import { env } from 'cloudflare:workers';
Astro.locals.runtime no longer contains the cf object. Instead, access it directly from the request:
Astro.request.cf;
Astro.locals.runtime no longer contains the caches object. Instead, use the global caches object directly:
caches.default.put(request, response);
Astro.locals.runtime object is replaced with Astro.locals.cfContext which contains the Cloudflare ExecutionContext:
const cfContext = Astro.locals.cfContext;
#14306 141c4a2 Thanks @ematipico! - Adds support for astro preview command
Developers can now use astro preview to test their Cloudflare Workers application locally before deploying. The preview runs using Cloudflare's workerd runtime, giving you a staging environment that matches production exactly—including support for KV namespaces, environment variables, and other Cloudflare-specific features.
The web framework for content-driven websites. ⭐️ Star to support our work!