Skip to content

Releases: withastro/astro

@astrojs/cloudflare@13.0.0

10 Mar 09:49
48e5c4d

Choose a tag to compare

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 exac...

Read more

@astrojs/cloudflare@12.6.13

10 Mar 15:03
434d9cc

Choose a tag to compare

Patch Changes

  • Updated dependencies [c2cd371]:
    • @astrojs/internal-helpers@0.7.6
    • @astrojs/underscore-redirects@1.0.0

@astrojs/check@0.9.7

10 Mar 09:49
48e5c4d

Choose a tag to compare

Patch Changes

@astrojs/alpinejs@0.5.0

10 Mar 09:49
48e5c4d

Choose a tag to compare

Minor Changes

Patch Changes

astro@6.0.0-beta.20

06 Mar 18:09
25560db

Choose a tag to compare

astro@6.0.0-beta.20 Pre-release
Pre-release

Major Changes

Minor Changes

  • #15700 4e7f3e8 Thanks @ocavue! - Updates the internal logic during SSR by providing additional metadata for UI framework integrations.

  • #15781 2de969d Thanks @ematipico! - Adds a new clientAddress option to the createContext() function

    Providing this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing clientAddress throws an error consistent with other contexts where it is not set by the adapter.

    Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.

    import { createContext } from 'astro/middleware';
    
    createContext({
      clientAddress: context.headers.get('x-real-ip'),
    });
  • #15755 f9ee868 Thanks @matthewp! - Adds a new security.serverIslandBodySizeLimit configuration option

    Server island POST endpoints now enforce a body size limit, similar to the existing security.actionBodySizeLimit for Actions. The new option defaults to 1048576 (1 MB) and can be configured independently.

    Requests exceeding the limit are rejected with a 413 response. You can customize the limit in your Astro config:

    export default defineConfig({
      security: {
        serverIslandBodySizeLimit: 2097152, // 2 MB
      },
    });

Patch Changes

  • #15712 7ac43c7 Thanks @florian-lefebvre! - Improves astro info by supporting more operating systems when copying the information to the clipboard.

  • #15780 e0ac125 Thanks @ematipico! - Prevents vite.envPrefix misconfiguration from exposing access: "secret" environment variables in client-side bundles. Astro now throws a clear error at startup if any vite.envPrefix entry matches a variable declared with access: "secret" in env.schema.

    For example, the following configuration will throw an error for API_SECRET because it's defined as secret its name matches ['PUBLIC_', 'API_'] defined in env.schema:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      env: {
        schema: {
          API_SECRET: envField.string({ context: 'server', access: 'secret', optional: true }),
          API_URL: envField.string({ context: 'server', access: 'public', optional: true }),
        },
      },
      vite: {
        envPrefix: ['PUBLIC_', 'API_'],
      },
    });
  • #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.

  • #15776 e9a9cc6 Thanks @matthewp! - Hardens error page response merging to ensure framing headers from the original response are not carried over to the rendered error page

  • #15759 39ff2a5 Thanks @matthewp! - Adds a new bodySizeLimit option to the @astrojs/node adapter

    You can now configure a maximum allowed request body size for your Node.js standalone server. The default limit is 1 GB. Set the value in bytes, or pass 0 to disable the limit entirely:

    import node from '@astrojs/node';
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      adapter: node({
        mode: 'standalone',
        bodySizeLimit: 1024 * 1024 * 100, // 100 MB
      }),
    });
  • #15777 02e24d9 Thanks @matthewp! - Fixes CSRF origin check mismatch by passing the actual server listening port to createRequest, ensuring the constructed URL origin includes the correct port (e.g., http://localhost:4321 instead of http://localhost). Also restricts X-Forwarded-Proto to only be trusted when allowedDomains is configured.

  • #15768 6328f1a Thanks @matthewp! - Hardens internal cookie parsing to use a null-prototype object consistently for the fallback path, aligning with how the cookie library handles parsed values

  • #15757 631aaed Thanks @matthewp! - Hardens URL pathname normalization to consistently handle backslash characters after decoding, ensuring middleware and router see the same canonical pathname

  • #15761 8939751 Thanks @ematipico! - Fixes an issue where it wasn't possible to set experimental.queuedRendering.poolSize to 0.

  • #15764 44daecf Thanks @matthewp! - Fixes form actions incorrectly auto-executing during error page rendering. When an error page (e.g. 404) is rendered, form actions from the original request are no longer executed, since the full request handling pipeline is not active.

  • #15788 a91da9f Thanks @florian-lefebvre! - Reverts changes made to TSConfig templates

  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3
    • @astrojs/markdown-remark@7.0.0-beta.11

@astrojs/vercel@10.0.0-beta.8

06 Mar 18:09
25560db

Choose a tag to compare

Pre-release

Patch Changes

  • #15781 2de969d Thanks @ematipico! - Adds a new clientAddress option to the createContext() function

    Providing this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing clientAddress throws an error consistent with other contexts where it is not set by the adapter.

    Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.

    import { createContext } from 'astro/middleware';
    
    createContext({
      clientAddress: context.headers.get('x-real-ip'),
    });
  • #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.

  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3

@astrojs/react@5.0.0-beta.4

06 Mar 18:08
25560db

Choose a tag to compare

Pre-release

Patch Changes

  • #15700 4e7f3e8 Thanks @ocavue! - Improves how React components are identified when setting the include and/or exclude options in projects where multiple JSX frameworks are used together

  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3

@astrojs/preact@5.0.0-beta.5

06 Mar 18:08
25560db

Choose a tag to compare

Pre-release

Patch Changes

  • #15700 4e7f3e8 Thanks @ocavue! - Improves how Preact components are identified when setting the include and/or exclude options in projects where multiple JSX frameworks are used together

  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3

@astrojs/node@10.0.0-beta.9

06 Mar 18:09
25560db

Choose a tag to compare

Pre-release

Minor Changes

  • #15759 39ff2a5 Thanks @matthewp! - Adds a new bodySizeLimit option to the @astrojs/node adapter

    You can now configure a maximum allowed request body size for your Node.js standalone server. The default limit is 1 GB. Set the value in bytes, or pass 0 to disable the limit entirely:

    import node from '@astrojs/node';
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      adapter: node({
        mode: 'standalone',
        bodySizeLimit: 1024 * 1024 * 100, // 100 MB
      }),
    });

Patch Changes

  • #15777 02e24d9 Thanks @matthewp! - Fixes CSRF origin check mismatch by passing the actual server listening port to createRequest, ensuring the constructed URL origin includes the correct port (e.g., http://localhost:4321 instead of http://localhost). Also restricts X-Forwarded-Proto to only be trusted when allowedDomains is configured.

  • #15763 1567e8c Thanks @matthewp! - Normalizes static file paths before evaluating dotfile access rules for improved consistency

  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3

@astrojs/netlify@7.0.0-beta.14

06 Mar 18:09
25560db

Choose a tag to compare

Pre-release

Patch Changes

  • #15781 2de969d Thanks @ematipico! - Adds a new clientAddress option to the createContext() function

    Providing this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing clientAddress throws an error consistent with other contexts where it is not set by the adapter.

    Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.

    import { createContext } from 'astro/middleware';
    
    createContext({
      clientAddress: context.headers.get('x-real-ip'),
    });
  • Updated dependencies [4ebc1e3, 4e7f3e8]:

    • @astrojs/internal-helpers@0.8.0-beta.3
    • @astrojs/underscore-redirects@1.0.0