- Adds documentdb and cosmosdb to CI test matrix
- Adds missing generateDatabaseAdapter configs
- Adjust generateDatabaseAdapter firestore config to make it pure to the
compatibilityOptions we provide as an export
Creating as draft because I expect a few tests to fail based on previous
comments.
---------
Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com>
Fixes#14032.
When duplicating arrays that contains nested arrays, the newly
duplicated row will include twice as many fields within the nested array
as the original.
This is because duplicated row ids don't match 1:1 with their parent's
`rows` property.
For example: `array.0.nestedArray.0.id` should match
`array.0.nestedArray.rows[0].id`.
The problem is that when we duplicate the row, we regenerate all nested
id fields, but we fail to sync them its corresponding row in its parent
field. When we go to build form state on the server, we build new fields
for this stale row. Then when we merge server form state back into local
state, those new fields are simply _merged_ with the local state without
replacing them.
This is how we determine whether local changes to a row took place while
a form state request was pending. It is important to prevent the merge
strategy from overriding your active changes.
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211543194775558
Closes https://github.com/payloadcms/payload/issues/10378
We now pass `collection` containing the current collection's config into
the `generateURL` and `generateLabel` as a third parameter.
In the future we should change this into an object so we can more easily
insert new params.
Follow up from https://github.com/payloadcms/payload/pull/14053
Add detection for `--experimental-https` flag based on `process.argv`
which may not be reliable so we're keeping the env var toggle in as well
This commit provides a comprehensive update to the Persian (fa-IR)
translation files, focusing on improving the overall user experience by
adopting a more natural, modern, and consistent tone.
The previous translations, while functional, often used overly formal,
literal, or archaic vocabulary that can feel unnatural in a modern web
application. This revision addresses these issues across all major
sections of the CMS.
Key improvements include:
- **Modern Terminology:** Replaced archaic or formal words with their
common, modern equivalents (e.g., "نگارش" -> "نسخه", "رایانامه" ->
"ایمیل", "پیوند" -> "لینک").
- **Natural Phrasing:** Rephrased verbose confirmation dialogs and
validation messages into concise, direct questions and statements that
are standard in UI/UX design.
- **Correction of Mistranslations:** Fixed incorrect translations for
key terms like `crop`, `locale`, `type` (version), and `character`
length validation.
- **Consistency:** Ensured consistent terminology for common elements
like "field", "file", "version", and "upload" across all sections.
- **Improved Flow:** Adjusted sentence structures to read more naturally
for a native Persian speaker.
It was explained in #14025 that defining indexes via collection-level
`indexes` for locale paths is not actually supported.
This removes the recommendation and configuration example, and replaces
them with workarounds provided in #14025.
Fixes: 379ef87d84
Closes https://github.com/payloadcms/payload/issues/12087
When using `--experimental-https` from Nextjs we have no way of
detecting that right now so I've added documentation on how to handle
this flag and added to support for `USE_HTTPS` to set the websocket
protocol for HMR to `wss` instead of `ws`
### What?
Adds the missing `/* webpackIgnore: true */` annotation when importing
wrangler, as in the original OpenNext patch.
### Why?
It looks like Webpack messes up the template styles when bundling the
Cloudflare template, which causes some issues such as black text on
black background or larger than usual font size.
### How?
By telling Webpack to ignore wrangler when bundling.
This solution was found by @nwong212 in the original issue, I'm just
submitting the fix after checking my self that it indeed fixes the
bundling.
Fixes#13989
Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
### What?
Adds Cache-Control headers for the static files generated by Next.js
(e.g. .js files).
This follows a recommendation by the OpenNext team:
https://opennext.js.org/cloudflare/caching#static-assets-caching
### Why?
To avoid avoiding unnecessary revalidation requests caused by Workers
Static Assets' default headers.
### How?
By caching the static files for up to an year.
Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
Optimized database queries generated by graphQL by only selecting the
fields that have been requested. This is particularly useful for
collections with fields of type "join" and "relationship"
Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
### What?
Fixes "Invalid time value" error in the DocumentLocked modal when
displaying the last edited timestamp.
### Why?
The `formatDate` function was passing a timestamp number directly to
`Intl.DateTimeFormat().format()`, which expects a Date object. When
`updatedAt` is a number (timestamp), this causes an "Invalid time value"
error.
### How?
Wrap the date parameter with `new Date()` before passing it to
`Intl.DateTimeFormat().format()` to properly convert the timestamp to a
Date object.
Fixes#14016
### What?
Adds the missing `$CLOUDFLARE_ENV` env parameter when optimizing the D1
database after deploy.
Switched from `-e` to `--env` as `-e` doesn't handle it very well when
`$CLOUDFLARE_ENV` is empty.
### Why?
Running "PRAGMA optimize" tells D1/SQLite to refresh its statistics for
the query planner. This is crucial whenever an index is added or
removed.
### How?
By adding the "--env" parameter to the `wrangler d1 execute` command
Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
### What?
Fixes the remote binding behavior so that they're only used when
deployed or when applying the database migrations.
I've also pinned the Wrangler version to prevent it breaking due to
behavior changes in minor versions.
And I took the opportunity to update the compatibility date, to one that
already includes the MessagePort by default.
### Why?
It turns out the remote binding behavior slightly changed since the beta
until the final release.
As a result, when developing locally, wrangler would connect to the
remote database, which is a big nono
### How?
By making sure the getCloudflareContext() method is not invoked outside
of NODE_ENV === 'production', as the wrangler.jsonc has the "remote"
flag as true for the D1 database and therefore will always point to the
remote database.
Fixes#14041
Co-authored-by: Ricardo Tavares <rtavares@cloudflare.com>
Follow-up to #14012.
Once live preview conditions have passed, it is jarring for the live
preview window to suddenly appear. It should be that, despite
preferences, if the live preview window did not _load_ active, then it
should not become active until the user explicitly toggles it on.
This is especially poor UX while creating a new doc. If the conditional
URL is based on a field that has't been filled yet, upon filling that
field (with autosave), live preview suddenly appears and the entire page
shifts mid-edit.
Before:
https://github.com/user-attachments/assets/0da75306-eed3-4a77-bc58-d8a8dd0254bf
After:
https://github.com/user-attachments/assets/c7918601-959d-4ac5-b168-066afc3d879d
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211534009142634
### What?
- Fixes an issue where the table header row was overlapping menu items
in the ListControls component.
### Why?
- The overlapping occurred because the table lacked proper stacking
context, causing z-index rules to affecting the visibility and usability
of menu items in the ListControls component rendered above the table.
### How?
- Added the CSS property isolation: isolate to the table styles. This
creates a new stacking context, ensuring that the table header does not
interfere with overlapping UI elements
### UI Changes:
Before:
<img width="1357" height="730" alt="image"
src="https://github.com/user-attachments/assets/703f7bbe-0cd7-4dfb-a584-a6436a0ea5d7"
/>
After:
<img width="1357" height="730" alt="image"
src="https://github.com/user-attachments/assets/927c904a-4423-420b-ad4d-0a3c4624b5ee"
/>
Fixes#13941
<!--
Thank you for the PR! Please go through the checklist below and make
sure you've completed all the steps.
Please review the
[CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md)
document in this repository if you haven't already.
The following items will ensure that your PR is handled as smoothly as
possible:
- PR Title must follow conventional commits format. For example, `feat:
my new feature`, `fix(plugin-seo): my fix`.
- Minimal description explained as if explained to someone not
immediately familiar with the code.
- Provide before/after screenshots or code diffs if applicable.
- Link any related issues/discussions from GitHub or Discord.
- Add review comments if necessary to explain to the reviewer the logic
behind a change
### What?
### Why?
### How?
Fixes #
-->
### What?
Fixes a bug where dragging a file into an upload dropzone when the
drawer is closed throws an error: "Cannot read properties of undefined".
### Why?
The `collectionConfig` variable can be undefined when the drawer is not
opened, causing the code to fail when trying to access
`collectionConfig.upload?.displayPreview`.
### How?
Added optional chaining (`?.`) to safely access `collectionConfig`,
changing `collectionConfig.upload?.displayPreview` to
`collectionConfig?.upload?.displayPreview`.
Fixes#13999
### What?
Update README to reflect template on the Vercel Template Marketplace.
### Why?
Have users setup their templates through the Template Marketplace and
Vercel Integrations.
### How?
Update 'Deploy to Vercel' link to the template link on the Template
Marketplace.
Old vs Proposed change

