payload icon indicating copy to clipboard operation
payload copied to clipboard

Error while loading some /admin styles

Open wellitongervickas opened this issue 1 year ago • 8 comments

Link to reproduction

No response

Describe the Bug

I'm not sure what i'm doing wrong, but installing the latest beta version (113), my admin is not loading the css: Image

Already updated (payload) folder withing the also the latest version using create-payload-app to copy files

To Reproduce

payload config

import { vercelPostgresAdapter } from '@payloadcms/db-vercel-postgres'
import {
  lexicalEditor,
  LinkFeature,
  UploadFeature,
  InlineToolbarFeature,
  FixedToolbarFeature,
  HTMLConverterFeature,
} from '@payloadcms/richtext-lexical'
import path from 'path'
import { buildConfig } from 'payload'
import { fileURLToPath } from 'url'
import sharp from 'sharp'
import { vercelBlobStorage } from '@payloadcms/storage-vercel-blob'
import { Users } from '@/lib/payloadcms/collections/Users'
import { Media } from '@/lib/payloadcms/collections/Media'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { my } from '@/lib/payloadcms/plugins'
import { formBuilderPlugin } from '@payloadcms/plugin-form-builder'
import { anyone, noOne } from '@/lib/payloadcms/plugins/utils/validate-role'
import { fields } from '@/lib/payloadcms/plugins/fields'

const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)

export default buildConfig({
  // cors: process.env.NODE_ENV === 'production' ? [process.env.NEXT_DEFAULT_APP_URL!] : ['*'],
  // csrf: process.env.NODE_ENV === 'production' ? [process.env.NEXT_DEFAULT_APP_URL!] : ['*'],
  admin: {
    user: Users.slug,
    importMap: {
      baseDir: path.resolve(dirname),
    },
  },
  graphQL: {
    schemaOutputFile: path.resolve(
      dirname,
      'lib/payloadcms/plugins/graphql/schemas/default.graphql',
    ),
  },
  collections: [Users, Media],
  editor: lexicalEditor({
    features({ defaultFeatures, rootFeatures }) {
      return [
        ...defaultFeatures,
        HTMLConverterFeature(),
        InlineToolbarFeature(),
        FixedToolbarFeature({
          applyToFocusedEditor: true,
        }),
        LinkFeature({
          // Example showing how to customize the built-in fields
          // of the Link feature
          fields: ({ defaultFields }) => [
            ...defaultFields,
            {
              name: 'rel',
              label: 'Rel Attribute',
              type: 'select',
              hasMany: true,
              options: ['noopener', 'noreferrer', 'nofollow'],
              admin: {
                description:
                  'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
              },
            },
          ],
        }),
        UploadFeature({
          collections: {
            uploads: {
              // Example showing how to customize the built-in fields
              // of the Upload feature
              fields: [
                {
                  name: 'caption',
                  type: 'richText',
                  editor: lexicalEditor(),
                },
              ],
            },
          },
        }),
        ...rootFeatures,
      ]
    },
  }),
  secret: process.env.PAYLOAD_SECRET || '',
  typescript: {
    outputFile: path.resolve(dirname, 'lib/payloadcms/types/payload-types.ts'),
  },
  db: vercelPostgresAdapter({
    pool: {
      connectionString: process.env.POSTGRES_URL,
    },
  }),
  sharp,
  /// dev: the order of plugins is important
  plugins: [
    vercelBlobStorage({
      enabled: true, // Optional, defaults to true
      // dev: Specify which collections should use Vercel Blob
      collections: {
        [Media.slug]: true,
      },
      // dev:Token provided by Vercel once Blob storage is added to your Vercel project
      token: process.env.BLOB_READ_WRITE_TOKEN!,
      cacheControlMaxAge: 31536000,
    }),
    my.plugin(),
    seoPlugin({
      collections: [`pages`, `events_posts`, `news_posts`, `articles_posts`],
      uploadsCollection: `media`,
      generateTitle: async ({ doc }) => {
        return `${doc.title} `
      },
      generateDescription: ({ doc }) => doc.excerpt,
    }),
    formBuilderPlugin({
      fields: {
        // text: true,
        // textarea: true,
        // select: true,
        email: true,
        // state: true,
        // country: true,
        // checkbox: true,
        // number: true,
        // message: true,
        // payment: false,
      },
      formOverrides: {
        slug: 'forms',
        access: {
          read: anyone,
          update: noOne,
        },
        fields: ({ defaultFields }) => {
          return [
            ...fields.utils.slug({
              slugFieldProps: {
                fieldToFormat: 'title',
                unique: true,
              },
            }),
            ...defaultFields,
          ]
        },
      },
    }),
  ],
})

Root layout (app folder)

import type { ReactNode } from 'react'
import { ServiceProvider } from '@/lib/services/graphql/components/Provider'
import { Registry } from '@/app/Registry'
import { headers } from 'next/headers'

import '@/lib/ui/styles/default.css'

import { Viewport } from 'next'

import { fonts } from '@/lib/ui/fonts'
import classNames from 'classnames'

import LayoutAdmin from '@/app/(payload)/layout'

export type DefaultProps = {
  children: ReactNode
  params: Promise<Record<string, any>>
}

export const viewport: Viewport = {
  width: `device-width`,
  initialScale: 1,
}

const Layout = async ({ children, ...rest }: DefaultProps) => {
  // Get the headers (includes request URL)
  const headersData = await headers()
  const currentPath = headersData.get('referer')

  // If path is /admin, avoid rendering custom layout
  if (currentPath?.includes('/admin/')) {
    // Return null or minimal structure to prevent duplication
    return children
  }
  return (
    <html lang="en">
      <body className={classNames([fonts.variable, 'relative'])}>
        <Registry>
          <ServiceProvider>{children}</ServiceProvider>
        </Registry>
      </body>
    </html>
  )
}

export default Layout

Payload Version

v3.0.0-beta.113

Adapters and Plugins

No response

wellitongervickas avatar Oct 14 '24 19:10 wellitongervickas

Hey @wellitongervickas,

This observed behavior is a symptom of preflight styles (from something like TailwindCSS) impacting the layers that Payload puts its' styles into. A simple fix is to check your layout.tsx location and ensure you're not importing the preflight into the (Payload) location.

Let me know if this isn't the case. There were somewhat recent changes to how Payload ships its' styles.

akhrarovsaid avatar Oct 14 '24 19:10 akhrarovsaid

I'll change to get this from sub routers layout instead and check if work

wellitongervickas avatar Oct 14 '24 19:10 wellitongervickas

It worked, just removing reference of Tailwind from (payload)

wellitongervickas avatar Oct 14 '24 20:10 wellitongervickas

Happy to hear you found a solution! Will close accordingly.

jmikrut avatar Oct 15 '24 14:10 jmikrut

Found a solution moving my files to src/app/(frontend)/ folder 😀

GusLyon avatar Oct 16 '24 07:10 GusLyon

This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.

github-actions[bot] avatar Oct 18 '24 04:10 github-actions[bot]