Files
payload/examples/localization/src/payload.config.ts
Sebastian Blank f70c6fe3e7 fix(templates): wrong link in demo content (custom components) (#13024)
### What?

The "custom component" link in the dashboard of the website demo is
wrong:

![image](https://github.com/user-attachments/assets/ee716a87-c515-4561-932d-f1c1fcccfd5e)
2025-07-03 12:07:19 +00:00

215 lines
6.5 KiB
TypeScript

// storage-adapter-import-placeholder
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { payloadCloudPlugin } from '@payloadcms/payload-cloud'
import { formBuilderPlugin } from '@payloadcms/plugin-form-builder'
import { nestedDocsPlugin } from '@payloadcms/plugin-nested-docs'
import { redirectsPlugin } from '@payloadcms/plugin-redirects'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { searchPlugin } from '@payloadcms/plugin-search'
import {
BoldFeature,
FixedToolbarFeature,
HeadingFeature,
ItalicFeature,
LinkFeature,
lexicalEditor,
} from '@payloadcms/richtext-lexical'
import sharp from 'sharp' // editor-import
import { UnderlineFeature } from '@payloadcms/richtext-lexical'
import path from 'path'
import { buildConfig } from 'payload'
import { fileURLToPath } from 'url'
import Categories from './collections/Categories'
import { Media } from './collections/Media'
import { Pages } from './collections/Pages'
import { Posts } from './collections/Posts'
import Users from './collections/Users'
import { seedHandler } from './endpoints/seedHandler'
import { Footer } from './globals/Footer/config'
import { Header } from './globals/Header/config'
import { revalidateRedirects } from './hooks/revalidateRedirects'
import { GenerateTitle, GenerateURL } from '@payloadcms/plugin-seo/types'
import { Page, Post } from 'src/payload-types'
import { searchFields } from '@/search/fieldOverrides'
import { beforeSyncWithSearch } from '@/search/beforeSync'
import localization from './i18n/localization'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const generateTitle: GenerateTitle<Post | Page> = ({ doc }) => {
return doc?.title ? `${doc.title} | Payload Website Template` : 'Payload Website Template'
}
const generateURL: GenerateURL<Post | Page> = ({ doc }) => {
return doc?.slug
? `${process.env.NEXT_PUBLIC_SERVER_URL!}/${doc.slug}`
: process.env.NEXT_PUBLIC_SERVER_URL!
}
export default buildConfig({
admin: {
components: {
// The `BeforeLogin` component renders a message that you see while logging into your admin panel.
// Feel free to delete this at any time. Simply remove the line below.
beforeLogin: ['@/components/BeforeLogin'],
afterDashboard: ['@/components/AfterDashboard'],
},
importMap: {
baseDir: path.resolve(dirname),
},
user: Users.slug,
livePreview: {
breakpoints: [
{
label: 'Mobile',
name: 'mobile',
width: 375,
height: 667,
},
{
label: 'Tablet',
name: 'tablet',
width: 768,
height: 1024,
},
{
label: 'Desktop',
name: 'desktop',
width: 1440,
height: 900,
},
],
},
},
// This config helps us configure global or default features that the other editors can inherit
editor: lexicalEditor({
features: () => {
return [
UnderlineFeature(),
BoldFeature(),
ItalicFeature(),
LinkFeature({
enabledCollections: ['pages', 'posts'],
fields: ({ defaultFields }) => {
const defaultFieldsWithoutUrl = defaultFields.filter((field) => {
if ('name' in field && field.name === 'url') return false
return true
})
return [
...defaultFieldsWithoutUrl,
{
name: 'url',
type: 'text',
admin: {
condition: ({ linkType }) => linkType !== 'internal',
},
label: ({ t }) => t('fields:enterURL'),
required: true,
validate: (value: any, options: any) => {
if (options?.siblingData?.linkType === 'internal') {
return true // no validation needed, as no url should exist for internal links
}
return value ? true : 'URL is required'
},
},
]
},
}),
]
},
}),
db: mongooseAdapter({
url: process.env.DATABASE_URI || '',
}),
collections: [Pages, Posts, Media, Categories, Users],
cors: [process.env.PAYLOAD_PUBLIC_SERVER_URL || ''].filter(Boolean),
csrf: [process.env.PAYLOAD_PUBLIC_SERVER_URL || ''].filter(Boolean),
endpoints: [
// The seed endpoint is used to populate the database with some example data
// You should delete this endpoint before deploying your site to production
{
handler: seedHandler,
method: 'get',
path: '/seed',
},
],
globals: [Header, Footer],
plugins: [
redirectsPlugin({
collections: ['pages', 'posts'],
overrides: {
// @ts-expect-error
fields: ({ defaultFields }) => {
return defaultFields.map((field) => {
if ('name' in field && field.name === 'from') {
return {
...field,
admin: {
description: 'You will need to rebuild the website when changing this field.',
},
}
}
return field
})
},
hooks: {
afterChange: [revalidateRedirects],
},
},
}),
nestedDocsPlugin({
collections: ['categories'],
}),
seoPlugin({
generateTitle,
generateURL,
}),
formBuilderPlugin({
fields: {
payment: false,
},
formOverrides: {
fields: ({ defaultFields }) => {
return defaultFields.map((field) => {
if ('name' in field && field.name === 'confirmationMessage') {
return {
...field,
editor: lexicalEditor({
features: ({ rootFeatures }) => {
return [
...rootFeatures,
FixedToolbarFeature(),
HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }),
]
},
}),
}
}
return field
})
},
},
}),
searchPlugin({
collections: ['posts'],
beforeSync: beforeSyncWithSearch,
searchOverrides: {
fields: ({ defaultFields }) => {
return [...defaultFields, ...searchFields]
},
},
}),
payloadCloudPlugin(), // storage-adapter-placeholder
],
localization,
secret: process.env.PAYLOAD_SECRET!,
sharp,
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
})