prismicio / prismic-next

Helpers to integrate Prismic into Next.js apps
https://prismic.io/docs/technologies/nextjs
Apache License 2.0
57 stars 7 forks source link

Transpiling package using NextJS transpilePackages config causes issues with "use client" directive #82

Open Syphini opened 1 year ago

Syphini commented 1 year ago

Versions

Reproduction

Additional Details
``` { "name": "prismic-test", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "slicemachine": "start-slicemachine" }, "dependencies": { "@prismicio/client": "^7.2.0", "@prismicio/next": "^1.3.4", "@prismicio/react": "^2.7.1", "autoprefixer": "10.4.15", "eslint": "8.48.0", "eslint-config-next": "13.4.19", "next": "^13.4.19", "postcss": "8.4.29", "react": "18.2.0", "react-dom": "18.2.0", "tailwindcss": "3.3.3" } } ```

Steps to reproduce

  1. Run npx create-next-app@latest and npx @slicemachine/init@latest with App Router enabled
  2. In the next.config.js file add the following to the nextConfig
    const nextConfig = {
    transpilePackages: ["@prismicio/client", "@prismicio/next"]
    }
  3. Create a component as follows
    
    "use client"

import { PrismicNextLink } from "@prismicio/next"

export default function StyledLink() { return }

4. Import and render the new component into a `page.js` in your `app` directory
5. Attempt to navigate to the page with component included and see a Server Component error

### What is expected?
`PrismicNextLink` will render the same with or without the "use client" directive, as it does so when not transpiling the packages using NextJS configuration

### What is actually happening?
The new component throws the following fatal error

ReactServerComponentsError:

You're importing a component that needs next/headers. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component. Learn more: https://nextjs.org/docs/getting-started/react-essentials

1 | import { jsxs, Fragment, jsx } from "react/jsx-runtime"; 2 | import Script from "next/script"; 3 | import { draftMode } from "next/headers"; : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | import { PrismicPreviewClient } from "./PrismicPreviewClient.js"; 5 | import { getToolbarSrc } from './_node_modules/@prismicio/client/dist/getToolbarSrc.js'; 6 | function PrismicPreview({ repositoryName, children, ...props }) { `----

One of these is marked as a client entry with "use client": ./node_modules\@prismicio\next\dist\PrismicPreview.js ./node_modules\@prismicio\next\dist\index.js ./components\StyledLink.js

github-actions[bot] commented 1 year ago

This issue has been labeled as a bug since it was created using the 🚨 Bug Report Template.

Hi there, thank you so much for the report!

Following our Maintenance Process, we will review your bug report and get back to you next Wednesday. To ensure a smooth review of your issue and avoid unnecessary delays, please make sure your issue includes the following:

If you have identified the cause of the bug described in your report and know how to fix it, you're more than welcome to open a pull request address it. Check out our quick start guide for a simple contribution process.

If you think your issue is a question (not a bug) and would like quicker support, please close this issue and forward it to an appropriate section on our community forum: https://community.prismic.io

- The Prismic Open-Source Team

angeloashmore commented 1 year ago

Hi @Syphini, could you explain your use case for adding @prismicio/client and @prismicio/next to transpilePackages? Both packages should work without adding them to the transpilePackages option.

This may be happening because Next.js is bundling the packages into a single file, which causes the "use client" to be part of the whole file—not just the individual modules that need it. Just speculating; I haven't tested this yet.

Syphini commented 1 year ago

Hey @angeloashmore, I was testing the packages against an iOS 12 device with Safari 12 installed (since NextJS supports Safari 12+) , and noticed that it was throwing errors related to ES2020 features so I figured that the package wasn't natively transpiling to support them in older devices. Decided to throw both packages in the transpilePackages option of nextConfig and that seemed to allow them to work correctly on that older device until I discovered this issue.

Wasn't really sure if I should try filing a bug report with you guys or NextJS, or maybe even one about natively transpiling here. Can also provide a reproduction of the Safari 12 issue if that's something you guys do support.