Importing Payload components causes SyntaxError on the front-end when using next-payload

default discord avatar
imcorfitz
2 months ago

I have tried to add a color-picker field to a global in Payload, but the moment I call the useField hook or useFieldType hook, it seems that the front-end is having issues - outputting following in the terminal:



- error /my-app/node_modules/payload/dist/admin/components/forms/Label/index.scss:1
@import '../../../scss/styles.scss';
^

SyntaxError: Invalid or unexpected token
    at internalCompileFunction (node:internal/vm:73:18)
    at wrapSafe (node:internal/modules/cjs/loader:1176:20)
    at Module._compile (node:internal/modules/cjs/loader:1218:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/my-app/node_modules/payload/dist/admin/components/forms/Label/index.js:10:1)
    at Module._compile (node:internal/modules/cjs/loader:1254:14) {
  digest: undefined
}


https://github.com/payloadcms/next-payload/issues/45


Importing Payload components causes SyntaxError on the front-end when using next-payload



## How to replicate



1. Spin up a new next installation.


2. Follow the

next-payload

installation directions.


3. Create a

Field.tsx

file in the

payload

directory with following:


import React from "react";
import { Label } from "payload/components/forms";
import { Props } from "payload/components/fields/Text";

const LabelField: React.FC<Props> = (props) => {
  const { path, required, label } = props;

  return (
    <div>
      <Label htmlFor={path} label={label} required={required} />
    </div>
  );
};

export default LabelField;


4. Update

payload.config.ts

as follows:


import path from "path";
import { buildConfig } from "payload/config";
import Field from "./Field";

export default buildConfig({
  collections: [
    // Your collections here
  ],
  globals: [
    // Your globals here
    {
      slug: "header",
      fields: [
        {
          name: "custom",
          type: "text",
          admin: {
            components: {
              Field,
            },
          },
        },
      ],
    },
  ],
  typescript: {
    outputFile: path.resolve(__dirname, "../payload-types.ts"),
  },
});


5. Finally call the

getPayloadClient()

function on the front-end e.g. by updating the default

layout.tsx

file like this:


import getPayloadClient from '@/payload/payloadClient'
import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

async function getSiteSettings() {
  const payload = await getPayloadClient();

  return {};
}


This will cause the error on the front-end. And if one goes in the the

Field.tsx

file and simply remove the imported

<Label />

component from Payload, then no errors appear.



I have also tried not to use the Payload components, but when I call the

useField()

hook, it causes the same error.



---


It should be noted, that the CMS however is fully working even with imported Payload components. It is only the Next.js front-end when initialising the payloadClient, that breaks.



And there are also no issues using payload plugins such as the

seo

plugin which (though compiled) also imports the Payload resources and create custom components. So I guess I would have to create my color picker component as a separate plugin, compile it and then install it.



Actually - I take that back. I just tried to update to the latest Next.js version. Now I am not using my own custom component, but

plugin-seo

causes issues.





I think we can conclude this is due to something Next.js does.

next-payload

is facing a few limitations thereof. I just tried to set up a bare-bone

next-payload

installation, and simply by installing

@payloadcms/plugin-seo

and adding following to the

payload.config.ts

the site breaks.


 plugins: [
    seo({
      collections: [],
    }),
  ],


So basically - If you are using Next.js version

next@13.4.9

and DON'T use custom components that import resources from Payload - then it seems to be working fine. Also with SEO plugin.



I wonder if this can have anything to do with how Next.js transpiles 3rd party plugins 🤔 Since it always is a syntax error because of

@import ../../../../styles.scss


This has been resolved thanks to a reply made in GitHub. Basically Next.js requires you to forcefully make your custom components client components when using

next-payload

. So adding

'use client'

in the top of your custom component file does the trick. However it doesn't solve the issue with

@payloadcms/plugin-seo

as you can't add

'use client'

to that code. Here you have to add it to

transpilePackages: ["@payloadcms/plugin-seo"],

to next.config.js

    Open the post
    Continue the discussion in Discord
    Like what we're doing?
    Star us on GitHub!

    Star

    Connect with the Payload Community on Discord

    Discord

    online

    Can't find what you're looking for?

    Get help straight from the Payload team with an Enterprise License.