github withastro/astro @astrojs/cloudflare@13.0.0

latest releases: @astrojs/netlify@6.6.5, @astrojs/node@9.5.5, @astrojs/internal-helpers@0.7.6...
5 hours ago

Major Changes

  • #14306 141c4a2 Thanks @ematipico! - Changes the API for creating a custom entrypoint, replacing the createExports() function with a direct export pattern.

    What should I do?

    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.

  • #15435 957b9fe Thanks @rururux! - Changes the default image service from compile to cloudflare-binding. Image services options that resulted in broken images in development due to Node JS incompatiblities have now been updated to use the noop passthrough image service in dev mode. - (Cloudflare v13 and Astro6 upgrade guidance)

  • #15400 41eb284 Thanks @florian-lefebvre! - Removes the workerEntryPoint option, which wasn't used anymore. Set the main field of your wrangler config instead

    See how to migrate

  • #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.

    New runtime

    Previously, Astro.locals.runtime provided access to Cloudflare-specific APIs. These APIs have now moved to align with Cloudflare's native patterns.

    What should I do?

    Update occurrences of Astro.locals.runtime:

    • Astro.locals.runtime.env → Import env from cloudflare:workers
    • Astro.locals.runtime.cf → Access via Astro.request.cf
    • Astro.locals.runtime.caches → Use the global caches object
    • Astro.locals.runtime (for ExecutionContext) → Use Astro.locals.cfContext

    Here's an example showing how to update your code:

    Before:

    ---
    const { env, cf, caches, ctx } = Astro.locals.runtime;
    const value = await env.MY_KV.get('key');
    const country = cf.country;
    await caches.default.put(request, response);
    ctx.waitUntil(promise);
    ---
    
    <h1>Country: {country}</h1>
    

    After:

    ---
    import { env } from 'cloudflare:workers';
    
    const value = await env.MY_KV.get('key');
    const country = Astro.request.cf.country;
    await caches.default.put(request, response);
    Astro.locals.cfContext.waitUntil(promise);
    ---
    
    <h1>Country: {country}</h1>
    
  • #15345 840fbf9 Thanks @matthewp! - Removes the cloudflareModules adapter option

    The cloudflareModules option has been removed because it is no longer necessary. Cloudflare natively supports importing .sql, .wasm, and other module types.

    What should I do?

    Remove the cloudflareModules option from your Cloudflare adapter configuration if you were using it:

    import cloudflare from '@astrojs/cloudflare';
    
    export default defineConfig({
      adapter: cloudflare({
    -   cloudflareModules: true
      })
    });
    
  • #14445 ecb0b98 Thanks @florian-lefebvre! - Astro v6.0 upgrades to Vite v7.0 as the development server and production bundler - (v6 upgrade guidance)

  • #15037 8641805 Thanks @matthewp! - Updates the Wrangler entrypoint

    Previously, the main field in wrangler.jsonc pointed to the built output, since Wrangler only ran in production after the build completed:

    {
      "main": "dist/_worker.js/index.js",
    }
    

    Now that Wrangler runs in both development (via workerd) and production, Astro provides a default entrypoint that works for both scenarios.

    What should I do?

    Update your wrangler.jsonc to use the new entrypoint:

    {
      "main": "@astrojs/cloudflare/entrypoints/server",
    }
    

    This single entrypoint handles both astro dev and production deployments.

  • #15480 e118214 Thanks @alexanderniebuhr! - Drops official support for Cloudflare Pages in favor of Cloudflare Workers

    The Astro Cloudflare adapter now only supports deployment to Cloudflare Workers by default in order to comply with Cloudflare's recommendations for new projects. If you are currently deploying to Cloudflare Pages, consider migrating to Workers by following the Cloudflare guide for an optimal experience and full feature support.

