Skip to content

Conversation

@matthewp
Copy link
Contributor

@matthewp matthewp commented Dec 6, 2025

Description (required)

Adds Zod 4 under the "Dependency Upgrades" section.

Mostly just refers to the Zod 4's own migration guide.

Related issues & labels (optional)

For Astro version: 6.x. See astro PR #14956.

@astrobot-houston
Copy link
Contributor

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
en/guides/upgrade-to/v6.mdx Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@netlify
Copy link

netlify bot commented Dec 6, 2025

Deploy Preview for astro-docs-2 ready!

Name Link
🔨 Latest commit f24ed9c
🔍 Latest deploy log https://app.netlify.com/projects/astro-docs-2/deploys/693432a7bbdf5c000879ad72
😎 Deploy Preview https://deploy-preview-12848--astro-docs-2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@sarah11918 sarah11918 added the 6.0 label Dec 8, 2025
@sarah11918 sarah11918 added this to the v6.0.0 docs milestone Dec 8, 2025
@sarah11918
Copy link
Member

Thanks, @matthewp !

Also checking that none of these examples here where we describe using Zod for content collections look outdated to you? (This whole section on "Defining the collection schema" including the subsections for defining data types and collection references): https://deploy-preview-12322--astro-docs-2.netlify.app/en/guides/content-collections/#defining-datatypes-with-zod

We also do mention and show examples of Zod schemas on the actions page, but it's probably the two sections here about validation where we have text/examples that we should double check are still accurate for Zod 4: https://deploy-preview-12322--astro-docs-2.netlify.app/en/guides/actions/#using-validators-with-form-inputs

Lastly, even though Zod's migration guide shows everything, I would suspect there would be some changes that are common that most people would have to make to content collections schemas that are worth showing here, a way of focusing their attention on things that they'd very likely have to deal with. Can you suggest what some of those might be? If for example there were one or two things ONLY thing that will affect the majority of people, but maybe that's all they need to do, it would be much better for us to show those here. If it would be possible to help a number of people avoid needing to go to Zod's guide at all, then we really should do that.

@ArmandPhilippot
Copy link
Member

In addition to what Sarah just said, I noticed another change in the implementation regarding the use of the image() helper:

-heroImage: image().optional(),
+heroImage: z.optional(image()),

Does this mean that image() is no longer chainable with Zod 4? Does this also apply to reference()? Since both are specific to Astro, we might need to say something about them in our upgrade guide.

@matthewp
Copy link
Contributor Author

matthewp commented Dec 8, 2025

@sarah11918

Also checking that none of these examples here where we describe using Zod for content collections look outdated to you?

Yes, I wasn't sure if updating other docs was in scope for these PRs or not, since in the last one it was not. Happy to update other docs though, just tell me.

Lastly, even though Zod's migration guide shows everything, I would suspect there would be some changes that are common that most people would have to make to content collections schemas that are worth showing here, a way of focusing their attention on things that they'd very likely have to deal with. Can you suggest what some of those might be?

