diff --git a/packages/next/src/templates/Default/index.tsx b/packages/next/src/templates/Default/index.tsx index 5bedabe4947..469f738819c 100644 --- a/packages/next/src/templates/Default/index.tsx +++ b/packages/next/src/templates/Default/index.tsx @@ -62,7 +62,7 @@ export const DefaultTemplate: React.FC = ({ admin: { avatar, components, - components: { header: CustomHeader, Nav: CustomNav } = { + components: { footer: CustomFooter, header: CustomHeader, Nav: CustomNav } = { header: undefined, Nav: undefined, }, @@ -189,6 +189,12 @@ export const DefaultTemplate: React.FC = ({ + {RenderServerComponent({ + clientProps, + Component: CustomFooter, + importMap: payload.importMap, + serverProps, + })} diff --git a/packages/payload/src/bin/generateImportMap/iterateConfig.ts b/packages/payload/src/bin/generateImportMap/iterateConfig.ts index 9c945e21b57..22f0025f241 100644 --- a/packages/payload/src/bin/generateImportMap/iterateConfig.ts +++ b/packages/payload/src/bin/generateImportMap/iterateConfig.ts @@ -56,6 +56,7 @@ export function iterateConfig({ addToImportMap(config.admin?.components?.Nav) addToImportMap(config.admin?.components?.header) + addToImportMap(config.admin?.components?.footer) addToImportMap(config.admin?.components?.logout?.Button) addToImportMap(config.admin?.components?.graphics?.Icon) addToImportMap(config.admin?.components?.graphics?.Logo) diff --git a/packages/payload/src/config/types.ts b/packages/payload/src/config/types.ts index a76832e8038..1f8ece93b86 100644 --- a/packages/payload/src/config/types.ts +++ b/packages/payload/src/config/types.ts @@ -805,6 +805,10 @@ export type Config = { * Add custom components before the navigation links */ beforeNavLinks?: CustomComponent[] + /** + * Add custom footer to bottom of page globally + */ + footer?: CustomComponent[] /** Replace graphical components */ graphics?: { /** Replace the icon in the navigation */ diff --git a/test/admin/components/CustomFooter/index.tsx b/test/admin/components/CustomFooter/index.tsx new file mode 100644 index 00000000000..80d7dec3904 --- /dev/null +++ b/test/admin/components/CustomFooter/index.tsx @@ -0,0 +1,27 @@ +import type { PayloadServerReactComponent, SanitizedConfig } from 'payload' + +import React from 'react' + +const baseClass = 'custom-footer' + +export const CustomFooter: PayloadServerReactComponent< + SanitizedConfig['admin']['components']['footer'][0] +> = () => { + return ( +
+

+ Here is a custom footer inserted with admin.components.footer +

+
+ ) +} diff --git a/test/admin/config.ts b/test/admin/config.ts index dbaf45e5582..ac8d46c7119 100644 --- a/test/admin/config.ts +++ b/test/admin/config.ts @@ -78,6 +78,7 @@ export default buildConfigWithDefaults({ Icon: '/components/graphics/Icon.js#Icon', }, header: ['/components/CustomHeader/index.js#CustomHeader'], + footer: ['/components/CustomFooter/index.js#CustomFooter'], logout: { Button: '/components/Logout/index.js#Logout', }, diff --git a/test/admin/e2e/general/e2e.spec.ts b/test/admin/e2e/general/e2e.spec.ts index f94839c522d..e6c39ba93ef 100644 --- a/test/admin/e2e/general/e2e.spec.ts +++ b/test/admin/e2e/general/e2e.spec.ts @@ -716,6 +716,12 @@ describe('General', () => { const header = page.locator('.custom-header') await expect(header).toContainText('Here is a custom header') }) + + test('should render custom footer', async () => { + await page.goto(`${serverURL}/admin`) + const footer = page.locator('.custom-footer') + await expect(footer).toContainText('Here is a custom footer') + }) }) describe('i18n', () => {