---------
Co-authored-by: Paul <paul@payloadcms.com>
### What?
This PR adds a new `admin.disableRowTypes` config to `'join'` fields
which hides the `"Type"` column from the relationship table.
### Why?
While the collection type column _can be_ helpful for providing
information, it's not always necessary and can sometimes be redundant
when the field only has a singular relationTo. Hiding it can be helpful
by removing visual noise and providing editors the data directly.
### How?
By threading `admin.disableRowTypes` directly to the `getTableState`
function of the `RelationshipTable` component.
**With row types** (via `admin.disableRowTypes: false | undefined` OR
default for polymorphic):

**Without row types** (default for monomorphic):

### What?
When `?locale=` is present in an admin panel URL and that admin panel
URL is visited in an unauthenticated browser, a runtime error is thrown.
### Why?
`upsertPreferences` relies on `req.user` to successfully create a new
`payload-preferences` document. When an unauthenticated user visits a
URL with a `locale` parameter, `upsertPreferences` is called but
`req.user` is not available.
### How?
Prevent `upsertPreferences` from being called when `req.user` is not
available.
Fixes#13581
Co-authored-by: Patrik Kozak <35232443+PatrikKozak@users.noreply.github.com>
Fixes https://github.com/payloadcms/payload/issues/13308
Adds support for a custom live preview component back, we previously
supported this and it was allowed via the config types but it wasn't
being rendered.
Now we export the `useLivePreviewContext` hook and the original
`LivePreviewWindow` component too so that end users can wrap the live
preview functionality with anything custom that they may need
### What?
Add various missing translations for Icelandic language and update some
of the current ones to be more human readable.
### Why?
To make it more useable in Icelandic
Supports live preview conditions. This is essentially access control for
live preview, where you may want to restrict who can use it based on
certain criteria, such as the current user or document data.
To do this, simply return null or undefined from your live preview url
functions:
```ts
url: ({ req }) => (req.user?.role === 'admin' ? '/hello-world' : null)
```
This is also useful for pages which derive their URL from document data,
e.g. a slug field, do not attempt to render the live preview window
until the URL is fully formatted.
For example, if you have a page in your front-end with the URL structure
of `/posts/[slug]`, the slug field is required before the page can
properly load. However, if the slug is not a required field, or when
drafts and/or autosave is enabled, the slug field might not yet have
data, leading to `/posts/undefined` or similar.
```ts
url: ({ data }) => data?.slug ? `/${data.slug}` : null
```
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211513433305000
### What?
Adds a new `disableGroupBy` admin config property for fields to control
their visibility in the list view GroupBy dropdown.
### Why
Previously, the GroupByBuilder was incorrectly using `disableListFilter`
to determine which fields to show in the group-by dropdown.
### How
- Added new `disableGroupBy` property to the field admin config types.
- Updated `GroupByBuilder` to filter fields based on `disableGroupBy`
instead of `disableListFilter`
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211511898438807
### What?
Fixed a typo in the ecommerce template footer component.
Changed "Crafted by Prayload" → "Crafted by Payload" in
`templates/ecommerce/src/components/Footer/index.tsx`.
### Why?
Ensures correct branding and improves professionalism of the template.
### How?
Updated the footer text string directly.
Before:
Crafted by Prayload
After:
Crafted by Payload
This PR updates the build process to generate a single
`dist/index.bundled.d.ts` file that bundles all `payload` package types.
Having one bundled declaration file makes it easy to load types into the
Monaco editor (e.g. for the new Code block), enabling full type
completion for the `payload` package.
## Example
```ts
BlocksFeature({
blocks: [
CodeBlock({
slug: 'PayloadCode',
languages: {
ts: 'TypeScript',
},
typescript: {
fetchTypes: [
{
filePath: 'file:///node_modules/payload/index.d.ts',
url: 'https://unpkg.com/payload@3.59.0-internal.e247081/dist/index.bundled.d.ts', // <= download bundled .d.ts
},
],
paths: {
payload: ['file:///node_modules/payload/index.d.ts'],
},
typeRoots: ['node_modules/@types', 'node_modules/payload'],
},
}),
],
}),
```
<img width="1506" height="866" alt="Screenshot 2025-10-01 at 12 38
54@2x"
src="https://github.com/user-attachments/assets/135b9b69-058a-42b9-afa0-daa328f64f38"
/>
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211524241290884
When you have a `hasMany: true` relationship field with at least 1 ID
that references nothing (because the actual document was deleted and
since MongoDB doesn't have foreign constraints - the relationship field
still includes that "dead" ID) graphql querying of that field fails.
This PR fixes it.
The same applies if you don't have access to some document for all DBs
### What?
This PR applies `mergeFieldStyles` to the `ArrayFieldComponent`
component, ensuring that custom admin styles such as `width` are
correctly respected when Array fields are placed inside row layouts.
### Why?
Previously, Array fields did not inherit or apply their `admin.width`
(or other merged field styles). For example, when placing two array
fields side by side inside a row with `width: '50%'`, the widths were
ignored, causing layout issues.
### How?
- Imported and used `mergeFieldStyles` within `ArrayFieldComponent`.
- Applied the merged styles to the root `<div>` via the `style` prop,
consistent with how other field components (like `TextField`) handle
styles.
Fixes#13973
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211511898438801