Minor Changes

  • #15435 957b9fe Thanks @rururux! - Adds support for configuring the image service as an object with separate build and runtime options

    It is now possible to set both a build-time and runtime service independently. Currently, 'compile' is the only available build time option. The supported runtime options are 'passthrough' (default) and 'cloudflare-binding':

    import { defineConfig } from 'astro/config';
    import cloudflare from '@astrojs/cloudflare';
    
    export default defineConfig({
      adapter: cloudflare({
        imageService: { build: 'compile', runtime: 'cloudflare-binding' },
      }),
    });
    

    See the Cloudflare adapter imageService docs for more information about configuring your image service.

  • #15077 a164c77 Thanks @matthewp! - Adds support for prerendering pages using the workerd runtime.

    The Cloudflare adapter now uses the new setPrerenderer() API to prerender pages via HTTP requests to a local preview server running workerd, instead of using Node.js. This ensures prerendered pages are built using the same runtime that serves them in production.

  • #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.

  • #15037 8641805 Thanks @matthewp! - The Wrangler configuration file is now optional. If you don't have custom Cloudflare bindings (KV, D1, Durable Objects, etc.), Astro will automatically generate a default configuration for you.

    What should I do?

    If your wrangler.jsonc only contains basic configuration like this:

    {
      "main": "@astrojs/cloudflare/entrypoints/server",
      "compatibility_date": "2026-01-28",
      "assets": {
        "directory": "./dist",
        "binding": "ASSETS",
      },
    }
    

    You can safely delete the file. Astro will handle this configuration automatically.

    You only need a wrangler config file if you're using:

    • KV namespaces
    • D1 databases
    • Durable Objects
    • R2 buckets
    • Environment variables
    • Custom compatibility flags
    • Other Cloudflare-specific features
  • #15006 f361730 Thanks @florian-lefebvre! - Adds new session driver object shape

    For greater flexibility and improved consistency with other Astro code, session drivers are now specified as an object:

    -import { defineConfig } from 'astro/config'
    +import { defineConfig, sessionDrivers } from 'astro/config'
    
    export default defineConfig({
      session: {
    -    driver: 'redis',
    -    options: {
    -      url: process.env.REDIS_URL
    -    },
    +    driver: sessionDrivers.redis({
    +      url: process.env.REDIS_URL
    +    }),
      }
    })
    

    Specifying the session driver as a string has been deprecated, but will continue to work until this feature is removed completely in a future major version. The object shape is the current recommended and documented way to configure a session driver.

  • #15556 8fb329b Thanks @florian-lefebvre! - Adds support for more @cloudflare/vite-plugin options

    The adapter now accepts the following options from Cloudflare's Vite plugin:

    • auxiliaryWorkers
    • configPath
    • inspectorPort
    • persistState
    • remoteBindings
    • experimental.headersAndRedirectsDevModeSupport

    For example, you can now set inspectorPort to provide a custom port for debugging your Workers:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    import cloudflare from '@astrojs/cloudflare';
    
    export default defineConfig({
      adapter: cloudflare({
        inspectorPort: 3456,
      }),
    });
    