Not really, no. I can only say what was common in updating Astro itself, but I wouldn't presume that holds over to CC users. For example .default() was a bit of a problem for Astro but I don't know if users are going to need that a lot for CC (I wouldn't see a need for it personally). So I'd be afraid giving advice here would just be inaccurate. Perhaps when we have people upgrading it will reveal what's common?

@matthewp
Copy link
Contributor Author

matthewp commented Dec 8, 2025

@ArmandPhilippot

Does this mean that image() is no longer chainable with Zod 4? Does this also apply to reference()? Since both are specific to Astro, we might need to say something about them in our upgrade guide.

It should still be chainable, I'll check to confirm.

@sarah11918
Copy link
Member

Just noting that we're holding on this one as some aspects of the implementation PR might determine what kind of guidance is needed here!

@matthewp
Copy link
Contributor Author

matthewp commented Dec 9, 2025

@sarah11918 Which aspects? So I can unblock if possible.

@sarah11918
Copy link
Member

@matthewp We were waiting on whether or not reference() and image() were going to have to update re: the chaining question. (If so, we'd need to say that here.) But, it looks like that was a bug that was fixed, and we don't need to provide that specific guidance anymore!

@sarah11918
Copy link
Member

Seeing #12866 and that some of our Action code samples had to update makes me think that mentioning some of Zod's changes ourself is probably helpful. Expecially if people have followed our code examples, and we are updating examples in docs, that's probably a good indication of what's common enough to include as some additional helpful content.

So, in the Actions guide, we saw our own examples update from z.string().email() and z.string.url() to just z.email() and z.url(). We could therefore include something like:

Many string() formats have been deprecated (e.g. email(), url()), and their APIs have been moved to the top-level z namespace. You may need to update how you validate form input for your Astro Actions.

Presumably the default()/prefault() shenanigans are similarly worth pointing out in particular that people may very well need to go see what to do there, but is there anything else?

@ArmandPhilippot
Copy link
Member

I think what you mentioned could be the most commonly used. Except that, maybe customizing errors?

For people using Zod on the client (e.g. a form) and having implemented i18n, they probably customized the error messages because every errors were in English in Zod 3. The message property is replaced with error and the errorMap no longer exists. Now, Zod has built-in translations... but it seems we might not ship this (this feature is in zod/core).

And, yes, we should mention Actions schema in addition to content collections!

@matthewp
Copy link
Contributor Author

Do I need to update the examples/docs in this PR to their proper v4 usage?

@sarah11918
Copy link
Member

sarah11918 commented Dec 10, 2025

Hi @matthewp , sorry there hasn't been a lot of direct actionable instructions on this PR as Armand and I have kind of been discussing what might need to be said!

I have taken a quick look through all the content collections material we show and I think I only saw one stray z.string().url() but otherwise, our content collections/astro:content/loader API docs and (thanks to Armand) our Actions docs should all be updated.

So here's what you can do:

  • on the content-collections.mdx page, update z.string().url() to the Zod4 z.url(). As far as I can tell, I think Armand and I have caught everything else in code samples.

  • I will suggest here a short blurb reminding people to check their actions because common validation syntax like z.string().url() and z.string().email() have changed. Can you please write a little something similar about whatever the heck is going on with default() that people might need to know? ("similar" in the sense that you don't have to be the Zod 4 upgrade guide, but rather just pointing it out as something to look for in that guide because we expect this might affect a significant number of people?)

  • It looks like Armand thinks pointing out something about translatable error messages might be a thing, too. If people will need to update their error messages as a result of this, please also add a "similar" point about that. Again, the goal is only to point people to the common things in that whole guide that we already know a lot of people will need to know, so we can help focus their attention to those common things.

I think that's all we'll do for now. As we notice people trying the beta and maybe struggling with the upgrade on certain things, we might later decide to add more specific guidance here.


#### What should I do?

If you have custom Zod schemas in your `content.config.ts` or other configuration files, you'll need to update them for Zod 4. Refer to the [Zod migration guide](https://zod.dev/v4/changelog) for detailed changes in the Zod API.
Copy link
Member

@sarah11918 sarah11918 Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you have custom Zod schemas in your `content.config.ts` or other configuration files, you'll need to update them for Zod 4. Refer to the [Zod migration guide](https://zod.dev/v4/changelog) for detailed changes in the Zod API.
If you have custom Zod schemas in your `content.config.ts` or other configuration files, you'll need to update them for Zod 4. Refer to the [Zod migration guide](https://zod.dev/v4/changelog) for detailed changes in the Zod API.
Notably, many `string()` formats have been deprecated (e.g. `z.string().email()`, `z.string.url()`), and their APIs have been moved to the top-level `z` namespace. You may need to update how you validate form input for your Astro Actions:
```ts title="src/actions/index.ts" ins={8} del={7}
import { defineAction } from 'astro:actions';
import { z } from 'astro/zod';
export const server = {
newsletter: defineAction({
accept: 'form',
input: z.object({
email: z.string().email(),
email: z.email(),
terms: z.boolean(),
}),
handler: async ({ email, terms }) => { /* ... */ },
})
}
```


If you have custom Zod schemas in your `content.config.ts` or other configuration files, you'll need to update them for Zod 4. Refer to the [Zod migration guide](https://zod.dev/v4/changelog) for detailed changes in the Zod API.

You can import Zod from `astro/zod` to ensure you're using the same version of Zod that Astro uses internally:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can import Zod from `astro/zod` to ensure you're using the same version of Zod that Astro uses internally:
You can ensure you're the same version of Zod that Astro uses internally by [importing Zod from `astro/zod`](#deprecated-astroschema-and-z-from-astrocontent).

This doesn't have quite the same nuance you were getting at, but I think for our intended audience it's clear guidance that will they can follow for a successful upgrade and it also links to the other entry about Zod imports where we've deprecated importing from other places. So I think it's good "upgrade material."

import { z } from 'astro/zod';
```

<ReadMore>See more about [defining collection schemas with Zod](/en/guides/content-collections/#defining-datatypes-with-zod).</ReadMore>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<ReadMore>See more about [defining collection schemas with Zod](/en/guides/content-collections/#defining-datatypes-with-zod).</ReadMore>
<ReadMore>See more about [the `astro/zod` module](/en/reference/modules/astro-zod/).</ReadMore>

Thanks to Armand, we have a much better link now! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants