Skip to content

AstroEco is Contributing…

Display your GitHub pull requests using astro-loader-github-prs

withastro/astro

Changes

A difference in the stack trace format was causing live collecitons to incorrectly complain that the colleciton was defined in the wrong file. Also in some cases such as when there's a space in the filename, the stack doesn't include the filename at all, giving another false error.

This PR loosens the check to make it more forgiving, and to not assume the worst if no filename can be found

Closes #13980

Testing

Tested manually

Docs

withastro/astro

Changes

This PR adds a small message that is shown in dev mode when users use CSP.

Testing

Docs

/cc @withastro/maintainers-docs for feedback!

I would appreciate some feedback around the nature of the message. I decided to use info severity. Should we use warning?

withastro/astro

Changes

  • Closes #13221
  • The dev toolbar relies on the data-image-component attribute for an audit
  • In content collections md/mdx files, images are not created using the <Image /> component so the attribute was not set in dev

Testing

Manually

Docs

Changeset

withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.10.1

Patch Changes

withastro/astro

Changes

  • Updates chanhelogs to avoid using h2/h3 headings inside changelog entries
  • This ensures headings are sequential and relate to the h2 and h3 headings added by changesets

Testing

n/a

Docs

Yup.

withastro/starlight

Description

Adds missing danish UI translations.

withastro/astro

Changes

  • Closes #13903
  • Instead of hardcoding what path to use, we grab the matched action filename and use directly

Testing

Manually

Docs

Changeset

withastro/astro

Changes

This PR implements static headers for the Node.js adapter. To support it, the adapter now creates a _headers.json file during the build, which has the following shape:

[
	{
		"source": "/blog/[...slug]", // it uses `RouteData.route`, which is a unique pattern
		"headers": [
			{
				"key": "Content-Security-Policy",
				"value": "script-src: ... "
			}
		]
	}
]

This file is read by the Node.js adapter when it starts the server, and its value is stored inside NodeApp class.

The inconvenient part is that both NodeApp and App belong to core, so any solution would force a minor into astro. Because of that, I decided to apply a more generic solution, because App has access to the manifest, which contains the list of routes. App.match doesn't return matched RouteData, but with a new, optional parameter, it's possible to return them.

The static handler of the Node.js adapter checks if a RouteData matches the request, and if there's a corresponding header, it's added to the final response!

Testing

Added new tests

Docs

Added two changesets:

  • one for the adapter
  • one for the internal changes in Astro (minor, unfortunately)
withastro/astro

Changes

Closes #13967

Just to go over my thought process:

  • The env-loader logic is used for both populating the astro:env virtual modules and import.meta.env.
  • We want variables imported via astro:env to still be converted into the expected type.
  • We want variables on import.meta.env to not be converted and should be set as-is (i.e. a string).
  • astro:env is entirely set up in vite-plugin-env.ts (?)
  • import.meta.env is entirely set up in vite-plugin-import-meta-env.ts (?)

I added a coerceValues argument to createEnvLoader and getPrivateEnv.

Then, in packages/astro/src/core/create-vite.ts, we create two separate envLoaders, one more astro:env and one for import.meta.env, where the the importMetaEnv plugin is passed an envLoader with coerceValues = false.

Alternate Solution

The above solution requires making two envLoaders.

As an alternative, we could attach a property to the object returned by createEnvLoader called something like getRawPrivateEnv which contains the original string values. We would use one envLoader and then in vite-plugin-import-meta-env.ts we usegetRawPrivateEnv instead of getPrivateEnv.

Testing

I tested with the examples/minimal project:

  • Add the following to index.astro:
     import { MY_VAR } from 'astro:env/client';
     console.log(`typeof: ${typeof import.meta.env.MY_VAR}`);
     console.log(`typeof: ${typeof MY_VAR}`);
  • Set up the astro.config:
     export default defineConfig({env: {
     	schema: {
     		MY_VAR: {
     			access: "public",
     			context: "client",
     			type: "boolean",
     			
     		}
     	}
     }});
  • Run MY_VAR=true pnpm --filter @example/minimal run build:
     typeof: string // from import.meta.env
     typeof: boolean // from astro:env
    

Docs

I don't think this needs doc changes.

withastro/astro

Changes

  • Fix SVG file-level duplication: Prevent identical SVG content from being physically stored multiple times on disk
  • Add content-based deduplication: Implement SHA256 content hashing to detect duplicate SVG files regardless of import path or filename
  • Use hard link optimization: Create hard links for duplicate content instead of separate physical files
  • Preserve existing behavior: Maintain all expected filenames and HTML references while optimizing storage

Before

Source files:     duplicate1.svg, duplicate2.svg (identical), unique.svg
Generated files:  4 separate physical SVG files in _astro/ directory
Storage impact:   100% overhead for duplicate content

After

Source files:     duplicate1.svg, duplicate2.svg (identical), unique.svg  
Generated files:  4 filenames → 2 physical files (hard linked)
Storage impact:   Optimal - duplicate content stored only once

Testing

  • Added comprehensive test suite (file-level-svg-deduplication.test.js) with 4 test cases:

    • Hard link verification: Validates that duplicate content uses hard links instead of separate files
    • Physical file count: Ensures only unique content creates physical files (2 inodes for 2 unique contents)
    • Filename preservation: Confirms all expected filenames exist and HTML references work correctly
    • Content validation: Verifies duplicate detection using SHA256 content hashing
  • Test results demonstrate optimization:

    • 4 filenames available → 2 physical files (inodes) → 2 hard link pairs
    • Storage reduction: ~50% for projects with duplicate SVG content
    • Zero breaking changes: All expected filenames and references preserved

Docs

No documentation changes needed - this is an internal build optimization that doesn't affect user-facing APIs or behavior.

  • Preserves all existing filenames: Each import still gets its expected filename reference
  • Maintains HTML output: Generated HTML references remain unchanged from user perspective
  • No breaking changes: Pure storage optimization with no API or behavior changes
  • Automatic performance improvement: Users benefit from reduced disk usage without code changes

Related Issues: Closes #13910

withastro/astro

Changes

Previously, it led to https://docs.astro.build/en/reference/configuration-reference/#trailingslash%22 (see the double quote at the end of the URL)

Docs

The 404 page template was fixed, there is no reason to touch the documentation.

withastro/astro

Changes

Very similar to #13952, it adds support for static headers in the Vercel adapter

Testing

Added a new test

Docs

The changeset is a copy-past from the netlify one, updated to use the vercel adapter.

/cc @withastro/maintainers-docs for feedback!

withastro/astro

Changes

Testing

Manually

Docs

Changeset

withastro/astro

Changes

This is my first ever change to astro. So I am not sure this is the correct way. Therefore a more thorough review may be required.

The PR aims to implement the experimental CSP policy to the cloudflare adapter.

Mainly copied work from: de82ef2

Testing

Added tests. Existing tests should still pass.

Validate CF docs if output matches.

Example output:

/has-header
  cdn-cache-control: public, max-age=3600
  Content-Security-Policy: script-src 'self' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-QzWFZi+FLIx23tnm9SBU4aEgx4x8DsuASP07mfqol/c=' 'sha256-0chmwFk0zaA528yFfGV7J9ppIpdfTPPULncDF3WG7Zs=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-Q2BPg90ZMplYY+FSdApNErhpWafg2hcRRbndmvxuL/Q=' 'sha256-0oe0j1+KVmVYcHm1N1/3tGTf3Yhpnd6heIyJsO4LZS0=' 'sha256-Yfb49Tdgb3WWkhZG+Levy7SSbIwvHj9bEqvunWdMcuU='; style-src 'self' 'sha256-2sYicASgHviyvFSsZfd8xuNIhA0b8XasqB2neZePwjs=';