Patch Changes

  • #15044 7cac71b Thanks @florian-lefebvre! - Removes an exposed internal API of the preview server

  • #15080 f67b738 Thanks @gameroman! - Updates wrangler dependency to be a peerDependency over a dependency

  • #15039 6cc96e7 Thanks @matthewp! - Fixes static content deployment by moving it to another folder, so Wrangler can tell the static and worker content apart

  • #15452 e1aa3f3 Thanks @matthewp! - Fixes server-side dependencies not being discovered ahead of time during development

    Previously, imports in .astro file frontmatter were not scanned by Vite's dependency optimizer, causing a "new dependencies optimized" message and page reload when the dependency was first encountered. Astro is now able to scan these dependencies ahead of time.

  • #15391 5d996cc Thanks @florian-lefebvre! - Fixes types of the handle() function exported from /handler, that could be incompatible with types generated by wrangler types

  • #15696 a9fd221 Thanks @Princesseuh! - Fixes duplicate logging showing up in some cases when prerendering pages

  • #15309 4b9c8b8 Thanks @ematipico! - Update the underneath @cloudflare/workers-types library to address a warning emitted by the package manager during the installation.

  • #15079 4463a55 Thanks @ascorbic! - Fixes auto-provisioning of default bindings (SESSION KV, IMAGES, and ASSETS). Default bindings are now correctly applied whether or not you have a wrangler.json file.
    Previously, these bindings were only added when no wrangler config file existed. Now they are added in both cases, unless you've already defined them yourself.

  • #15694 66449c9 Thanks @matthewp! - Fixes deployment of static sites with the Cloudflare adapter

    Fixes an issue with detecting and building fully static sites that caused deployment errors when using output: 'static' with the Cloudflare adapter

  • #15565 30cd6db Thanks @ematipico! - Fixes an issue where the use of the Code component would result in an unexpected error.

  • #15121 06261e0 Thanks @ematipico! - Fixes a bug where the Astro, with the Cloudflare integration, couldn't correctly serve certain routes in the development server.

  • #15026 90c608c Thanks @matthewp! - Improves prebundling of internal Astro modules

  • #15778 4ebc1e3 Thanks @ematipico! - Fixes an issue where the computed clientAddress was incorrect in cases of a Request header with multiple values. The clientAddress is now also validated to contain only characters valid in IP addresses, rejecting injection payloads.

  • #15669 d5a888b Thanks @florian-lefebvre! - Removes the cssesc dependency

    This CommonJS dependency could sometimes cause errors because Astro is ESM-only. It is now replaced with a built-in ESM-friendly implementation.

  • #15075 ee2c260 Thanks @matthewp! - Adds deprecation errors for Astro.locals.runtime properties to help migrate from Astro v5 to v6

    When accessing the removed Astro.locals.runtime properties on Cloudflare, developers now receive clear error messages explaining the migration path:

    • Astro.locals.runtime.env → Use import { env } from "cloudflare:workers"
    • Astro.locals.runtime.cf → Use Astro.request.cf
    • Astro.locals.runtime.caches → Use the global caches object
    • Astro.locals.runtime.ctx → Use Astro.locals.cfContext
  • #15336 9cce92e Thanks @ascorbic! - Fixes a dev server issue where framework components from linked packages would fail to load with a 504 error.

    This could occur when using client:only or other client directives with components from monorepo packages (linked via file: or workspace protocol). The first request would trigger Vite's dependency optimizer mid-request, causing concurrent client module requests to fail.

  • #15255 a66783a Thanks @florian-lefebvre! - Fixes a case where the types of handle() could mismatch with the ones from the user's project. They now rely on globals, that can be obtained by running wrangler types

  • #15045 31074fc Thanks @ematipico! - Fixes an issue where using the Vue integration with the Cloudflare adapter resulted in some runtime errors.

  • #15386 a0234a3 Thanks @OliverSpeir! - Updates astro add cloudflare to use the latest valid compatibility_date in the wrangler config, if available

  • #15432 e2ad69e Thanks @OliverSpeir! - Removes unnecessary warning about sharp from being printed at start of dev server and build

  • #15588 425ea16 Thanks @rururux! - Fixes an issue where esbuild would throw a "Top-level return cannot be used inside an ECMAScript module" error during dependency scanning in certain environments.

  • #15450 50c9129 Thanks @florian-lefebvre! - Fixes a case where build.serverEntry would not be respected when using the new Adapter API

  • #15030 b5aa52b Thanks @ematipico! - Fixed an issue where the feature experimental.chromeDevtoolsWorkspace wasn't supported by the new version of the adapter.

  • #15648 802426b Thanks @rururux! - Restore and fix <Code /> component functionality on Cloudflare Workers.

  • #15478 ee519e5 Thanks @matthewp! - Fixes fully static sites to not output server-side worker code. When all routes are prerendered, the _worker.js directory is now removed from the build output.

  • #15636 5ecd04c Thanks @florian-lefebvre! - Adds an error when running on Stackblitz, since workerd doesn't support it

  • #15269 6f82aae Thanks @ematipico! - Fixes a regression where build.serverEntry stopped working as expected.

  • #15798 05771cf Thanks @rururux! - Fixes a regression where using the adapter would throw an error when using an integration that uses JSX.

  • #15053 674b63f Thanks @matthewp! - Excludes astro:* and virtual:astro:* from client optimizeDeps in core. Needed for prefetch users since virtual modules are now in the dependency graph.

  • #15495 5b99e90 Thanks @leekeh! - Refactors to use middlewareMode adapter feature (set to classic)

  • Updated dependencies [4ebc1e3, 4e7f3e8, a164c77, cf6ea6b, a18d727, 240c317, 745e632]:

    • @astrojs/internal-helpers@0.8.0
    • @astrojs/underscore-redirects@1.0.0

Don't miss a new astro release

NewReleases is sending notifications on new releases.