Refined the grammar and structure of the usage note for
`vercelPostgresAdapter`. Replaced the ambiguous phrase "If when using"
with "If you are using" for better readability and clarity.
Continuation of #10540. Passes server props to custom label components
rendered within table columns, such as the list view. This way custom
server components can have access to `payload`, `i18n`, etc. as
expected.
After merging this PR: https://github.com/payloadcms/payload/pull/10169
the estonian language pack has been published, but since the translation
type was not correct, it meant en wasn't used as a fallback lanugage,
which resulted the whole app to crash:
In the Browser the following error is shown, if Estonian language is
picked.
```
Error: Cannot read properties of undefined (reading 'default')
at resolveErrorDev (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@15.1.3_react-dom@19.0.0_react@19.0.0__react@19.0.0_sass@1.77.4/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js:1792:63)
at processFullStringRow (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@15.1.3_react-dom@19.0.0_react@19.0.0__react@19.0.0_sass@1.77.4/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js:2071:17)
at processFullBinaryRow (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@15.1.3_react-dom@19.0.0_react@19.0.0__react@19.0.0_sass@1.77.4/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js:2059:7)
at progress (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@15.1.3_react-dom@19.0.0_react@19.0.0__react@19.0.0_sass@1.77.4/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js:2262:17)
```
Fixes #
This is now fixed by adding the correct type to the translation object.
### What?
The documentation for `addFieldRow` and `replaceFieldRow` was not
updated during the v2 -> v3 update.
### How?
Updates the documentation for `addFieldRow` and `replaceFieldRow`.
Fixes#9244
Since postgres uses number IDs by default, when we were storing the
relationship field value with postgres we weren't able to query it
This fixes that problem by casting the ID to always a string making it
safe for querying inside the JSON field
In PR https://github.com/payloadcms/payload/pull/9507, which aims to
enable only used formats to be enabled in lexical, the
`TEXT_TYPE_TO_FORMAT` constant in the lexical library was altered. This
means it becomes impossible to create a feature relying on the
`highlight` format. I am of the opinion that this should not be the
case; and have used this for a lexical feature in one of my projects.
The type of `enabledFormats` of the `createClientFeature` function
should also be updated to reflect the availability of the format.
This PR aims to:
- Remove the alteration to the library constant
- Update type of `enabledFormats`
### What?
The list view was throwing a hydration error for date fields.
### Why?
The issue really stems from the fact that cells are client rendered. We
dynamically load the dateFNS Locale object at runtime to keep the bundle
size small — which makes sense. But on the first render that means we do
not have the Locale object from the known locale so the server/client
determines what to render it as. This causes a mismatch when hydrating.
In the future I think cells could be server rendered and that would
solve the need for this fix which adds "Loading..." while the dateFNS
Locale is loaded.
I think server rendering the cells would allow us to import the dateFNS
Locale inline (blocking) and then pass the rendered string down to the
list view. This should work because we **know** the locale on the
server.
### How?
In this PR, it adds a "Loading..." fallback for the date cell if the
dateFNS Locale has not loaded yet.
Fixes#10044
Fixes#10529. The `req.locale` property within collection and global
access control functions does not reflect the current locale. This was
because we were attaching the locale to the req only _after_ running
`payload.auth`, which attempts to get access control without a
fully-formed req. The fix is to first authenticate the user using the
`executeAuthStrategies` operation directly, then determine the request
locale with that user, and finally get access results with the proper
locale.
This PR adds `cacheTags: boolean` (default `true`) to allow users to
disable the appended document updatedAt value in the case of hosting
with third party CDNs which may not allow additional search params and
throw an error.
It also fixes how we append this value to consider the case where the
URL already contains parameters and appends it with `&` instead.
In the future `cacheTags` can be made an object to allow granularity for
disabling `eTag` headers used for caching as well.
The cache tag control should help with these two issues:
- Fixes https://github.com/payloadcms/payload/issues/9880
- Fixes https://github.com/payloadcms/payload/issues/9993
The appending of the value correctly addresses this:
- Fixes https://github.com/payloadcms/payload/issues/10139
Fixes https://github.com/payloadcms/payload/issues/10436
Fixes an issue where drafts' updatedAt timestamp is not being updated.
We weren't updating the `versionData` to have the right timestamp in the
saveVersion operation when drafts were being updated.
Added e2e tests to make sure 'Last Modified' is always different in both
autosave and non-autosave drafts.
This should fix it https://github.com/payloadcms/payload/issues/10387
I don't know why we had 2 different copies of normalizeMarkdown.
Also, the most up-to-date one still had a bug where lines were
considered as if they were inside codeblocks when they weren't.
How I tested that it works:
1. I copied the `normalizeMarkdown` implementation from this PR into the
website repo, and made sure it is called before the conversion to
editorState.
2. In the admin panel, sync docs.
3. In the admin panel, refresh mdx to lexical (new button, below sync
docs).
4. Look for the examples from bug #10387 and verify that they have been
resolved.
An extra pair of eyes would be nice to make sure I'm not getting
confused with the imports.
### What?
Consolidates logic in update and updateByID. These two operations used a
lot of the same core functionality. This is a QOL improvement for future
features/fixes on each operation. You will not need to make changes to
both operations now.
### Why?
Recently we released a feature for `publishSpecificLocale` and that was
only implemented on the updateByID operation. I think future
enhancements and fixes may suffer the same treatment.
### How?
Moves shared logic into a new file with a function called
`updateDocument`.
### What?
This PR fixes a minor issue in `richtext-lexical` where editor
placeholders were not localized.
### Why?
To allow users to localize placeholders accordingly with their language
preferences in config.
### How?
By evaluating the placeholder in the editor RSC, if any is provided. The
`ContentEditable` component falls back to a default in the event that no
placeholder was provided as this was the existing behavior.
Fixes#10518
The `req` object returned from `initReq` does not include the `user`
property, and instead returned `user` and `i18n` _alongside_ the req
(and in the case of `i18n`, duplicately, as it was _also_ on the req).
Now, these properties exist directly on the req itself as expected. The
`initPage` function was also unnecessary instantiating a new local req
object just to override the `headers`, `url`, and `query` properties.
Instead of doing this, we now support overriding properties upon
instantiating a new req, bypassing the need to create an entirely new
object.
Fixes the utilities alias used by shadcn to a specific file renamed to
`ui.ts` from `cn.ts` since there may be other utilities installed by
shadcn depending on the components the user installs.
Co-Authored-By: Q.Tran <quan.tran@metro.digital>
Fixes https://github.com/payloadcms/payload/issues/10462
This behavior caused the fixed toolbar of the lexical editor within the
drawer to trigger overlap behavior of the fixed toolbar belonging to the
lexical editor behind the drawer.
Editors within drawers should be treated as separate, instead of being
able to form parent-child relationships between editors behind or in
nested drawers
Previously, this config:
```ts
import type { CollectionConfig } from 'payload'
export const tabSlug = 'tabs'
export const Tab: CollectionConfig = {
slug: tabSlug,
fields: [
{
type: 'tabs',
tabs: [
{
name: 'tabLocalized',
localized: true,
fields: [
{
name: 'title',
type: 'text',
},
{
name: 'array',
type: 'array',
fields: [
{
name: 'title',
type: 'text',
},
],
},
],
},
],
},
],
}
```
This call
```ts
const result = await payload.create({
collection: tabSlug,
locale: englishLocale,
data: {
tabLocalized: {},
},
})
```
Led to the following crash with the MongoDB adapter
<img width="741" alt="image"
src="https://github.com/user-attachments/assets/8d1d37de-a685-4a30-bd37-58af164108a2"
/>
This is due to how Mongoose, apparently just ignores the `minimize:
false` configuration
a83a430a3a/packages/db-mongodb/src/models/buildSchema.ts (L571)
and we, instead of `tabLocalized: { en: { } }` receive just
`tabLocalized: {}`.
This isn't an issue with group fields because we have fallback for them
a83a430a3a/packages/payload/src/fields/hooks/afterChange/promise.ts (L203)
This PR adds the same for tabs.
Fixes https://github.com/payloadcms/payload/issues/8036
This PR upgrades lexical from 0.20.0 to 0.21.0. As stated in the docs,
please ensure you're using our re-exported lexical packages instead of
installing lexical directly. E.g., import from
`@payloadcms/richtext-lexical/lexical` instead of `lexical`. Direct
lexical imports are not supported and may break.
This PR ports over all relevant PRs from the lexical playground that
have been pushed between 0.20.0 and 0.21.0. This includes a lot of bug
fixes related to tables, specifically scrollable tables and table
selection.
🤖 Automated bump of templates for v3.16.0
Triggered by user: @denolfe
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Editing fields during a locale change on slow networks can lead to
changes being reset when the new form state is returned. This is because
the fields receive new values from context when the new locale loads in,
which may have occurred _after_ changes were made to the fields. The fix
is to subscribe to a new `localeIsLoading` context which is set
immediately after changing locales, and then reset once the new locale
loads in. This also removes the misleading `@deprecated` flag from the
`useLocale` hook itself.
**Description:**
- [x] Replaces the [SKIPPED] entry with the correct translation for
"Blockquote".
- [x] I have read and understand the CONTRIBUTING.md document in this
repository.
**Type of Change:**
- [x] Bug fix (non-breaking change which fixes an issue).
**Fixes:**
1. fix the translation issue by replacing the [SKIPPED] entry with the
correct Thai translation for "Blockquote". Which I choose
"ข้อความอ้างอิง" However one might prefer other form of translation like
"คำอ้างอิง" or "กล่องข้อความอ้างอิง" which represent the 'block' with in
the 'Blockquote'
2. corrects the Thai translation for "Horizontal Rule." The translation
has been changed from "กฎแนวนอน," which was a mistranslation, to
"เส้นขอบแนวนอน" to better reflect the meaning of "Horizontal Rule" as a
visual divider or border.
docs: update beforeValidate documentation
These hooks operate similarly across the different contexts they can be
registered in, but were not sufficiently documented as such.
Signed-off-by: Steve Kuznetsov <stekuznetsov@microsoft.com>
I think some automatic formatter added the `{' '}` styling, it doesn't
render correctly. Update the formatting for this banner to remove it and
correctly refer to the `_status` field.
---------
Signed-off-by: Steve Kuznetsov <stekuznetsov@microsoft.com>
There was a `<br/>` tag, which was visible on the docs page. Also, I
removed spacing from the second tip box, to keep in consistent with tips
in other places in docs.
Previously, updates of the node fields from outside the form using
setFields did not trigger re-fetching the initial state, and thus
providing updated values to the form. This is to avoid unnecessary
re-renders of the form and unnecessary requests when setFields is
triggered from within the form.
This PR resets the initial state, thus triggering a re-render and
re-fetch of the initial state, if node.setFields is called from outside
the form. This preserves the performance optimization
The collection access endpoint, apparently, can be used without an ID as
well and the correct status code in `notFoundResponse` was missing.
Huge thanks to @akhrarovsaid
This PR auto-runs jobs only when an admin route is visited. This
solution is only temporary, as it will not work for deployments without
the admin panel that should run jobs
This PR improves how we handle REST API.
Problems before:
* `packages/next/src/routes/rest/*` had a huge amount of code that
didn't depend on next.js at all.
* `packages/next/src/routes/rest/index.ts` itself was not only huge but
also really hard to follow. Every method (`GET`, `POST` etc. was almost
full copy of another).
* `packages/next/src/utilities` had some utilities like
`headersWithCors` or `createPayloadRequest` that again, weren't depend
on next.js and potentially can be used outside of next.js.
Now:
All the logic that's not related to next.js now is inside
`packages/payload`, `packages/next/src/routes/rest/index.ts` now is only
_40_ lines instead of 900+
Functions like `headersWithCors` are now implemented and exported in
`payload`. To keep bc, we re-export them from the same path but marked
as `@deprecated`.
You can attach Payload REST API to any backend framework that uses Fetch
API (like Remix / SolidStart / Bun / Hono) if you don't need the admin
panel in your server instance, but you still want to have REST API. The
main function [`handleEndpoints`
](https://github.com/payloadcms/payload/pull/10466/files#diff-82e97630068f9fc40256f3f46e06226215ab150d16012281810586b51b0cfd51R28)
accepts `Request` and returns `Response`.
It's also doable with Express, but you'd have to convert node.js'
req/res to fetch.
The `ListPreferences` and `ColumnPreferences` types were defined
multiple times in different places, making it difficult to make changes
across the board. Now, the `ListPreferences` type is exported directly
from `payload` alongside the other preferences types, and
`ColumnPreferences` has been merged directly into this type to simplify
usage as this is not a standalone preference.
Currently, unless a locale is present in the URL search params, the
locale context is instantiated using the default locale until prefs load
in client-side. This causes the locale selector to briefly render in
with the incorrect (default) locale before being replaced by the proper
locale of the request. For example, if the default locale is `en`, and
the page is requested in `es`, the locale selector will flash with
English before changing to the correct locale, even though the page data
itself is properly loaded in Spanish. This is especially evident within
slow networks.
The fix is to query the user's locale preference server-side and thread
it into the locale provider to initialize state. Because search params
are not available within server layouts, we cannot pass the locale param
in the same way, so we rely on the provider itself to read them from the
`useSearchParams` hook. If present, this takes precedence over the
user's preference if it exists.
Since the root page also queries the user's locale preference to
determine the proper locale across navigation, we use React's cache
function to dedupe these function calls and ensure only a single query
is made to the db for each request.
If the user has tasks configured, we set up cron jobs on init.
We also make sure to only run on one instance using a instance
identifier stored in a global.
This adds a new property to the payloadCloudPlugin: `jobs`.
It is currently possible to set all types of valid JSON within the
`payload-preferences` collection via the REST API, but not the Local
API. For example, locales are currently saved as plain strings to the
`value` field, something that is only possible through REST. This is
because there is a custom POST handler that submits the data directly to
the db using the update operation itself, bypassing typical `json` field
validation. However, when using the Local API, it does not behave in the
same way, and throws a validation error instead. The fix is to add a
custom `validate` function to this field that attempts to parse the
value, and if it succeeds, returns true. This way both APIs behave the
same.
### What?
In the scheduled publish feature, it is possible to open the modal to
schedule publishing a document even before you have saved a draft. This
change removes the option to open the drawer to even attempt this.
This also fixes an issue if you do not have permission to publish, you
cannot schedule publish either.
### Why?
There were numerous problems:
1. The schedule publish events would show all other publish events for
the collection without an ID in the query
2. Scheduling a publish would not work without an ID for a document to
publish
### How?
Removes the Schedule Publish menu item and drawer if you are on a
collection without an ID or you do not have permission to publish.
Without an ID:

With an ID:

Perviously, you would always have the option to Schedule Publish.
### What?
Export the default Payload JWTAuthentication strategy function for
extending and using in your own custom auth strategies that need to rely
on JWT.
### Why?
This makes it more simple to implement your own custom auth strategy.
All you need to do is set a valid JWT token as a cookie and then import
the default auth strategy so that the user will be recognized.
### How?
Exports the function and makes it reusable by adding a to the args a
strategyName prop. In the `executeAuthStrategies` function we assign the
strategyName from the configured `auth.strategies` own `name` property.