Fixes an issue where pasting text over a selection will automatically
add it as a link instead of replacing the text. This is caused by poor
regex matching in the case of relative URLs.
Added tests and strengthened both absolute and relative URL matchers
### What?
When switching tenants from within a document and then navigating back
out to the list view, the tenant would not be set correctly.
### Why?
This was because we handle the tenant selector selection differently
when viewing a document.
### How?
Now when you navigate out, the page will refresh the cookie.
Also adds test suite config that shows how the dom can be used to
manipulate styles per tenant.
### What?
This PR adds information and examples on the `useSelection` and
`useStepNav` hooks.
### Why?
To provide more information on the React hooks available to end-users.
### How?
Changes to `admin/hooks.mdx`
Running `pnpm add @payloadcms/plugin-multi-tenant@beta` will install
`v.0.0.1` which is outdated:
https://www.npmjs.com/package/@payloadcms/plugin-multi-tenant?activeTab=versions
I suspect the intention was to remove `@beta` from the plugin install
instructions with yesterday's Payload `v3.18.0` release which also
bumped `plugin-multi-tenant` to `v3.18.0`, but this might have been
missed.
* introduce AbortController to the event listeners in useClickableCard
* in an attempt to avoid ugly boolean check
* suggested pattern from
https://kettanaito.com/blog/dont-sleep-on-abort-controller
<!--
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?
Add AbortController to event listeners in useClickableCard.
### Why?
Following Theo's [video](https://www.youtube.com/watch?v=2sdXSczmvNc)
about the [blog
post](https://kettanaito.com/blog/dont-sleep-on-abort-controller) about
AbortController I came across a bit of code in examples that looked a
bit ugly and thought the AbortController could simplify it a bit
(especially the checks for the DOM node in the removal part).
### How?
Just re-writing the code in a different way. Though, I admit I'm not
wholly sure where the Cards are being used and for what purpose so I
haven't checked that there is no difference to the behaviour of the
code.
Fixes #
Not so much a fix but a different way to write the removal of event
listeners.
-->
### What?
Fixes issue where the provider would throw an error and prevent the
login screen from loading if there was no user.
### Why?
Missing try/catch around tenant find for the provider. (Missed because
test suites have autoLogin: true)
### How?
Adds try/catch around find query.
### What?
Currently it is not possible to override the upload component.
### Why?
The ability to override the upload component is missing from
`renderDocumentSlots`.
### How?
Adding a check to include the custom upload component if it is
available.
This issue is holding me back from releasing a payload plugin.
Fixes#9591
Previously, we were unnecessarily passing the `ClientCollectionConfig`
down from the Table to the Client, even though the client cell
components could simply access it via the `useConfig` hook. This
resulted in redundant data being sent to the client for every single
table cell. Additionally, we were performing a deep copy of the
`ClientCollectionConfig`, which wasted both memory and CPU resources on
the server.
---------
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
Custom block row labels defined on `admin.components.Label` were not
rendering despite existing in the config. Instead, if a custom label
component was defined on the _top-level_ blocks field itself, it was
incorrectly replacing each blocks label _in addition_ to the field's
label. Now, custom labels defined at the field-level now only replace
the field's label as expected, and custom labels defined at the
block-level are now supported as the types suggest.
Previously, the beforeValidate hook was deepCopying input data. This
indirectly ensured that the passed input data was not mutated.
E.g., if you run the `payload.create` local API, you do not want that to
mutate the `data` object that is passed as an argument. This will create
issues if you attempt to use it multiple times.
This PR moves the deepCopy logic from the beforeValidate hook to the
start of the local API operation. This ensures that
- Input data is intentionally copied at the beginning which makes more
sense. Comment was added to explain why
- GraphQL and Rest operations are now faster, as we don't need to ensure
that the input data is not mutated for those => deepCopy only runs for
local API
Following https://github.com/payloadcms/payload/pull/10551, I found and
fixed a handful more bugs:
- When writing to the input, the results that were already there were
not cleaned, causing incorrect results to appear.
- the scroll was causing an infinite loop that showed repeated elements
- optimization: only the required field is selected (not required)
- refs are set to the initial value to avoid a state where nothing can
be searched
Having the `scripts` dir re-use all packages from the top-level was
getting quite unwieldy. Created new `tools` directory that is part of
the workspace. Packages are exported with the `@tools` package
namespace.
https://github.com/payloadcms/payload/pull/9962 could be considered a
breaking change - this PR restores compatibility by allowing unknown
collection slugs, while still providing type suggestions.
The custom components example no longer ran seed on init. This is done
through a preconfigured migration script that automatically runs on
startup. The `@payloadcms/graphql` package was also incorrectly
installed as a dev dependency and the lockfile was significantly out of
date. The `react` and `react-dom` packages were also pinned to v19.0.0,
with their corresponding types packages to v19.0.1. These now all match
as expected and are identified using the caret operator to ensure the
latest versions are installed.
Bumps the following dependencies:
- next
- typescript
- http-status
- nodemailer
- Payload & next versions in all templates
- Monorepo only: playwright and dotenv
Removes unused dependencies:
- ts-jest
- jest-environment-jsdom
- resend (we don't use their sdk, we only use their rest API)
Previously images would not be revalidated if they were cropped or
changed in another ways.
Now if the image is updated, they will also be updated on the frontend
whenever a post is revalidated.
There was a rogue `{/* IMAGE OF LIVE PREVIEW HERE */}` comment being
rendered in the live preview docs. Comments in this format used to be
hidden, but since moving to a new rendering pattern they now appear.
### What?
Previously, field error messages displayed in toast notifications used
the field path to reference fields that failed validation. This
path-based approach was necessary to distinguish between fields that
might share the same name when nested inside arrays, groups, rows, or
collapsible fields.
However, the human readability of these paths was lacking, especially
for unnamed fields like rows and collapsible fields. For example:
- A text field inside a row could display as: `_index-0.text`
- A text field nested within multiple arrays could display as:
`items.0.subArray.0.text`
These outputs are technically correct but not user-friendly.
### Why?
While the previous format was helpful for pinpointing the specific field
that caused the validation error, it could be more user-friendly and
clearer to read. The goal is to maintain the same level of accuracy
while improving the readability for both developers and content editors.
### How?
To improve readability, the following changes were made:
1. Use Field Labels Instead of Field Paths:
- The ValidationError component now uses the label prop from the field
config (if available) instead of the field’s name.
- If a label is provided, it will be used in the error message.
- If no label exists, it will fall back to the field’s name.
2. Remove _index from Paths for Unnamed Fields (In the validationError
component only):
- For unnamed fields like rows and collapsibles, the _index prefix is
now stripped from the output to make it cleaner.
- Instead of `_index-0.text`, it now outputs just `Text`.
3. Reformat the Error Path for Readability:
- The error message format has been improved to be more human-readable,
showing the field hierarchy in a structured way with array indices
converted to 1-based numbers.
#### Example transformation:
##### Before:
The following fields are invalid: `items.0.subArray.0.text`
##### After:
The following fields are invalid: `Items 1 > SubArray 1 > Text`
### What?
The `pasteURL` feature for Upload fields has been updated to support
both **client-side** and **server-side** URL fetching. Previously, users
could only paste URLs from the same domain as their Payload instance
(internal) or public domains, which led to **CORS** errors when trying
to fetch files from external URLs.
Now, users can choose between **client-side fetching** (default) and
**server-side fetching** using the new `pasteURL` option in the Upload
collection config.
### How?
- By default, Payload will attempt to fetch the file client-side
directly in the browser.
- To enable server-side fetching, you can configure the new `pasteURL`
option with an `allowList` of trusted domains.
- The new `/api/:collectionSlug/paste-url` endpoint is used to fetch
files server-side and stream them back to the browser.
#### Example
```
import type { CollectionConfig } from 'payload'
export const Media: CollectionConfig = {
slug: 'media',
upload: {
// pasteURL: false, // Can now disable the pasteURL option entirely by passing "false".
pasteURL: {
allowList: [
{
hostname: 'payloadcms.com', // required
pathname: '',
port: '',
protocol: 'https', // defaults to https - options: "https" | "http"
search: ''
},
{
hostname: 'example.com',
pathname: '/images/*',
},
],
},
},
}
```
### Why
This update provides more flexibility for users to paste URLs into
Upload fields without running into **CORS errors** and allows Payload to
securely fetch files from trusted domains.