/parent/*/page
  Content-Security-Policy: script-src 'self' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-QzWFZi+FLIx23tnm9SBU4aEgx4x8DsuASP07mfqol/c=' 'sha256-0chmwFk0zaA528yFfGV7J9ppIpdfTPPULncDF3WG7Zs=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-Q2BPg90ZMplYY+FSdApNErhpWafg2hcRRbndmvxuL/Q=' 'sha256-0oe0j1+KVmVYcHm1N1/3tGTf3Yhpnd6heIyJsO4LZS0=' 'sha256-ByjyHeCbp9JwIvEz5gjdoP7siW4JyclCitgVszsv3/A='; style-src 'self' 'sha256-2sYicASgHviyvFSsZfd8xuNIhA0b8XasqB2neZePwjs=';

/
  Content-Security-Policy: script-src 'self' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-QzWFZi+FLIx23tnm9SBU4aEgx4x8DsuASP07mfqol/c=' 'sha256-0chmwFk0zaA528yFfGV7J9ppIpdfTPPULncDF3WG7Zs=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-Q2BPg90ZMplYY+FSdApNErhpWafg2hcRRbndmvxuL/Q=' 'sha256-0oe0j1+KVmVYcHm1N1/3tGTf3Yhpnd6heIyJsO4LZS0=' 'sha256-v10nX5cSfrpnBaKOp54plCw0M1DSmiPyeQyg//eGOnA='; style-src 'self' 'sha256-2sYicASgHviyvFSsZfd8xuNIhA0b8XasqB2neZePwjs=';

/*
  Content-Security-Policy: script-src 'self' 'sha256-BF0290pkb3jxQsE7z00xR8Imp8X34FLC88L0lkMnrGw=' 'sha256-QzWFZi+FLIx23tnm9SBU4aEgx4x8DsuASP07mfqol/c=' 'sha256-0chmwFk0zaA528yFfGV7J9ppIpdfTPPULncDF3WG7Zs=' 'sha256-eIXWvAmxkr251LJZkjniEK5LcPF3NkapbJepohwYRIc=' 'sha256-Q2BPg90ZMplYY+FSdApNErhpWafg2hcRRbndmvxuL/Q=' 'sha256-0oe0j1+KVmVYcHm1N1/3tGTf3Yhpnd6heIyJsO4LZS0=' 'sha256-84Lsggi8q1VFTLi2blghehwqNiFOYysZSnNhkaidDMk='; style-src 'self' 'sha256-2sYicASgHviyvFSsZfd8xuNIhA0b8XasqB2neZePwjs=';

Docs

Docs needs to be added, todo based on feedback.

withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.10.0

Minor Changes

  • #13917 e615216 Thanks @ascorbic! - Adds a new priority attribute for Astro's image components.

    This change introduces a new priority option for the <Image /> and <Picture /> components, which automatically sets the loading, decoding, and fetchpriority attributes to their optimal values for above-the-fold images which should be loaded immediately.

    It is a boolean prop, and you can use the shorthand syntax by simply adding priority as a prop to the <Image /> or <Picture /> component. When set, it will apply the following attributes:

    • loading="eager"
    • decoding="sync"
    • fetchpriority="high"

    The individual attributes can still be set manually if you need to customize your images further.

    By default, the Astro <Image /> component generates <img> tags that lazy-load their content by setting loading="lazy" and decoding="async". This improves performance by deferring the loading of images that are not immediately visible in the viewport, and gives the best scores in performance audits like Lighthouse.

    The new priority attribute will override those defaults and automatically add the best settings for your high-priority assets.

    This option was previously available for experimental responsive images, but now it is a standard feature for all images.

    Usage

    <Image src="/path/to/image.jpg" alt="An example image" priority />

    [!Note]
    You should only use the priority option for images that are critical to the initial rendering of the page, and ideally only one image per page. This is often an image identified as the LCP element when running Lighthouse tests. Using it for too many images will lead to performance issues, as it forces the browser to load those images immediately, potentially blocking the rendering of other content.

  • #13917 e615216 Thanks @ascorbic! - The responsive images feature introduced behind a flag in v5.0.0 is no longer experimental and is available for general use.

    The new responsive images feature in Astro automatically generates optimized images for different screen sizes and resolutions, and applies the correct attributes to ensure that images are displayed correctly on all devices.

    Enable the image.responsiveStyles option in your Astro config. Then, set a layout attribute on any or component, or configure a default image.layout, for instantly responsive images with automatically generated srcset and sizes attributes based on the image's dimensions and the layout type.

    Displaying images correctly on the web can be challenging, and is one of the most common performance issues seen in sites. This new feature simplifies the most challenging part of the process: serving your site visitor an image optimized for their viewing experience, and for your website's performance.

    For full details, see the updated Image guide.

    Migration from Experimental Responsive Images

    The experimental.responsiveImages flag has been removed, and all experimental image configuration options have been renamed to their final names.

    If you were using the experimental responsive images feature, you'll need to update your configuration:

    Remove the experimental flag

    export default defineConfig({
       experimental: {
    -    responsiveImages: true,
       },
    });

    Update image configuration options

    During the experimental phase, default styles were applied automatically to responsive images. Now, you need to explicitly set the responsiveStyles option to true if you want these styles applied.

    export default defineConfig({
      image: {
    +    responsiveStyles: true,
      },
    });

    The experimental image configuration options have been renamed:

    Before:

    export default defineConfig({
      image: {
        experimentalLayout: 'constrained',
        experimentalObjectFit: 'cover',
        experimentalObjectPosition: 'center',
        experimentalBreakpoints: [640, 750, 828, 1080, 1280],
        experimentalDefaultStyles: true,
      },
      experimental: {
        responsiveImages: true,
      },
    });

    After:

    export default defineConfig({
      image: {
        layout: 'constrained',
        objectFit: 'cover',
        objectPosition: 'center',
        breakpoints: [640, 750, 828, 1080, 1280],
        responsiveStyles: true, // This is now *false* by default
      },
    });

    Component usage remains the same

    The layout, fit, and position props on <Image> and <Picture> components work exactly the same as before:

    <Image
      src={myImage}
      alt="A responsive image"
      layout="constrained"
      fit="cover"
      position="center"
    />

    If you weren't using the experimental responsive images feature, no changes are required.

    Please see the Image guide for more information on using responsive images in Astro.

  • #13685 3c04c1f Thanks @ascorbic! - Adds experimental support for live content collections

    Live content collections are a new type of content collection that fetch their data at runtime rather than build time. This allows you to access frequently-updated data from CMSs, APIs, databases, or other sources using a unified API, without needing to rebuild your site when the data changes.

    Live collections vs build-time collections

    In Astro 5.0, the content layer API added support for adding diverse content sources to content collections. You can create loaders that fetch data from any source at build time, and then access it inside a page via getEntry() and getCollection(). The data is cached between builds, giving fast access and updates.

    However there is no method for updating the data store between builds, meaning any updates to the data need a full site deploy, even if the pages are rendered on-demand. This means that content collections are not suitable for pages that update frequently. Instead, today these pages tend to access the APIs directly in the frontmatter. This works, but leads to a lot of boilerplate, and means users don't benefit from the simple, unified API that content loaders offer. In most cases users tend to individually create loader libraries that they share between pages.

    Live content collections solve this problem by allowing you to create loaders that fetch data at runtime, rather than build time. This means that the data is always up-to-date, without needing to rebuild the site.

    How to use

    To enable live collections add the experimental.liveContentCollections flag to your astro.config.mjs file:

    {
      experimental: {
        liveContentCollections: true,
      },
    }

    Then create a new src/live.config.ts file (alongside your src/content.config.ts if you have one) to define your live collections with a live loader and optionally a schema using the new defineLiveCollection() function from the astro:content module.

    import { defineLiveCollection } from 'astro:content';
    import { storeLoader } from '@mystore/astro-loader';
    
    const products = defineLiveCollection({
      type: 'live',
      loader: storeLoader({
        apiKey: process.env.STORE_API_KEY,
        endpoint: 'https://api.mystore.com/v1',
      }),
    });
    
    export const collections = { products };

    You can then use the dedicated getLiveCollection() and getLiveEntry() functions to access your live data:

    ---
    import { getLiveCollection, getLiveEntry, render } from 'astro:content';
    
    // Get all products
    const { entries: allProducts, error } = await getLiveCollection('products');
    if (error) {
      // Handle error appropriately
      console.error(error.message);
    }
    
    // Get products with a filter (if supported by your loader)
    const { entries: electronics } = await getLiveCollection('products', { category: 'electronics' });
    
    // Get a single product by ID (string syntax)
    const { entry: product, error: productError } = await getLiveEntry('products', Astro.params.id);
    if (productError) {
      return Astro.redirect('/404');
    }
    
    // Get a single product with a custom query (if supported by your loader) using a filter object
    const { entry: productBySlug } = await getLiveEntry('products', { slug: Astro.params.slug });
    
    const { Content } = await render(product);
    ---
    
    <h1>{product.title}</h1>
    <Content />

    See the docs for the experimental live content collections feature for more details on how to use this feature, including how to create a live loader. Please give feedback on the RFC PR if you have any suggestions or issues.

Patch Changes

  • #13957 304df34 Thanks @ematipico! - Fixes an issue where report-uri wasn't available in experimental.csp.directives, causing a typing error and a runtime validation error.

  • #13957 304df34 Thanks @ematipico! - Fixes a type error for the CSP directives upgrade-insecure-requests, sandbox, and trusted-type.

  • #13862 fe8f61a Thanks @florian-lefebvre! - Fixes a case where the dev toolbar would crash if it could not retrieve some essential data

  • #13976 0a31d99 Thanks @florian-lefebvre! - Fixes a case where Astro Actions types would be broken when using a tsconfig.json with "moduleResolution": "nodenext"

@astrojs/cloudflare@12.6.0

Minor Changes

  • #13837 7cef86f Thanks @alexanderniebuhr! - Adds new configuration options to allow you to set a custom workerEntryPoint for Cloudflare Workers. This is useful if you want to use features that require handlers (e.g. Durable Objects, Cloudflare Queues, Scheduled Invocations) not supported by the basic generic entry file.

    This feature is not supported when running the Astro dev server. However, you can run astro build followed by either wrangler deploy (to deploy it) or wrangler dev to preview it.

    The following example configures a custom entry file that registers a Durable Object and a queue handler:

    // astro.config.ts
    import cloudflare from '@astrojs/cloudflare';
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      adapter: cloudflare({
        workerEntryPoint: {
          path: 'src/worker.ts',
          namedExports: ['MyDurableObject'],
        },
      }),
    });
    // src/worker.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,
      };
    }

Patch Changes

  • #13963 c667c55 Thanks @florian-lefebvre! - Fixes a case where the platform proxy would not be disposed when the dev process ended

  • Updated dependencies []:

    • @astrojs/underscore-redirects@1.0.0

@astrojs/vercel@8.2.0

Minor Changes

  • #13965 95ece06 Thanks @ematipico! - Adds support for the experimental static headers Astro feature.

    When the feature is enabled via option experimentalStaticHeaders, and experimental Content Security Policy is enabled, the adapter will generate Response headers for static pages, which allows support for CSP directives that are not supported inside a <meta> tag (e.g. frame-ancestors).

    import { defineConfig } from 'astro/config';
    import vercel from '@astrojs/vercel';
    
    export default defineConfig({
      adapter: vercel({
        experimentalStaticHeaders: true,
      }),
      experimental: {
        cps: true,
      },
    });

Patch Changes

  • #13917 e615216 Thanks @ascorbic! - The responsive images feature introduced behind a flag in v5.0.0 is no longer experimental and is available for general use.

    The new responsive images feature in Astro automatically generates optimized images for different screen sizes and resolutions, and applies the correct attributes to ensure that images are displayed correctly on all devices.

    Enable the image.responsiveStyles option in your Astro config. Then, set a layout attribute on any or component, or configure a default image.layout, for instantly responsive images with automatically generated srcset and sizes attributes based on the image's dimensions and the layout type.

    Displaying images correctly on the web can be challenging, and is one of the most common performance issues seen in sites. This new feature simplifies the most challenging part of the process: serving your site visitor an image optimized for their viewing experience, and for your website's performance.

    For full details, see the updated Image guide.

    Migration from Experimental Responsive Images

    The experimental.responsiveImages flag has been removed, and all experimental image configuration options have been renamed to their final names.

    If you were using the experimental responsive images feature, you'll need to update your configuration:

    Remove the experimental flag

    export default defineConfig({
       experimental: {
    -    responsiveImages: true,
       },
    });

    Update image configuration options

    During the experimental phase, default styles were applied automatically to responsive images. Now, you need to explicitly set the responsiveStyles option to true if you want these styles applied.

    export default defineConfig({
      image: {
    +    responsiveStyles: true,
      },
    });

    The experimental image configuration options have been renamed:

    Before:

    export default defineConfig({
      image: {
        experimentalLayout: 'constrained',
        experimentalObjectFit: 'cover',
        experimentalObjectPosition: 'center',
        experimentalBreakpoints: [640, 750, 828, 1080, 1280],
        experimentalDefaultStyles: true,
      },
      experimental: {
        responsiveImages: true,
      },
    });

    After:

    export default defineConfig({
      image: {
        layout: 'constrained',
        objectFit: 'cover',
        objectPosition: 'center',
        breakpoints: [640, 750, 828, 1080, 1280],
        responsiveStyles: true, // This is now *false* by default
      },
    });

    Component usage remains the same

    The layout, fit, and position props on <Image> and <Picture> components work exactly the same as before:

    <Image
      src={myImage}
      alt="A responsive image"
      layout="constrained"
      fit="cover"
      position="center"
    />

    If you weren't using the experimental responsive images feature, no changes are required.

    Please see the Image guide for more information on using responsive images in Astro.

  • Updated dependencies []:

    • @astrojs/underscore-redirects@1.0.0
withastro/astro

Changes

This PR addresses a couple of issues that were encoureted during the API bash of CSP withastro/roadmap#1168 (comment)

Testing

Added new tests

Docs

withastro/astro

Apparently 'strict-dynamic' needs quotes

Changes

I just added quotes to strict-dynamic, so the experimental CSP feature render it with quotes. Otherwise validators complain (see the image)
Screenshot 2025-06-16 at 08 04 26

Docs on strict-dynamic use quotes too:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src

withastro/astro

Changes

This PR adds support for static headers for the Netlify adapter. The initial implementation supports the experimental CSP feature. In the future, this may change, and we will update the documentation as needed.

@astrojs/underscore-redirects

To implement the feature, I had to make some breaking changes within underscore-redirects. The package is mostly for internal usage, so we don't have strong documentation and it's mostly for our needs, so the changesets are mostly technical.

The functionality for redirects must stay the same.

The printing logic has been removed from Redirects, instead consumers need to use printAsRedirects instead. The core functionality hasn't changed much, it now accounts for .target, because it's now optional.

@astrojs/netlify

The function that creates config.json is now called in the astro:build:done hook, because we need to collect the static headers from the hook astro:build:generated.

The new logic now loops through the new static headers, and if cps is enabled, they are added to the final config.json.

Testing

Added a new test. Existing tests should still pass.

Docs

withastro/astro

Changes

Currently the session config object is optional, but if provided it must have a driver specified. This caused issues when trying to provide custom configuration to an automatically-provided session driver, such as Cloudflare or Netlify. This PR makes the value optional. It still validates that a driver has been provided once it is first used, so this will catch cases where no driver is provided by either the user or the adapter.

Makes the session driver name optional in config.

Fixes #13920

Testing

Added a test case

Docs

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@nanostores/preact ^0.5.2 -> ^1.0.0 age adoption passing confidence

Release Notes

nanostores/preact (@​nanostores/preact)

v1.0.0

Compare Source

  • Added Nano Stores 1.0 support.
  • Removed Node.js 18 support.

Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@​types/diff ^5.2.3 -> ^8.0.0 age adoption passing confidence
@types/picomatch (source) ^3.0.2 -> ^4.0.0 age adoption passing confidence
@types/react (source) ^18.3.20 -> ^19.1.8 age adoption passing confidence
@types/react-dom (source) ^18.3.5 -> ^19.1.6 age adoption passing confidence
diff ^5.2.0 -> ^8.0.2 age adoption passing confidence
execa ^8.0.1 -> ^9.6.0 age adoption passing confidence
react (source) ^18.3.1 -> ^19.1.0 age adoption passing confidence
react-dom (source) ^18.3.1 -> ^19.1.0 age adoption passing confidence
tinyexec ^0.3.2 -> ^1.0.1 age adoption passing confidence
yargs-parser ^21.1.1 -> ^22.0.0 age adoption passing confidence
yocto-spinner ^0.2.1 -> ^1.0.0 age adoption passing confidence

Release Notes

kpdecker/jsdiff (diff)

v8.0.2

Compare Source

  • #​616 Restored compatibility of diffSentences with old Safari versions. This was broken in 8.0.0 by the introduction of a regex with a lookbehind assertion; these weren't supported in Safari prior to version 16.4.
  • #​612 Improved tree shakeability by marking the built CJS and ESM packages with sideEffects: false.

v8.0.1

Compare Source

  • #​610 Fixes types for diffJson which were broken by 8.0.0. The new bundled types in 8.0.0 only allowed diffJson to be passed string arguments, but it should've been possible to pass either strings or objects (and now is). Thanks to Josh Kelley for the fix.

v8.0.0

Compare Source

  • #​580 Multiple tweaks to diffSentences:
    • tokenization no longer takes quadratic time on pathological inputs (reported as a ReDOS vulnerability by Snyk); is now linear instead
    • the final sentence in the string is now handled the same by the tokenizer regardless of whether it has a trailing punctuation mark or not. (Previously, "foo. bar." tokenized to ["foo.", " ", "bar."] but "foo. bar" tokenized to ["foo.", " bar"] - i.e. whether the space between sentences was treated as a separate token depended upon whether the final sentence had trailing punctuation or not. This was arbitrary and surprising; it is no longer the case.)
    • in a string that starts with a sentence end, like "! hello.", the "!" is now treated as a separate sentence
    • the README now correctly documents the tokenization behaviour (it was wrong before)
  • #​581 - fixed some regex operations used for tokenization in diffWords taking O(n^2) time in pathological cases
  • #​595 - fixed a crash in patch creation functions when handling a single hunk consisting of a very large number (e.g. >130k) of lines. (This was caused by spreading indefinitely-large arrays to .push() using .apply or the spread operator and hitting the JS-implementation-specific limit on the maximum number of arguments to a function, as shown at https://stackoverflow.com/a/56809779/1709587; thus the exact threshold to hit the error will depend on the environment in which you were running JsDiff.)
  • #​596 - removed the merge function. Previously JsDiff included an undocumented function called merge that was meant to, in some sense, merge patches. It had at least a couple of serious bugs that could lead to it returning unambiguously wrong results, and it was difficult to simply "fix" because it was unclear precisely what it was meant to do. For now, the fix is to remove it entirely.
  • #​591 - JsDiff's source code has been rewritten in TypeScript. This change entails the following changes for end users:
    • the diff package on npm now includes its own TypeScript type definitions. Users who previously used the @types/diff npm package from DefinitelyTyped should remove that dependency when upgrading JsDiff to v8.

      Note that the transition from the DefinitelyTyped types to JsDiff's own type definitions includes multiple fixes and also removes many exported types previously used for options arguments to diffing and patch-generation functions. (There are now different exported options types for abortable calls - ones with a timeout or maxEditLength that may give a result of undefined - and non-abortable calls.) See the TypeScript section of the README for some usage tips.

    • The Diff object is now a class. Custom extensions of Diff, as described in the "Defining custom diffing behaviors" section of the README, can therefore now be done by writing a class CustomDiff extends Diff and overriding methods, instead of the old way based on prototype inheritance. (I think code that did things the old way should still work, though!)

    • diff/lib/index.es6.js and diff/lib/index.mjs no longer exist, and the ESM version of the library is no longer bundled into a single file.

    • The ignoreWhitespace option for diffWords is no longer included in the type declarations. The effect of passing ignoreWhitespace: true has always been to make diffWords just call diffWordsWithSpace instead, which was confusing, because that behaviour doesn't seem properly described as "ignoring" whitespace at all. The property remains available to non-TypeScript applications for the sake of backwards compatibility, but TypeScript applications will now see a type error if they try to pass ignoreWhitespace: true to diffWords and should change their code to call diffWordsWithSpace instead.

    • JsDiff no longer purports to support ES3 environments. (I'm pretty sure it never truly did, despite claiming to in its README, since even the 1.0.0 release used Array.map which was added in ES5.)

  • #​601 - diffJson's stringifyReplacer option behaves more like JSON.stringify's replacer argument now. In particular:
    • Each key/value pair now gets passed through the replacer once instead of twice
    • The key passed to the replacer when the top-level object is passed in as value is now "" (previously, was undefined), and the key passed with an array element is the array index as a string, like "0" or "1" (previously was whatever the key for the entire array was). Both the new behaviours match that of JSON.stringify.
  • #​602 - diffing functions now consistently return undefined when called in async mode (i.e. with a callback). Previously, there was an odd quirk where they would return true if the strings being diffed were equal and undefined otherwise.

v7.0.0

Compare Source

Just a single (breaking) bugfix, undoing a behaviour change introduced accidentally in 6.0.0:

  • #​554 diffWords treats numbers and underscores as word characters again. This behaviour was broken in v6.0.0.

v6.0.0

Compare Source

This is a release containing many, many breaking changes. The objective of this release was to carry out a mass fix, in one go, of all the open bugs and design problems that required breaking changes to fix. A substantial, but exhaustive, changelog is below.

Commits

  • #​497 diffWords behavior has been radically changed. Previously, even with ignoreWhitespace: true, runs of whitespace were tokens, which led to unhelpful and unintuitive diffing behavior in typical texts. Specifically, even when two texts contained overlapping passages, diffWords would sometimes choose to delete all the words from the old text and insert them anew in their new positions in order to avoid having to delete or insert whitespace tokens. Whitespace sequences are no longer tokens as of this release, which affects both the generated diffs and the counts.

    Runs of whitespace are still tokens in diffWordsWithSpace.

    As part of the changes to diffWords, a new .postProcess method has been added on the base Diff type, which can be overridden in custom Diff implementations.

    diffLines with ignoreWhitespace: true will no longer ignore the insertion or deletion of entire extra lines of whitespace at the end of the text. Previously, these would not show up as insertions or deletions, as a side effect of a hack in the base diffing algorithm meant to help ignore whitespace in diffWords. More generally, the undocumented special handling in the core algorithm for ignored terminals has been removed entirely. (This special case behavior used to rewrite the final two change objects in a scenario where the final change object was an addition or deletion and its value was treated as equal to the empty string when compared using the diff object's .equals method.)

  • #​500 diffChars now diffs Unicode code points instead of UTF-16 code units.

  • #​508 parsePatch now always runs in what was previously "strict" mode; the undocumented strict option has been removed. Previously, by default, parsePatch (and other patch functions that use it under the hood to parse patches) would accept a patch where the line counts in the headers were inconsistent with the actual patch content - e.g. where a hunk started with the header @@&#8203; -1,3 +1,6 @&#8203;@&#8203;, indicating that the content below spanned 3 lines in the old file and 6 lines in the new file, but then the actual content below the header consisted of some different number of lines, say 10 lines of context, 5 deletions, and 1 insertion. Actually trying to work with these patches using applyPatch or merge, however, would produce incorrect results instead of just ignoring the incorrect headers, making this "feature" more of a trap than something actually useful. It's been ripped out, and now we are always "strict" and will reject patches where the line counts in the headers aren't consistent with the actual patch content.

  • #​435 Fix parsePatch handling of control characters. parsePatch used to interpret various unusual control characters - namely vertical tabs, form feeds, lone carriage returns without a line feed, and EBCDIC NELs - as line breaks when parsing a patch file. This was inconsistent with the behavior of both JsDiff's own diffLines method and also the Unix diff and patch utils, which all simply treat those control characters as ordinary characters. The result of this discrepancy was that some well-formed patches - produced either by diff or by JsDiff itself and handled properly by the patch util - would be wrongly parsed by parsePatch, with the effect that it would disregard the remainder of a hunk after encountering one of these control characters.

  • #​439 Prefer diffs that order deletions before insertions. When faced with a choice between two diffs with an equal total edit distance, the Myers diff algorithm generally prefers one that does deletions before insertions rather than insertions before deletions. For instance, when diffing abcd against acbd, it will prefer a diff that says to delete the b and then insert a new b after the c, over a diff that says to insert a c before the b and then delete the existing c. JsDiff deviated from the published Myers algorithm in a way that led to it having the opposite preference in many cases, including that example. This is now fixed, meaning diffs output by JsDiff will more accurately reflect what the published Myers diff algorithm would output.

  • #​455 The added and removed properties of change objects are now guaranteed to be set to a boolean value. (Previously, they would be set to undefined or omitted entirely instead of setting them to false.)

  • #​464 Specifying {maxEditLength: 0} now sets a max edit length of 0 instead of no maximum.

  • #​460 Added oneChangePerToken option.

  • #​467 Consistent ordering of arguments to comparator(left, right). Values from the old array will now consistently be passed as the first argument (left) and values from the new array as the second argument (right). Previously this was almost (but not quite) always the other way round.

  • #​480 Passing maxEditLength to createPatch & createTwoFilesPatch now works properly (i.e. returns undefined if the max edit distance is exceeded; previous behavior was to crash with a TypeError if the edit distance was exceeded).

  • #​486 The ignoreWhitespace option of diffLines behaves more sensibly now. values in returned change objects now include leading/trailing whitespace even when ignoreWhitespace is used, just like how with ignoreCase the values still reflect the case of one of the original texts instead of being all-lowercase. ignoreWhitespace is also now compatible with newlineIsToken. Finally, diffTrimmedLines is deprecated (and removed from the docs) in favour of using diffLines with ignoreWhitespace: true; the two are, and always have been, equivalent.

  • #​490 When calling diffing functions in async mode by passing a callback option, the diff result will now be passed as the first argument to the callback instead of the second. (Previously, the first argument was never used at all and would always have value undefined.)

  • #​489 this.options no longer exists on Diff objects. Instead, options is now passed as an argument to methods that rely on options, like equals(left, right, options). This fixes a race condition in async mode, where diffing behaviour could be changed mid-execution if a concurrent usage of the same Diff instances overwrote its options.

  • #​518 linedelimiters no longer exists on patch objects; instead, when a patch with Windows-style CRLF line endings is parsed, the lines in lines will end with \r. There is now a new autoConvertLineEndings option, on by default, which makes it so that when a patch with Windows-style line endings is applied to a source file with Unix style line endings, the patch gets autoconverted to use Unix-style line endings, and when a patch with Unix-style line endings is applied to a source file with Windows-style line endings, it gets autoconverted to use Windows-style line endings.

  • #​521 the callback option is now supported by structuredPatch, createPatch, and createTwoFilesPatch

  • #​529 parsePatch can now parse patches where lines starting with -- or ++ are deleted/inserted; previously, there were edge cases where the parser would choke on valid patches or give wrong results.

  • #​530 Added ignoreNewlineAtEof option to diffLines

  • #​533 applyPatch uses an entirely new algorithm for fuzzy matching. Differences between the old and new algorithm are as follows:

    • The fuzzFactor now indicates the maximum Levenshtein distance that there can be between the context shown in a hunk and the actual file content at a location where we try to apply the hunk. (Previously, it represented a maximum Hamming distance, meaning that a single insertion or deletion in the source file could stop a hunk from applying even with a high fuzzFactor.)
    • A hunk containing a deletion can now only be applied in a context where the line to be deleted actually appears verbatim. (Previously, as long as enough context lines in the hunk matched, applyPatch would apply the hunk anyway and delete a completely different line.)
    • The context line immediately before and immediately after an insertion must match exactly between the hunk and the file for a hunk to apply. (Previously this was not required.)
  • #​535 A bug in patch generation functions is now fixed that would sometimes previously cause \ No newline at end of file to appear in the wrong place in the generated patch, resulting in the patch being invalid. These invalid patches can also no longer be applied successfully with applyPatch. (It was already the case that tools other than jsdiff, like GNU patch, would consider them malformed and refuse to apply them; versions of jsdiff with this fix now do the same thing if you ask them to apply a malformed patch emitted by jsdiff v5.)

  • #​535 Passing newlineIsToken: true to patch-generation functions is no longer allowed. (Passing it to diffLines is still supported - it's only functions like createPatch where passing newlineIsToken is now an error.) Allowing it to be passed never really made sense, since in cases where the option had any effect on the output at all, the effect tended to be causing a garbled patch to be created that couldn't actually be applied to the source file.

  • #​539 diffWords now takes an optional intlSegmenter option which should be an Intl.Segmenter with word-level granularity. This provides better tokenization of text into words than the default behaviour, even for English but especially for some other languages for which the default behaviour is poor.

sindresorhus/execa (execa)

v9.6.0

Compare Source


v9.5.3

Compare Source


v9.5.2

Compare Source

Bug fixes

v9.5.1

Compare Source

Bug fixes

v9.5.0

Compare Source

Features

await execa({stdout: {file: 'output.txt', append: true}})`npm run build`;

v9.4.1

Compare Source

Bug fixes

v9.4.0

Compare Source

Features

  • We've created a separate package called nano-spawn. It is similar to Execa but with fewer features, for a much smaller package size. More info.

Bug fixes

Documentation

v9.3.1

Compare Source

Thanks @​holic and @​jimhigson for your contributions!

Bugs

Bugs (types)

  • Fix type of the env option. It was currently failing for Remix or Next.js users. (by @​holic) (#​1141)

Documentation

v9.3.0

Compare Source

Features

v9.2.0

Compare Source

This release includes a new set of methods to exchange messages between the current process and a Node.js subprocess, also known as "IPC". This allows passing and returning almost any message type to/from a Node.js subprocess. Also, debugging IPC is now much easier.

Moreover, a new gracefulCancel option has also been added to terminate a subprocess gracefully.

For a deeper dive-in, please check and share the release post!

Thanks @​iiroj for your contribution, @​SimonSiefke and @​adymorz for reporting the bugs fixed in this release, and @​karlhorky for improving the documentation!

Deprecations

  • Passing 'ipc' to the stdio option has been deprecated. It will be removed in the next major release. Instead, the ipc: true option should be used. (#​1056)
- await execa('npm', ['run', 'build'], {stdio: ['pipe', 'pipe', 'pipe', 'ipc']});
+ await execa('npm', ['run', 'build'], {ipc: true});
- import {execaCommand} from 'execa';
+ import {execa} from 'execa';

- await execaCommand('npm run build');
+ await execa`npm run build`;

const taskName = 'build';
- await execaCommand(`npm run ${taskName}`);
+ await execa`npm run ${taskName}`;

const commandArguments = ['run', 'task with space'];
await execa`npm ${commandArguments}`;

If the file and/or multiple arguments are supplied as a single string, parseCommandString(command) can split that string into an array. More info. (#​1054)

- import {execaCommand} from 'execa';
+ import {execa, parseCommandString} from 'execa';

const commandString = 'npm run task';
- await execaCommand(commandString);
+ const commandArray = parseCommandString(commandString); // ['npm', 'run', 'task']
+ await execa`${commandArray}`;

// Or alternatively:
const [file, ...commandArguments] = commandArray;
await execa(file, commandArguments);

Features

Types

Bug fixes

v9.1.0

Compare Source

Features (types)

v9.0.2

Compare Source

Bug fixes (types)

v9.0.1

Compare Source

Bug fixes (types)

v9.0.0

Compare Source

This major release brings many important features including:

Please check the release post for a high-level overview! For the full list of breaking changes, features and bug fixes, please read below.

Thanks @​younggglcy, @​koshic, @​am0o0 and @​codesmith-emmy for your help!


One of the maintainers @​ehmicky is looking for a remote full-time position. Specialized in Node.js back-ends and CLIs, he led Netlify Build, Plugins and Configuration for 2.5 years. Feel free to contact him on his website or on LinkedIn!


Breaking changes (not types)

const {stdout} = await execa('node', ['file.js'], {encoding: 'buffer'});
console.log(stdout); // This is now an Uint8Array
- await execa('node', ['file.js'], {encoding: null});
+ await execa('node', ['file.js'], {encoding: 'buffer'});

- await execa('node', ['file.js'], {encoding: 'utf-8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'UTF8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'utf-16le'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs-2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'binary'});
+ await execa('node', ['file.js'], {encoding: 'latin1'});
  • Passing a file path to subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() has been removed. Instead, a {file: './path'} object should be passed to the stdout or stderr option. (#​752)
- await execa('node', ['file.js']).pipeStdout('output.txt');
+ await execa('node', ['file.js'], {stdout: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeStderr('output.txt');
+ await execa('node', ['file.js'], {stderr: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeAll('output.txt');
+ await execa('node', ['file.js'], {
+	stdout: {file: 'output.txt'},
+	stderr: {file: 'output.txt'},
+});
- await execa('node', ['file.js']).pipeStdout(stream);
+ await execa('node', ['file.js'], {stdout: ['pipe', stream]});

- await execa('node', ['file.js']).pipeStderr(stream);
+ await execa('node', ['file.js'], {stderr: ['pipe', stream]});

- await execa('node', ['file.js']).pipeAll(stream);
+ await execa('node', ['file.js'], {
+	stdout: ['pipe', stream],
+	stderr: ['pipe', stream],
+});
  • The subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() methods have been renamed to subprocess.pipe(). The command and its arguments can be passed to subprocess.pipe() directly, without calling execa() a second time. The from piping option can specify 'stdout' (the default value), 'stderr' or 'all'. (#​757)
- await execa('node', ['file.js']).pipeStdout(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js']);

- await execa('node', ['file.js']).pipeStderr(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'stderr'});

- await execa('node', ['file.js']).pipeAll(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'all'});
- await execa('node', ['file.js'], {signal: abortController.signal});
+ await execa('node', ['file.js'], {cancelSignal: abortController.signal});
try {
	await execa('node', ['file.js']);
} catch (error) {
- if (error.killed) {
+ if (error.isTerminated) {
		// ...
	}
}
- subprocess.cancel();
+ subprocess.kill();
- const subprocess = execa('node', ['file.js']);
- subprocess.kill('SIGTERM', {forceKillAfterTimeout: 1000});
+ const subprocess = execa('node', ['file.js'], {forceKillAfterDelay: 1000});
+ subprocess.kill('SIGTERM');
  • The verbose option is now a string enum instead of a boolean. false has been renamed to 'none' and true has been renamed to 'short'. (#​884)
- await execa('node', ['file.js'], {verbose: false});
+ await execa('node', ['file.js'], {verbose: 'none'});

- await execa('node', ['file.js'], {verbose: true});
+ await execa('node', ['file.js'], {verbose: 'short'});
- await execa('node', ['file.js'], {execPath: './path/to/node'});
+ await execa('node', ['file.js'], {nodePath: './path/to/node'});
- subprocess.send({example: true, getExample() {}});
+ subprocess.send({example: true});
const subprocess = execa('node', ['file.js']);
- setTimeout(() => {
	subprocess.stdout.pipe(process.stdout);
- }, 0);
- const subprocess = execa('node', ['file.js'], {killSignal: 'sigterm'});
+ const subprocess = execa('node', ['file.js'], {killSignal: 'SIGTERM'});

- subprocess.kill('sigterm');
+ subprocess.kill('SIGTERM');

Features

Execution
Text lines
Piping multiple subprocesses

Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

Changes

I was told to:

 update  ▶ New version of Astro available: 5.9.3
  Run deno run npm:@astrojs/upgrade to update

When I did it it failed and told me to run manually deno add @astrojs/rss@4.0.12 @astrojs/sitemap@3.4.1 astro@5.9.3 which would also fail because I need to specify that they are npm packages with the prefix npm: before each package, or, as of a recent feature added to Deno, use the --npm flag to say all packages are from npm.

Testing

Docs

withastro/astro

Changes

Add TOML support to the built-in content loaders.

A bit over a year ago, there was a PR (#11004) which added TOML support to Astro, but it was closed in favor of a community loader. However, in Astro 5.2, support was added for TOML Markdown frontmatter (including within content collections).

I think that following the addition of that feature, it makes sense to directly support TOML files within content collections for consistency. I wanted to move some data I had in markdown frontmatter to just plain TOML files and it feels odd to have support for the format in one place but not others.

I've added smol-toml as a direct dependency of astro, as this was already a transitive dependency through the markdown package.

Testing

This change was tested by extending the current test fixtures to include TOML files.

Docs

This will need documentation! I am happy to update the docs with a bit of guidance.

I think at minimum, we'd want to update the following link to mention that both the glob and file loaders now natively support toml.
https://docs.astro.build/en/reference/content-loader-reference/#built-in-loaders

In addition, the example about the custom parser function uses the toml format as an example. We'd probably want to update this to a CSV or another format, as if this change is merged, we will have native toml support and the example wouldn't make much sense.
https://docs.astro.build/en/guides/content-collections/#parser-function

/cc @withastro/maintainers-docs for feedback!

withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@astrojs/underscore-redirects@1.0.0

Major Changes

  • #13952 de82ef2 Thanks @ematipico! - - The type Redirects has been renamed to HostRoutes.

    • RouteDefinition.target is now optional
    • RouteDefinition.weight is now optional
    • Redirects.print has been removed. Now you need to pass Redirects type to the print function
    - redirects.print()
    + import { printAsRedirects } from "@astrojs/underscore-redirects"
    + printAsRedirects(redirects)

Minor Changes

  • #13952 de82ef2 Thanks @ematipico! - Adds a new method called createHostedRouteDefinition, which returns a HostRoute type from a IntegrationResolvedRoute.

  • #13952 de82ef2 Thanks @ematipico! - Adds a new method called printAsRedirects to print HostRoutes as redirects for the _redirects file.

@astrojs/netlify@6.4.0

Minor Changes

  • #13952 de82ef2 Thanks @ematipico! - Adds support for the experimental static headers Astro feature.

    When the feature is enabled via option experimentalStaticHeaders, and experimental Content Security Policy is enabled, the adapter will generate Response headers for static pages, which allows support for CSP directives that are not supported inside a <meta> tag (e.g. frame-ancestors).

    import { defineConfig } from 'astro/config';
    import netlify from '@astrojs/netlify';
    
    export default defineConfig({
      adapter: netlify({
        experimentalStaticHeaders: true,
      }),
      experimental: {
        cps: true,
      },
    });

Patch Changes

astro@5.9.4

Patch Changes

  • #13951 7eb88f1 Thanks @ascorbic! - Fixes a issue that caused errors when using an adapter-provided session driver with custom options

  • #13953 448bddc Thanks @zaitovalisher! - Fixes a bug where quotes were not added to the 'strict-dynamic' CSP directive

@astrojs/cloudflare@12.5.5

Patch Changes

withastro/starlight

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@astrojs/starlight@0.34.4

Patch Changes

withastro/starlight

Description

Initially spotted by @ArmandPhilippot in Astro Docs, this PR prevents icons in <Card> components from being shrunk.

Before After
SCR-20250613-jnwj SCR-20250613-jnyw
Remaining tasks
  • Remove the code change in docs/src/content/docs/index.mdx only used to make the issue more visible.
withastro/starlight

Description

The Bag of Tricks for Astro's View Transitions (= view transitions with the <ClientRouter />)
The Bag of Tricks for View Transitions, @vtbag (= view transitions with the browser native API)

withastro/astro

closes #13791

withastro/starlight

Description

Create a createMarkdownTestHelper method to reduce repeated creation of createMarkdownProcessor, and this method could initialize different parameters in the test method, so we get all tests passed!

before
image

after
image

Next, I will create a test to reproduce this bug, so that we can better verify the modified code logic.
Add a test(should correctly autolink headings in remote markdown content using rehypeAutolinkHeadings) to reproduce this bug

TypeError: Failed to parse Markdown file "undefined":
Cannot read properties of undefined (reading 'replace')
at normalizePath (/Users/sgalcheung/Documents/....../starlight/packages/starlight/integrations/heading-links.ts:110:14)
at transformer (/Users/sgalcheung/Documents/....../starlight/packages/starlight/integrations/heading-links.ts:34:8)
at wrapped (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:115:27)
at next (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:65:23)
at done (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:148:7)
at then (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:158:5)
at wrapped (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:136:9)
at next (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:65:23)
at done (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:148:7)
at then (file:///Users/sgalcheung/Documents/....../starlight/node_modules/.pnpm/trough@2.1.0/node_modules/trough/index.js:158:5)

withastro/astro

Changes

This PR adds a new feature and fixes a bug.

Feature

It adds a new experimental adapter feature called staticHeaders. See the updated section here: https://github.com/withastro/roadmap/blob/feat/rfc-csp/proposals/0055-csp.md#solution-adopted

The adapter feature is intentionally generic, allowing CSP to take advantage of it. It's been called experimental because the first feature to use it is CSP, so we want to make sure we get the API right first.

The PR doesn't update any adapters yet. I will do that in a separate PR.

To support this feature, we now track a new field called cspDestination within the SSRManifest. In the manifest, the value is intentionally undefined if the adapter doesn't use the new feature. The final value is eventually calculated at the very end, right before the rendering phase, and that's why the value becomes NonNullable.

Bug fix

Addresses

Where the meta tag should be rendered as early as possible.

Testing

I updated the tests and added new ones.

Docs

@withastro/maintainers-docs for feedback!

withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.9.3

Patch Changes

  • #13923 a9ac5ed Thanks @ematipico! - BREAKING CHANGE to the experimental Content Security Policy (CSP) only

    Changes the behavior of experimental Content Security Policy (CSP) to now serve hashes differently depending on whether or not a page is prerendered:

    • Via the <meta> element for static pages.
    • Via the Response header content-security-policy for on-demand rendered pages.

    This new strategy allows you to add CSP content that is not supported in a <meta> element (e.g. report-uri, frame-ancestors, and sandbox directives) to on-demand rendered pages.

    No change to your project code is required as this is an implementation detail. However, this will result in a different HTML output for pages that are rendered on demand. Please check your production site to verify that CSP is working as intended.

    To keep up to date with this developing feature, or to leave feedback, visit the CSP Roadmap proposal.

  • #13926 953a249 Thanks @ematipico! - Adds a new Astro Adapter Feature called experimentalStaticHeaders to allow your adapter to receive the Headers for rendered static pages.

    Adapters that enable support for this feature can access header values directly, affecting their handling of some Astro features such as Content Security Policy (CSP). For example, Astro will no longer serve the CSP <meta http-equiv="content-security-policy"> element in static pages to adapters with this support.

    Astro will serve the value of the header inside a map that can be retrieved from the hook astro:build:generated. Adapters can read this mapping and use their hosting headers capabilities to create a configuration file.

    A new field called experimentalRouteToHeaders will contain a map of Map<IntegrationResolvedRoute, Headers> where the Headers type contains the headers emitted by the rendered static route.

    To enable support for this experimental Astro Adapter Feature, add it to your adapterFeatures in your adapter config:

    // my-adapter.mjs
    export default function createIntegration() {
      return {
        name: '@example/my-adapter',
        hooks: {
          'astro:config:done': ({ setAdapter }) => {
            setAdapter({
              name: '@example/my-adapter',
              serverEntrypoint: '@example/my-adapter/server.js',
              adapterFeatures: {
                experimentalStaticHeaders: true,
              },
            });
          },
        },
      };
    }

    See the Adapter API docs for more information about providing adapter features.

  • #13697 af83b85 Thanks @benosmac! - Fixes issues with fallback route pattern matching when i18n.routing.fallbackType is rewrite.

    • Adds conditions for route matching in generatePath when building fallback routes and checking for existing translated pages

    Now for a route to be matched it needs to be inside a named [locale] folder. This fixes an issue where route.pattern.test() incorrectly matched dynamic routes, causing the page to be skipped.

    • Adds conditions for route matching in findRouteToRewrite

    Now the requested pathname must exist in route.distURL for a dynamic route to match. This fixes an issue where route.pattern.test() incorrectly matched dynamic routes, causing the build to fail.

  • #13924 1cd8c3b Thanks @qw-in! - Fixes an edge case where isPrerendered was incorrectly set to false for static redirects.

  • #13926 953a249 Thanks @ematipico! - Fixes an issue where the experimental CSP meta element wasn't placed in the <head> element as early as possible, causing these policies to not apply to styles and scripts that came before the meta element.

withastro/astro

Changes

Closes #13875

Previously, isPrerendered would be false in statically built configured redirects (notably in middleware).

Testing

I added a test, happy to expand or reorganize. Additionally I've run the full test suite locally and I don't have any new failures (rosetta + devcontainers likely the culprit #12704).

Docs

This is a fix, so I don't think docs are necessary?

withastro/astro

Changes

This PR changes how the CSP hashes are served. For static pages, we still serve them via the <meta> element, but for SSR pages, they are served using the Reponse headers.

This change partially addresses the following comments, where now the content of the CSP header for SSR pages can support directives that wouldn't be supported in the meta:

After landing this PR, I will move forward with the second part of Matthew's comment, where if there's an adapter, the meta tag isn't provided anymore for static pages, instead we will use the adapter's hosting capabilities to deliver those hashes:

Testing

Added a new test

Docs

I will update the roadmap PR after this PR is accepted.
I will send a pull request to the docs later.

withastro/astro

Changes

I think I saw this bug in the roadmap, or there was an issue? I can't recall. Regardless, with this PR, astro doesn't add the quote to the resources. Only certain resources must have quotes e.g. 'self', and users must be responsible for them.

Testing

Tests updated

Docs

Updated the configuration examples. Will need to update the roadmap too

withastro/astro

Changes

  • Unflags the responsive images feature
  • Defaults responsive styles to false
  • Makes the priority attribute available to all images

Migration Guide

If you were using the experimental responsive images feature, you'll need to update your configuration:

Remove the experimental flag

export default defineConfig({
   experimental: {
-    responsiveImages: true,
   },
});

Update image configuration options

During the experimental phase, default styles were applied automatically to responsive images. Now, you need to explicitly set the responsiveStyles option to true if you want these styles applied.

export default defineConfig({
  image: {
+    responsiveStyles: true,
  },
});

The experimental image configuration options have been renamed:

Before:

export default defineConfig({
  image: {
    experimentalLayout: 'constrained',
    experimentalObjectFit: 'cover', 
    experimentalObjectPosition: 'center',
    experimentalBreakpoints: [640, 750, 828, 1080, 1280],
    experimentalDefaultStyles: true, 
  },
  experimental: {
    responsiveImages: true,
  },
});

After:

export default defineConfig({
  image: {
    layout: 'constrained',
    objectFit: 'cover',
    objectPosition: 'center', 
    breakpoints: [640, 750, 828, 1080, 1280],
    responsiveStyles: true, // This is now *false* by default
  },
});

The priority option for the image component

By default, the Astro <Image /> component generates <img> tags that lazy-load their content by setting loading="lazy" and decoding="async". This improves performance by deferring the loading of images that are not immediately visible in the viewport, and gives the best scores in performance audits like Lighthouse. However, for the main, above-the-fold images, you should tell the browser to load them immediately. Currently you can do this by setting the loading attribute to "eager" and decoding to "sync" on the <img> tag, but this is a bit cumbersome. It also does not currently set the fetchpriority attribute, which is a new HTML attribute that allows you to specify the priority of resource fetching.

This change introduces a new priority option for the <Image /> and <Picture /> components, which automatically sets the loading, decoding, and fetchpriority attributes to their optimal values for above-the-fold images. It is a boolean prop, and you can use the shorthand syntax by simply adding priority as a prop to the <Image /> or <Picture /> component. When set, it will apply the following attributes:

  • loading="eager"
  • decoding="sync"
  • fetchpriority="high"

The individual attributes can still be set manually if you need to customize them further.

This option was previously available for experimental responsive images, but now it is a standard feature for all images.

Usage

<Image 
  src="/path/to/image.jpg" 
  alt="An example image" 
  priority
/>

Note

You should only use the priority option for images that are critical to the initial rendering of the page, and ideally only one image per page. Using it for too many images will lead to performance issues, as it forces the browser to load those images immediately, potentially blocking the rendering of other content.

Testing

Updated test fixtures

Docs

Changes needed beyond the initial planned unflagging:

  • renamed responsiveStyles option now defaults to false
  • new priority option
withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.9.2

Patch Changes

  • #13919 423fe60 Thanks @ematipico! - Fixes a bug where Astro added quotes to the CSP resources.

    Only certain resources require quotes (e.g. 'self' but not https://cdn.example.com), so Astro no longer adds quotes to any resources. You must now provide the quotes yourself for resources such as 'self' when necessary:

    export default defineConfig({
      experimental: {
        csp: {
          styleDirective: {
            resources: [
    -          "self",
    +          "'self'",
              "https://cdn.example.com"
            ]
          }
        }
      }
    })
  • #13914 76c5480 Thanks @ematipico! - BREAKING CHANGE to the experimental Content Security Policy feature only

    Removes support for experimental Content Security Policy (CSP) when using the <ClientRouter /> component for view transitions.

    It is no longer possible to enable experimental CSP while using Astro's view transitions. Support was already unstable with the <ClientRouter /> because CSP required making its underlying implementation asynchronous. This caused breaking changes for several users and therefore, this PR removes support completely.

    If you are currently using the component for view transitions, please remove the experimental CSP flag as they cannot be used together.

    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      experimental: {
    -   csp: true
       }
    });

    Alternatively, to continue using experimental CSP in your project, you can consider migrating to the browser native View Transition API and remove the <ClientRouter /> from your project. You may be able to achieve similar results if you are not using Astro's enhancements to the native View Transitions and Navigation APIs.

    Support might be reintroduced in future releases. You can follow this experimental feature's development in the CSP RFC.

withastro/astro

Changes

Depends on withastro/compiler#1081

This PR drops support for view transitions in CSP. Making the function renderTrantion asynchronous caused some undesirable effects in userland. We already knew that the support was unstable, and this regression made me decide that we aren't ready yet.

Closes #13908

Testing

I removed the tests

Docs

I will send a PR to the docs repository before the release

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@types/react (source) ^18.3.23 -> ^19.1.8 age adoption passing confidence
@types/react-dom (source) ^18.3.7 -> ^19.1.6 age adoption passing confidence
react (source) ^18.3.1 -> ^19.1.0 age adoption passing confidence
react-dom (source) ^18.3.1 -> ^19.1.0 age adoption passing confidence

Release Notes

facebook/react (react)

v19.1.0

Compare Source

v19.0.0

Compare Source

Below is a list of all new features, APIs, deprecations, and breaking changes. Read React 19 release post and React 19 upgrade guide for more information.

Note: To help make the upgrade to React 19 easier, we’ve published a react@18.3 release that is identical to 18.2 but adds warnings for deprecated APIs and other changes that are needed for React 19. We recommend upgrading to React 18.3.1 first to help identify any issues before upgrading to React 19.

New Features
React
  • Actions: startTransition can now accept async functions. Functions passed to startTransition are called “Actions”. A given Transition can include one or more Actions which update state in the background and update the UI with one commit. In addition to updating state, Actions can now perform side effects including async requests, and the Action will wait for the work to finish before finishing the Transition. This feature allows Transitions to include side effects like fetch() in the pending state, and provides support for error handling, and optimistic updates.
  • useActionState: is a new hook to order Actions inside of a Transition with access to the state of the action, and the pending state. It accepts a reducer that can call Actions, and the initial state used for first render. It also accepts an optional string that is used if the action is passed to a form action prop to support progressive enhancement in forms.
  • useOptimistic: is a new hook to update state while a Transition is in progress. It returns the state, and a set function that can be called inside a transition to “optimistically” update the state to expected final value immediately while the Transition completes in the background. When the transition finishes, the state is updated to the new value.
  • use: is a new API that allows reading resources in render. In React 19, use accepts a promise or Context. If provided a promise, use will suspend until a value is resolved. use can only be used in render but can be called conditionally.
  • ref as a prop: Refs can now be used as props, removing the need for forwardRef.
  • Suspense sibling pre-warming: When a component suspends, React will immediately commit the fallback of the nearest Suspense boundary, without waiting for the entire sibling tree to render. After the fallback commits, React will schedule another render for the suspended siblings to “pre-warm” lazy requests.
React DOM Client
  • <form> action prop: Form Actions allow you to manage forms automatically and integrate with useFormStatus. When a <form> action succeeds, React will automatically reset the form for uncontrolled components. The form can be reset manually with the new requestFormReset API.
  • <button> and <input> formAction prop: Actions can be passed to the formAction prop to configure form submission behavior. This allows using different Actions depending on the input.
  • useFormStatus: is a new hook that provides the status of the parent <form> action, as if the form was a Context provider. The hook returns the values: pending, data, method, and action.
  • Support for Document Metadata: We’ve added support for rendering document metadata tags in components natively. React will automatically hoist them into the <head> section of the document.
  • Support for Stylesheets: React 19 will ensure stylesheets are inserted into the <head> on the client before revealing the content of a Suspense boundary that depends on that stylesheet.
  • Support for async scripts: Async scripts can be rendered anywhere in the component tree and React will handle ordering and deduplication.
  • Support for preloading resources: React 19 ships with preinit, preload, prefetchDNS, and preconnect APIs to optimize initial page loads by moving discovery of additional resources like fonts out of stylesheet loading. They can also be used to prefetch resources used by an anticipated navigation.
React DOM Server
  • Added prerender and prerenderToNodeStream APIs for static site generation. They are designed to work with streaming environments like Node.js Streams and Web Streams. Unlike renderToString, they wait for data to load for HTML generation.
React Server Components
  • RSC features such as directives, server components, and server functions are now stable. This means libraries that ship with Server Components can now target React 19 as a peer dependency with a react-server export condition for use in frameworks that support the Full-stack React Architecture. The underlying APIs used to implement a React Server Components bundler or framework do not follow semver and may break between minors in React 19.x. See docs for how to support React Server Components.
Deprecations
  • Deprecated: element.ref access: React 19 supports ref as a prop, so we’re deprecating element.ref in favor of element.props.ref. Accessing will result in a warning.
  • react-test-renderer: In React 19, react-test-renderer logs a deprecation warning and has switched to concurrent rendering for web usage. We recommend migrating your tests to @​testing-library/react or @​testing-library/react-native
Breaking Changes

React 19 brings in a number of breaking changes, including the removals of long-deprecated APIs. We recommend first upgrading to 18.3.1, where we've added additional deprecation warnings. Check out the upgrade guide for more details and guidance on codemodding.

React
  • New JSX Transform is now required: We introduced a new JSX transform in 2020 to improve bundle size and use JSX without importing React. In React 19, we’re adding additional improvements like using ref as a prop and JSX speed improvements that require the new transform.
  • Errors in render are not re-thrown: Errors that are not caught by an Error Boundary are now reported to window.reportError. Errors that are caught by an Error Boundary are reported to console.error. We’ve introduced onUncaughtError and onCaughtError methods to createRoot and hydrateRoot to customize this error handling.
  • Removed: propTypes: Using propTypes will now be silently ignored. If required, we recommend migrating to TypeScript or another type-checking solution.
  • Removed: defaultProps for functions: ES6 default parameters can be used in place. Class components continue to support defaultProps since there is no ES6 alternative.
  • Removed: contextTypes and getChildContext: Legacy Context for class components has been removed in favor of the contextType API.
  • Removed: string refs: Any usage of string refs need to be migrated to ref callbacks.
  • Removed: Module pattern factories: A rarely used pattern that can be migrated to regular functions.
  • Removed: React.createFactory: Now that JSX is broadly supported, all createFactory usage can be migrated to JSX components.
  • Removed: react-test-renderer/shallow: This has been a re-export of react-shallow-renderer since React 18. If needed, you can continue to use the third-party package directly. We recommend using @​testing-library/react or @​testing-library/react-native instead.
React DOM
  • Removed: react-dom/test-utils: We’ve moved act from react-dom/test-utils to react. All other utilities have been removed.
  • Removed: ReactDOM.render, ReactDOM.hydrate: These have been removed in favor of the concurrent equivalents: ReactDOM.createRoot and ReactDOM.hydrateRoot.
  • Removed: unmountComponentAtNode: Removed in favor of root.unmount().
  • Removed: ReactDOM.findDOMNode: You can replace ReactDOM.findDOMNode with DOM Refs.
Notable Changes
React
  • <Context> as a provider: You can now render <Context> as a provider instead of <Context.Provider>.
  • Cleanup functions for refs: When the component unmounts, React will call the cleanup function returned from the ref callback.
  • useDeferredValue initial value argument: When provided, useDeferredValue will return the initial value for the initial render of a component, then schedule a re-render in the background with the deferredValue returned.
  • Support for Custom Elements: React 19 now passes all tests on Custom Elements Everywhere.
  • StrictMode changes: useMemo and useCallback will now reuse the memoized results from the first render, during the second render. Additionally, StrictMode will now double-invoke ref callback functions on initial mount.
  • UMD builds removed: To load React 19 with a script tag, we recommend using an ESM-based CDN such as esm.sh.
React DOM
  • Diffs for hydration errors: In the case of a mismatch, React 19 logs a single error with a diff of the mismatched content.
  • Compatibility with third-party scripts and extensions: React will now force a client re-render to fix up any mismatched content caused by elements inserted by third-party JS.
TypeScript Changes

The most common changes can be codemodded with npx types-react-codemod@latest preset-19 ./path-to-your-react-ts-files.

  • Removed deprecated TypeScript types:
    • ReactChild (replacement: React.ReactElement | number | string)
    • ReactFragment (replacement: Iterable<React.ReactNode>)
    • ReactNodeArray (replacement: ReadonlyArray<React.ReactNode>)
    • ReactText (replacement: number | string)
    • VoidFunctionComponent (replacement: FunctionComponent)
    • VFC (replacement: FC)
    • Moved to prop-types: Requireable, ValidationMap, Validator, WeakValidationMap
    • Moved to create-react-class: ClassicComponentClass, ClassicComponent, ClassicElement, ComponentSpec, Mixin, ReactChildren, ReactHTML, ReactSVG, SFCFactory
  • Disallow implicit return in refs: refs can now accept cleanup functions. When you return something else, we can’t tell if you intentionally returned something not meant to clean up or returned the wrong value. Implicit returns of anything but functions will now error.
  • Require initial argument to useRef: The initial argument is now required to match useState, createContext etc
  • Refs are mutable by default: Ref objects returned from useRef() are now always mutable instead of sometimes being immutable. This feature was too confusing for users and conflicted with legit cases where refs were managed by React and manually written to.
  • Strict ReactElement typing: The props of React elements now default to unknown instead of any if the element is typed as ReactElement
  • JSX namespace in TypeScript: The global JSX namespace is removed to improve interoperability with other libraries using JSX. Instead, the JSX namespace is available from the React package: import { JSX } from 'react'
  • Better useReducer typings: Most useReducer usage should not require explicit type arguments.
    For example,
    -useReducer<React.Reducer<State, Action>>(reducer)
    +useReducer(reducer)
    or
    -useReducer<React.Reducer<State, Action>>(reducer)
    +useReducer<State, Action>(reducer)
All Changes
React
React DOM
React DOM Server
ReactTestRenderer
React Reconciler
React-Is
useSyncExternalStore
facebook/react (react-dom)

v19.1.0

Compare Source

v19.0.0

Compare Source

Below is a list of all new features, APIs, deprecations, and breaking changes. Read React 19 release post and React 19 upgrade guide for more information.

Note: To help make the upgrade to React 19 easier, we’ve published a react@18.3 release that is identical to 18.2 but adds warnings for deprecated APIs and other changes that are needed for React 19. We recommend upgrading to React 18.3.1 first to help identify any issues before upgrading to React 19.

New Features
React
  • Actions: startTransition can now accept async functions. Functions passed to startTransition are called “Actions”. A given Transition can include one or more Actions which update state in the background and update the UI with one commit. In addition to updating state, Actions can now perform side effects including async requests, and the Action will wait for the work to finish before finishing the Transition. This feature allows Transitions to include side effects like fetch() in the pending st

Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@sveltejs/vite-plugin-svelte (source) ^5.0.3 -> ^5.1.0 age adoption passing confidence
@vitejs/plugin-react (source) ^4.5.0 -> ^4.5.2 age adoption passing confidence
@vue/compiler-sfc (source) ^3.5.16 -> ^3.5.17 age adoption passing confidence
cheerio (source) 1.0.0 -> 1.1.0 age adoption passing confidence
linkedom ^0.18.10 -> ^0.18.11 age adoption passing confidence
preact (source) ^10.26.8 -> ^10.26.9 age adoption passing confidence
svelte (source) ^5.33.14 -> ^5.34.7 age adoption passing confidence
svelte2tsx (source) ^0.7.39 -> ^0.7.40 age adoption passing confidence
vite-plugin-vue-devtools (source) ^7.7.6 -> ^7.7.7 age adoption passing confidence
vue (source) ^3.5.16 -> ^3.5.17 age adoption passing confidence

Release Notes

sveltejs/vite-plugin-svelte (@​sveltejs/vite-plugin-svelte)

v5.1.0

Compare Source

Minor Changes
  • scope css to js module to enable treeshaking scoped css from unused components. Requires vite 6.2 and svelte 5.26 (#​1092)
Patch Changes
  • add svelte > clsx to optimizeDeps.include to avoid page reload when using vite6 and npm (#​1124)
vitejs/vite-plugin-react (@​vitejs/plugin-react)

v4.5.2

Compare Source

Suggest @vitejs/plugin-react-oxc if rolldown-vite is detected #​491

Emit a log which recommends @vitejs/plugin-react-oxc when rolldown-vite is detected to improve performance and use Oxc under the hood. The warning can be disabled by setting disableOxcRecommendation: false in the plugin options.

Use optimizeDeps.rollupOptions instead of optimizeDeps.esbuildOptions for rolldown-vite #​489

This suppresses the warning about optimizeDeps.esbuildOptions being deprecated in rolldown-vite.

Add Vite 7-beta to peerDependencies range #​497

React plugins are compatible with Vite 7, this removes the warning when testing the beta.

v4.5.1

Compare Source

Add explicit semicolon in preambleCode #​485

This fixes an edge case when using HTML minifiers that strips line breaks aggressively.

vuejs/core (@​vue/compiler-sfc)

v3.5.17

Compare Source

Bug Fixes
cheeriojs/cheerio (cheerio)

v1.1.0

Compare Source

What's Changed

Doc Improvements

New Contributors

Full Changelog: cheeriojs/cheerio@v1.0.0...v1.1.0

WebReflection/linkedom (linkedom)

v0.18.11

Compare Source

preactjs/preact (preact)

v10.26.9

Compare Source

Fixes
Maintenance
sveltejs/svelte (svelte)

v5.34.7

Compare Source

Patch Changes
  • fix: address css class matching regression (#​16204)

v5.34.6

Compare Source

Patch Changes
  • fix: match class and style directives against attribute selector (#​16179)

v5.34.5

Compare Source

Patch Changes
  • fix: keep spread non-delegated event handlers up to date (#​16180)

  • fix: remove undefined attributes on hydration (#​16178)

  • fix: ensure sources within nested effects still register correctly (#​16193)

  • fix: avoid shadowing a variable in dynamic components (#​16185)

v5.34.4

Compare Source

Patch Changes
  • fix: don't set state withing with_parent in proxy (#​16176)

  • fix: use compiler-driven reactivity in legacy mode template expressions (#​16100)

v5.34.3

Compare Source

Patch Changes
  • fix: don't eagerly execute deriveds on resume (#​16150)

  • fix: prevent memory leaking signals in legacy mode (#​16145)

  • fix: don't define error.message if it's not configurable (#​16149)

v5.34.2

Compare Source

Patch Changes
  • fix: add missing typings for some dimension bindings (#​16142)

  • fix: prune typescript class field declarations (#​16154)

v5.34.1

Compare Source

Patch Changes
  • fix: correctly tag private class state fields (#​16132)

v5.34.0

Compare Source

Minor Changes
  • feat: add source name logging to $inspect.trace (#​16060)
Patch Changes
  • fix: add command and commandfor to HTMLButtonAttributes (#​16117)

  • fix: better $inspect.trace() output (#​16131)

  • fix: properly hydrate dynamic css props components and remove element removal (#​16118)

v5.33.19

Compare Source

Patch Changes
  • fix: reset is_flushing if flushSync is called and there's no scheduled effect (#​16119)

v5.33.18

Compare Source

Patch Changes

v5.33.17

Compare Source

Patch Changes
  • chore: update acorn parser ecmaVersion to parse import attributes (#​16098)

v5.33.16

Compare Source

Patch Changes
  • fix: visit expression when destructuring state declarations (#​16081)

  • fix: move xmlns attribute from SVGAttributes to to DOMAttributes (#​16080)

v5.33.15

Compare Source

Patch Changes
  • fix: invoke parent boundary of deriveds that throw (#​16091)
sveltejs/language-tools (svelte2tsx)

v0.7.40

Compare Source

  • fix: prevent error with bind:this={get, set} (#​2781)
  • fix: don't treat derived imported from svelte/store as a potential store (#​2780)
  • fix: key block can have its own block scope (#​2768)
vuejs/devtools (vite-plugin-vue-devtools)

v7.7.7

Compare Source

   🚀 Features
    View changes on GitHub

Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

…tributes

Changes

Testing

  • Updated component.test.js with unit tets

Docs

  • added changeset
withastro/astro

Changes

Updates compiler and reactivates some view transition e2e tests
Fixes withastro/compiler#1079

Testing

Reactivates skipped view transition e2e tests

Docs

n.a.: bug fix.

withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.9.1

Patch Changes

withastro/astro

Changes

Fixed a bug where the script source and style source were reversed.

Testing

should pass

Docs

N/A

withastro/astro

Changes

fixes #13879

Converts \0virtual:module.css to /@id/__x00__virtual:module.css, this is the direct reversal of the unwrapId function in core/utils.ts

Testing

The vite-virtual-modules e2e test has been added.
This tests if the dev server response contains style and script tags with proper data-vite-dev-id and src values respectively.

Docs

This is a correctness change in the internal vite-astro-server plugin which does not have public facing documentation.

withastro/astro

Changes

  • Fixes fallback not being removed/deleted when server island is rendered.
  • Fixes #13895

Testing

  • Tested locally
  • Added E2E test to check that fallback does not exist after server island renders

Docs

Bugfix, no new features or changes

withastro/starlight

Description

  • Adds Fomr to showcase sites
withastro/astro

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

astro@5.9.0

Minor Changes

  • #13802 0eafe14 Thanks @ematipico! - Adds experimental Content Security Policy (CSP) support

    CSP is an important feature to provide fine-grained control over resources that can or cannot be downloaded and executed by a document. In particular, it can help protect against cross-site scripting (XSS) attacks.

    Enabling this feature adds additional security to Astro's handling of processed and bundled scripts and styles by default, and allows you to further configure these, and additional, content types. This new experimental feature has been designed to work in every Astro rendering environment (static pages, dynamic pages and single page applications), while giving you maximum flexibility and with type-safety in mind.

    It is compatible with most of Astro's features such as client islands, and server islands, although Astro's view transitions using the <ClientRouter /> are not yet fully supported. Inline scripts are not supported out of the box, but you can provide your own hashes for external and inline scripts.

    To enable this feature, add the experimental flag in your Astro config:

    // astro.config.mjs
    import { defineConfig } from 'astro/config';
    
    export default defineConfig({
      experimental: {
        csp: true,
      },
    });

    For more information on enabling and using this feature in your project, see the Experimental CSP docs.

    For a complete overview, and to give feedback on this experimental API, see the Content Security Policy RFC.

  • #13850 1766d22 Thanks @ascorbic! - Provides a Markdown renderer to content loaders

    When creating a content loader, you will now have access to a renderMarkdown function that allows you to render Markdown content directly within your loaders. It uses the same settings and plugins as the renderer used for Markdown files in Astro, and follows any Markdown settings you have configured in your Astro project.

    This allows you to render Markdown content from various sources, such as a CMS or other data sources, directly in your loaders without needing to preprocess the Markdown content separately.

    import type { Loader } from 'astro/loaders';
    import { loadFromCMS } from './cms';
    
    export function myLoader(settings): Loader {
      return {
        name: 'my-loader',
        async load({ renderMarkdown, store }) {
          const entries = await loadFromCMS();
    
          store.clear();
    
          for (const entry of entries) {
            // Assume each entry has a 'content' field with markdown content
            store.set(entry.id, {
              id: entry.id,
              data: entry,
              rendered: await renderMarkdown(entry.content),
            });
          }
        },
      };
    }

    The return value of renderMarkdown is an object with two properties: html and metadata. These match the rendered property of content entries in content collections, so you can use them to render the content in your components or pages.

    ---
    import { getEntry, render } from 'astro:content';
    const entry = await getEntry('my-collection', Astro.params.id);
    const { Content } = await render(entry);
    ---
    
    <Content />

    For more information, see the Content Loader API docs.

  • #13887 62f0668 Thanks @yanthomasdev! - Adds an option for integration authors to suppress adapter warning/errors in supportedAstroFeatures. This is useful when either an warning/error isn't applicable in a specific context or the default one might conflict and confuse users.

    To do so, you can add suppress: "all" (to suppress both the default and custom message) or suppress: "default" (to only suppress the default one):

    setAdapter({
      name: 'my-astro-integration',
      supportedAstroFeatures: {
        staticOutput: 'stable',
        hybridOutput: 'stable',
        sharpImageService: {
          support: 'limited',
          message:
            "The sharp image service isn't available in the deploy environment, but will be used by prerendered pages on build.",
          suppress: 'default',
        },
      },
    });

    For more information, see the Adapter API reference docs.

@astrojs/cloudflare@12.5.4

Patch Changes

  • #13817 b7258f1 Thanks @yanthomasdev! - Clarifies and reduces a few logs when starting the dev server with @astrojs/cloudflare.

    Warnings about sharp support will now be suppressed when you have explicitly set an imageService option.

  • Updated dependencies []:

    • @astrojs/underscore-redirects@0.6.1
withastro/astro

Resurrection of #13842

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@netlify/blobs ^8.2.0 -> ^9.1.5 age adoption passing confidence
@netlify/functions ^3.1.5 -> ^4.1.2 age adoption passing confidence
execa ^8.0.1 -> ^9.6.0 age adoption passing confidence
express (source) ^4.21.2 -> ^5.1.0 age adoption passing confidence

Release Notes

netlify/primitives (@​netlify/blobs)

v9.1.5

Compare Source

v9.1.4

Compare Source

v9.1.3

Compare Source

v9.1.2

Compare Source

v9.1.1

Compare Source

v9.1.0

Compare Source

v9.0.1

Compare Source

v9.0.0

Compare Source

sindresorhus/execa (execa)

v9.6.0

Compare Source


v9.5.3

Compare Source


v9.5.2

Compare Source

Bug fixes

v9.5.1

Compare Source

Bug fixes

v9.5.0

Compare Source

Features

await execa({stdout: {file: 'output.txt', append: true}})`npm run build`;

v9.4.1

Compare Source

Bug fixes

v9.4.0

Compare Source

Features

  • We've created a separate package called nano-spawn. It is similar to Execa but with fewer features, for a much smaller package size. More info.

Bug fixes

Documentation

v9.3.1

Compare Source

Thanks @​holic and @​jimhigson for your contributions!

Bugs

Bugs (types)

  • Fix type of the env option. It was currently failing for Remix or Next.js users. (by @​holic) (#​1141)

Documentation

v9.3.0

Compare Source

Features

v9.2.0

Compare Source

This release includes a new set of methods to exchange messages between the current process and a Node.js subprocess, also known as "IPC". This allows passing and returning almost any message type to/from a Node.js subprocess. Also, debugging IPC is now much easier.

Moreover, a new gracefulCancel option has also been added to terminate a subprocess gracefully.

For a deeper dive-in, please check and share the release post!

Thanks @​iiroj for your contribution, @​SimonSiefke and @​adymorz for reporting the bugs fixed in this release, and @​karlhorky for improving the documentation!

Deprecations

  • Passing 'ipc' to the stdio option has been deprecated. It will be removed in the next major release. Instead, the ipc: true option should be used. (#​1056)
- await execa('npm', ['run', 'build'], {stdio: ['pipe', 'pipe', 'pipe', 'ipc']});
+ await execa('npm', ['run', 'build'], {ipc: true});
- import {execaCommand} from 'execa';
+ import {execa} from 'execa';

- await execaCommand('npm run build');
+ await execa`npm run build`;

const taskName = 'build';
- await execaCommand(`npm run ${taskName}`);
+ await execa`npm run ${taskName}`;

const commandArguments = ['run', 'task with space'];
await execa`npm ${commandArguments}`;

If the file and/or multiple arguments are supplied as a single string, parseCommandString(command) can split that string into an array. More info. (#​1054)

- import {execaCommand} from 'execa';
+ import {execa, parseCommandString} from 'execa';

const commandString = 'npm run task';
- await execaCommand(commandString);
+ const commandArray = parseCommandString(commandString); // ['npm', 'run', 'task']
+ await execa`${commandArray}`;

// Or alternatively:
const [file, ...commandArguments] = commandArray;
await execa(file, commandArguments);

Features

Types

Bug fixes

v9.1.0

Compare Source

Features (types)

v9.0.2

Compare Source

Bug fixes (types)

v9.0.1

Compare Source

Bug fixes (types)

v9.0.0

Compare Source

This major release brings many important features including:

Please check the release post for a high-level overview! For the full list of breaking changes, features and bug fixes, please read below.

Thanks @​younggglcy, @​koshic, @​am0o0 and @​codesmith-emmy for your help!


One of the maintainers @​ehmicky is looking for a remote full-time position. Specialized in Node.js back-ends and CLIs, he led Netlify Build, Plugins and Configuration for 2.5 years. Feel free to contact him on his website or on LinkedIn!


Breaking changes (not types)

const {stdout} = await execa('node', ['file.js'], {encoding: 'buffer'});
console.log(stdout); // This is now an Uint8Array
- await execa('node', ['file.js'], {encoding: null});
+ await execa('node', ['file.js'], {encoding: 'buffer'});

- await execa('node', ['file.js'], {encoding: 'utf-8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'UTF8'});
+ await execa('node', ['file.js'], {encoding: 'utf8'});

- await execa('node', ['file.js'], {encoding: 'utf-16le'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'ucs-2'});
+ await execa('node', ['file.js'], {encoding: 'utf16le'});

- await execa('node', ['file.js'], {encoding: 'binary'});
+ await execa('node', ['file.js'], {encoding: 'latin1'});
  • Passing a file path to subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() has been removed. Instead, a {file: './path'} object should be passed to the stdout or stderr option. (#​752)
- await execa('node', ['file.js']).pipeStdout('output.txt');
+ await execa('node', ['file.js'], {stdout: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeStderr('output.txt');
+ await execa('node', ['file.js'], {stderr: {file: 'output.txt'}});

- await execa('node', ['file.js']).pipeAll('output.txt');
+ await execa('node', ['file.js'], {
+	stdout: {file: 'output.txt'},
+	stderr: {file: 'output.txt'},
+});
- await execa('node', ['file.js']).pipeStdout(stream);
+ await execa('node', ['file.js'], {stdout: ['pipe', stream]});

- await execa('node', ['file.js']).pipeStderr(stream);
+ await execa('node', ['file.js'], {stderr: ['pipe', stream]});

- await execa('node', ['file.js']).pipeAll(stream);
+ await execa('node', ['file.js'], {
+	stdout: ['pipe', stream],
+	stderr: ['pipe', stream],
+});
  • The subprocess.pipeStdout(), subprocess.pipeStderr() and subprocess.pipeAll() methods have been renamed to subprocess.pipe(). The command and its arguments can be passed to subprocess.pipe() directly, without calling execa() a second time. The from piping option can specify 'stdout' (the default value), 'stderr' or 'all'. (#​757)
- await execa('node', ['file.js']).pipeStdout(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js']);

- await execa('node', ['file.js']).pipeStderr(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'stderr'});

- await execa('node', ['file.js']).pipeAll(execa('node', ['other.js']));
+ await execa('node', ['file.js']).pipe('node', ['other.js'], {from: 'all'});
- await execa('node', ['file.js'], {signal: abortController.signal});
+ await execa('node', ['file.js'], {cancelSignal: abortController.signal});
try {
	await execa('node', ['file.js']);
} catch (error) {
- if (error.killed) {
+ if (error.isTerminated) {
		// ...
	}
}
- subprocess.cancel();
+ subprocess.kill();
- const subprocess = execa('node', ['file.js']);
- subprocess.kill('SIGTERM', {forceKillAfterTimeout: 1000});
+ const subprocess = execa('node', ['file.js'], {forceKillAfterDelay: 1000});
+ subprocess.kill('SIGTERM');
  • The verbose option is now a string enum instead of a boolean. false has been renamed to 'none' and true has been renamed to 'short'. (#​884)
- await execa('node', ['file.js'], {verbose: false});
+ await execa('node', ['file.js'], {verbose: 'none'});

- await execa('node', ['file.js'], {verbose: true});
+ await execa('node', ['file.js'], {verbose: 'short'});
- await execa('node', ['file.js'], {execPath: './path/to/node'});
+ await execa('node', ['file.js'], {nodePath: './path/to/node'});
- subprocess.send({example: true, getExample() {}});
+ subprocess.send({example: true});
const subprocess = execa('node', ['file.js']);
- setTimeout(() => {
	subprocess.stdout.pipe(process.stdout);
- }, 0);
- const subprocess = execa('node', ['file.js'], {killSignal: 'sigterm'});
+ const subprocess = execa('node', ['file.js'], {killSignal: 'SIGTERM'});

- subprocess.kill('sigterm');
+ subprocess.kill('SIGTERM');

Features

Execution
Text lines
Piping multiple subprocesses
Input/output
Streams
Verbose mode
Debugging
Errors
Termination
Node.js files
Synchronous execution
Inter-process communication
Input validation

Bug fixes


Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
@preact/signals (source) ^2.0.5 -> ^2.2.0 age adoption passing confidence
@types/react (source) ^18.3.22 -> ^18.3.23 age adoption passing confidence
@vitejs/plugin-react (source) ^4.5.0 -> ^4.5.1 age adoption passing confidence
@vue/compiler-sfc (source) ^3.5.15 -> ^3.5.16 age adoption passing confidence
preact (source) ^10.26.7 -> ^10.26.8 age adoption passing confidence
svelte (source) ^5.33.2 -> ^5.33.14 age adoption passing confidence
vue (source) ^3.5.15 -> ^3.5.16 age adoption passing confidence

Release Notes

preactjs/signals (@​preact/signals)

v2.2.0

Compare Source

Minor Changes
Patch Changes

v2.1.1

Compare Source

Patch Changes

v2.1.0

Compare Source

Minor Changes
vitejs/vite-plugin-react (@​vitejs/plugin-react)

v4.5.1

Compare Source

Add explicit semicolon in preambleCode #​485

This fixes an edge case when using HTML minifiers that strips line breaks aggressively.

vuejs/core (@​vue/compiler-sfc)

v3.5.16

Compare Source

Reverts
preactjs/preact (preact)

v10.26.8

Compare Source

Fixes

sveltejs/svelte (svelte)

v5.33.14

Compare Source

Patch Changes
  • Revert "feat: enable TS autocomplete for Svelte HTML element definitions" (#​16063)

  • fix: destructuring snippet arguments (#​16068)

v5.33.13

Compare Source

Patch Changes
  • fix: avoid recursion error in EachBlock visitor (#​16058)

v5.33.12

Compare Source

Patch Changes
  • fix: correctly transform reassignments to class fields in SSR mode (#​16051)

v5.33.11

Compare Source

Patch Changes
  • fix: treat transitive dependencies of each blocks as mutable in legacy mode if item is mutated (#​16038)

v5.33.10

Compare Source

Patch Changes
  • fix: use fill: 'forwards' on transition animations to prevent flicker (#​16035)

v5.33.9

Compare Source

Patch Changes
  • fix: put expressions in effects unless known to be static (#​15792)

v5.33.8

Compare Source

Patch Changes
  • fix: only select_option if 'value' is in next (#​16032)

v5.33.7

Compare Source

Patch Changes
  • fix: bind:value to select with stores (#​16028)

v5.33.6

Compare Source

Patch Changes
  • fix: falsy attachments on components (#​16021)

  • fix: correctly mark elements as selected during SSR (#​16017)

v5.33.5

Compare Source

Patch Changes
  • fix: handle derived destructured iterators (#​16015)

  • fix: avoid rerunning attachments when unrelated spread attributes change (#​15961)

v5.33.4

Compare Source

Patch Changes
  • fix: narrow defaultChecked to boolean (#​16009)

  • fix: warn when using rest or identifier in custom elements without props option (#​16003)

v5.33.3

Compare Source

Patch Changes
  • fix: allow using typescript in customElement.extend option (#​16001)

  • fix: cleanup event handlers on media elements (#​16005)


Configuration

📅 Schedule: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

withastro/astro

Changes

Apply the image best practices described in the docs to hero images of examples/blog:

  • update the blog schema to change heroImage type from string to image
  • move the placeholder images from /public to /src/assets
  • update the sample blog posts' frontmatter with the new heroImage paths
  • update the templates to use the <Image /> component for hero images
  • update the about page hero image

Testing

These changes were applied in GitHub Codespaces and tested by running pnpm --filter @example/blog run test.

Docs

These changes make the hero images in the blog example comply with the practices recommended in the existing documentation. I don't think a documentation update is needed.


Last fetched:  |  Scheduled refresh: Every Saturday

See Customizing GitHub Activity Pages to configure your own

Inspired by prs.atinux.com