fix: prefetch causing stale data (#9020)

Potentially fixes #9012 by disabling prefetch for all Next.js `Link`
component usage.

With prefetch left as the default and _on_, there were cases where the
prefetch could fetch stale data for Edit routes. Then, when navigating
to the Edit route, the data could be stale.

In addition, I think there is some strangeness happening on the Next.js
side where prefetched data might still come from the router cache even
though router cache is disabled.

This fix should be done regardless, but I suspect it will solve for a
lot of stale data issues.
This commit is contained in:
James Mikrut
2024-11-04 14:24:28 -05:00
committed by GitHub
parent 6b9f178fcb
commit 35b107a103
12 changed files with 36 additions and 9 deletions

View File

@@ -67,6 +67,7 @@ export const DocumentTabLink: React.FC<{
<Link
className={`${baseClass}__link`}
href={!isActive || href !== pathname ? hrefWithLocale : ''}
prefetch={false}
{...(newTab && { rel: 'noopener noreferrer', target: '_blank' })}
tabIndex={isActive ? -1 : 0}
>

View File

@@ -98,6 +98,7 @@ export const DefaultNavClient: React.FC = () => {
href={href}
id={id}
key={i}
prefetch={Link ? false : undefined}
tabIndex={!navOpen ? -1 : undefined}
>
{activeCollection && <div className={`${baseClass}__link-indicator`} />}

View File

@@ -42,6 +42,7 @@ export const ForgotPasswordView: React.FC<AdminViewProps> = ({ initPageResult })
adminRoute,
path: accountRoute,
})}
prefetch={false}
>
{children}
</Link>
@@ -68,6 +69,7 @@ export const ForgotPasswordView: React.FC<AdminViewProps> = ({ initPageResult })
adminRoute,
path: loginRoute,
})}
prefetch={false}
>
{i18n.t('authentication:backToLogin')}
</Link>

View File

@@ -105,6 +105,7 @@ export const LoginForm: React.FC<{
adminRoute,
path: forgotRoute,
})}
prefetch={false}
>
{t('authentication:forgotPasswordQuestion')}
</Link>

View File

@@ -48,6 +48,7 @@ export const ResetPassword: React.FC<AdminViewProps> = ({ initPageResult, params
adminRoute,
path: accountRoute,
})}
prefetch={false}
>
{children}
</Link>
@@ -75,6 +76,7 @@ export const ResetPassword: React.FC<AdminViewProps> = ({ initPageResult, params
adminRoute,
path: loginRoute,
})}
prefetch={false}
>
{i18n.t('authentication:backToLogin')}
</Link>

View File

@@ -47,7 +47,7 @@ export const CreatedAtCell: React.FC<CreatedAtCellProps> = ({
}
return (
<Link href={to}>
<Link href={to} prefetch={false}>
{cellData &&
formatDate({ date: cellData as Date | number | string, i18n, pattern: dateFormat })}
</Link>

View File

@@ -94,6 +94,7 @@ export const AppHeader: React.FC = () => {
aria-label={t('authentication:account')}
className={`${baseClass}__account`}
href={formatAdminURL({ adminRoute, path: accountRoute })}
prefetch={Link ? false : undefined}
tabIndex={0}
>
<Account />

View File

@@ -121,6 +121,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
}
let buttonElement
let prefetch
switch (el) {
case 'anchor':
@@ -147,10 +148,12 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
if (disabled) {
LinkTag = 'div'
} else {
prefetch = false
}
buttonElement = (
<LinkTag {...buttonProps} href={to || url} to={to || url}>
<LinkTag {...buttonProps} href={to || url} prefetch={prefetch} to={to || url}>
<ButtonContents icon={icon} showTooltip={showTooltip} tooltip={tooltip}>
{children}
</ButtonContents>

View File

@@ -26,16 +26,21 @@ const DefaultLogout: React.FC<{
const basePath = process.env.NEXT_BASE_PATH ?? ''
const LinkElement = Link || 'a'
const props = {
'aria-label': t('authentication:logOut'),
className: `${baseClass}__log-out`,
prefetch: Link ? false : undefined,
tabIndex,
}
return (
<LinkElement
aria-label={t('authentication:logOut')}
className={`${baseClass}__log-out`}
{...props}
href={formatAdminURL({
adminRoute,
basePath,
path: logoutRoute,
})}
tabIndex={tabIndex}
>
<LogOutIcon />
</LinkElement>

View File

@@ -60,6 +60,7 @@ export const Button: React.FC<MenuButtonProps> = ({
onClick(e)
}
}}
prefetch={false}
>
{children}
</Link>

View File

@@ -34,11 +34,20 @@ const StepNav: React.FC<{
const LinkElement = Link || 'a'
const baseLinkProps = {
prefetch: Link ? false : undefined,
}
return (
<Fragment>
{stepNav.length > 0 ? (
<nav className={[baseClass, className].filter(Boolean).join(' ')}>
<LinkElement className={`${baseClass}__home`} href={admin} tabIndex={0}>
<LinkElement
className={`${baseClass}__home`}
href={admin}
tabIndex={0}
{...baseLinkProps}
>
<span title={t('general:dashboard')}>
<RenderComponent
Component={PayloadIcon}
@@ -58,7 +67,7 @@ const StepNav: React.FC<{
) : (
<Fragment key={i}>
{item.url ? (
<LinkElement href={item.url}>
<LinkElement href={item.url} {...baseLinkProps}>
<span key={i}>{StepLabel}</span>
</LinkElement>
) : (

View File

@@ -52,6 +52,7 @@ export const DefaultCell: React.FC<CellComponentProps> = (props) => {
classNameFromConfigContext
const onClick = onClickFromProps || onClickFromContext
const isLink = link !== undefined ? link : columnIndex === 0
let WrapElement: React.ComponentType<any> | string = 'span'
@@ -59,14 +60,14 @@ export const DefaultCell: React.FC<CellComponentProps> = (props) => {
className?: string
href?: string
onClick?: () => void
prefetch?: false
type?: 'button'
} = {
className,
}
const isLink = link !== undefined ? link : columnIndex === 0
if (isLink) {
wrapElementProps.prefetch = false
WrapElement = Link
wrapElementProps.href = customCellContext?.collectionSlug
? formatAdminURL({