Skip to content

Commit

Permalink
fix(next): threads server props to custom providers (#9412)
Browse files Browse the repository at this point in the history
When defining custom providers as server components, they currently do
not receive any of the server props that custom components expect to
receive, like `payload`, `i18n`, `user`, and so on.
  • Loading branch information
jacobsfletch authored Nov 21, 2024
1 parent 2036a56 commit f5683b0
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 8 deletions.
17 changes: 14 additions & 3 deletions packages/next/src/layouts/Root/NestProviders.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Config, ImportMap } from 'payload'
import type { Config, ImportMap, ServerProps } from 'payload'

import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent'
import '@payloadcms/ui/scss/app.scss'
Expand All @@ -8,14 +8,24 @@ type Args = {
readonly children: React.ReactNode
readonly importMap: ImportMap
readonly providers: Config['admin']['components']['providers']
readonly serverProps: ServerProps
}

export function NestProviders({ children, importMap, providers }: Args): React.ReactNode {
export function NestProviders({
children,
importMap,
providers,
serverProps,
}: Args): React.ReactNode {
return RenderServerComponent({
clientProps: {
children:
providers.length > 1 ? (
<NestProviders importMap={importMap} providers={providers.slice(1)}>
<NestProviders
importMap={importMap}
providers={providers.slice(1)}
serverProps={serverProps}
>
{children}
</NestProviders>
) : (
Expand All @@ -24,5 +34,6 @@ export function NestProviders({ children, importMap, providers }: Args): React.R
},
Component: providers[0],
importMap,
serverProps,
})
}
8 changes: 7 additions & 1 deletion packages/next/src/layouts/Root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const RootLayout = async ({

const payload = await getPayload({ config, importMap })

const { i18n, permissions, user } = await initReq(config)
const { i18n, permissions, req, user } = await initReq(config)

const dir = (rtlLanguages as unknown as AcceptedLanguages[]).includes(languageCode)
? 'RTL'
Expand Down Expand Up @@ -117,6 +117,12 @@ export const RootLayout = async ({
<NestProviders
importMap={payload.importMap}
providers={config.admin?.components?.providers}
serverProps={{
i18n,
payload,
permissions,
user,
}}
>
{children}
</NestProviders>
Expand Down
11 changes: 8 additions & 3 deletions test/admin/components/CustomProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ export const CustomProvider: React.FC<{ children: React.ReactNode }> = ({ childr
setCustom,
}

console.log('custom provider called')

return <Context.Provider value={value}>{children}</Context.Provider>
return (
<Context.Provider value={value}>
<div className="custom-provider" style={{ display: 'none' }}>
This is a custom provider.
</div>
{children}
</Context.Provider>
)
}

export const useCustom = () => useContext(Context)
17 changes: 17 additions & 0 deletions test/admin/components/CustomProviderServer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { ServerProps } from 'payload'

import React, { Fragment } from 'react'

export const CustomProviderServer: React.FC<{ children: React.ReactNode } & ServerProps> = ({
children,
payload,
}) => {
return (
<Fragment>
<div className="custom-provider-server" style={{ display: 'none' }}>
{`This is a custom provider with payload: ${Boolean(payload)}`}
</div>
{children}
</Fragment>
)
}
2 changes: 1 addition & 1 deletion test/admin/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default buildConfigWithDefaults({
Button: '/components/Logout/index.js#Logout',
},
providers: [
'/components/CustomProvider/index.js#CustomProvider',
'/components/CustomProviderServer/index.js#CustomProviderServer',
'/components/CustomProvider/index.js#CustomProvider',
],
views: {
Expand Down
16 changes: 16 additions & 0 deletions test/admin/e2e/1/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,22 @@ describe('admin1', () => {
})
})

describe('custom providers', () => {
test('should render custom providers', async () => {
await page.goto(`${serverURL}/admin`)
await expect(page.locator('.custom-provider')).toHaveCount(1)
await expect(page.locator('.custom-provider')).toContainText('This is a custom provider.')
})

test('should render custom provider server components with props', async () => {
await page.goto(`${serverURL}/admin`)
await expect(page.locator('.custom-provider-server')).toHaveCount(1)
await expect(page.locator('.custom-provider-server')).toContainText(
'This is a custom provider with payload: true',
)
})
})

describe('custom views', () => {
test('root — should render custom view', async () => {
await page.goto(`${serverURL}${adminRoutes.routes.admin}${customViewPath}`)
Expand Down

0 comments on commit f5683b0

Please sign in to comment.