prismicio / prismic-next

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

Preview causing infinite reloading loop in Chrome and Firefox #13

Closed draykefriesen closed 2 years ago

draykefriesen commented 2 years ago

Versions

Reproduction

Using preview in Chrome and Firefox causes infinite reloading loop. Works as expected in Safari.

Steps to reproduce

Create slicemachine Next.js project, and use this guide to set up Previews.

What is expected?

Preview to load once and not cause infinite reloading loop.

What is actually happening?

Preview is in infinite reloading loop.

dayhaysoos commented 2 years ago

Hey @draykefriesen, super weird. Going to look into this, just wanted to thank you for opening the issue in the meantime!

dayhaysoos commented 2 years ago

Hey @draykefriesen is it possible at all that you can show me a repo where this issue is happening?

jeremytenjo commented 2 years ago

Having the same issue after using https://prismic.io/docs/technologies/preview-content-nextjs

package_name: v0.1.2

guitheengineer commented 2 years ago

Same problem, I noticed if I comment the redirectToPreviewURL on pages/api/preview.js it stops reloading

import { createClient, linkResolver } from '../../utils/prismicHelpers'
import * as prismicNext from '@prismicio/next'

export default async (req, res) => {
  const client = createClient({ req })
  await prismicNext.setPreviewData({ req, res })
  // await prismicNext.redirectToPreviewURL({ req, res, client, linkResolver }) <- this line is causing an infinite reload
}

So it probably has to be something wrong with this function? https://github.com/prismicio/prismic-next/blob/db8ca224edf10b4de8384782f4bab32df69ec47f/src/redirectToPreviewURL.ts#L75-L95

chamois-d-or commented 2 years ago

Hey, @dayhaysoos Not sure if this is linked, but I had this issue of the preview in a reloading loop when I wrongly setup my preview in my prismic repository. In the domain name name I had put "http" instead of "https". When I added the "s" it fixed it. maybe it can help to solve the issue?

guitheengineer commented 2 years ago

Hey, @dayhaysoos Not sure if this is linked, but I had this issue of the preview in a reloading loop when I wrongly setup my preview in my prismic repository. In the domain name name I had put "http" instead of "https". When I added the "s" it fixed it. maybe it can help to solve the issue?

Maybe can be one problem that can cause this, but in my case Is still http because I'm using preview on localhost:3000 (as it's on the docs at this moment)

webda2l commented 2 years ago

Similar issue here.

First preview is ok (toward a domain.localhost:3000, NextJS 12.1.4), I save and preview from prismic.io and can navigate to differents page without issue. But if I modify the url address manually (just press enter), or if I do a change from prismic.io and save, it start an infinite reload loop.

Other issue, more nextJS side I think, is the fact that the preview feature seems not handling perfectly my _middleware that redirect / toward /dashboard if there is a JWT request.cookie. And so the prismic preview get me to / at first and require me to navigate again to /, to get the right /dashboard rewrite (by the _middleware handling).

angeloashmore commented 2 years ago

Hey everyone, thanks for the details. I will be looking into why this is happening and coming up with a solution.

Could everyone provide me details about their app?

  1. Do you use basePath in your app? If not, do you have any other setup that changes your app's URLs (middleware, i18n, etc.)?
  2. Are you using the recommended /api/preview and /api/exit-preview API endpoints? If not, what are they?
  3. Are you using an Incognito or some kind of private window for previews?

This will help me understand how <PrismicPreview> should support your setup, or identify extra config that is necessary for your app.

Thanks!


Some background info on why the infinite refresh happens: Prismic lets you share preview sessions with others by clicking the Get a sharable link button in the Prismic toolbar. This will only appear when you are in a preview session.

When a users visits the shared preview link, the following happens:

  1. User visits the Prismic URL.
  2. It sets a cookie that identifies the preview session.
  3. User is redirected to your app's page where the shareable preview link was created.
  4. Your app sees the Prismic cookie, but also sees that Next.js's Preview Mode is not active.
  5. Your app fetches the Preview Mode endpoint (/api/preview by default) to set the Preview Mode cookie.
  6. Your app refreshes the page, now with Preview Mode active.

If the Preview Mode cookie is not set in Step 5 for any reason, such as accessing the incorrect API endpoint, Steps 4-6 get stuck in an infinite loop.

angeloashmore commented 2 years ago

@jeremytenjo @guilhermefront @chamois-d-or @webda2l

Could you try out a new alpha version, v0.2.0-alpha.0, and let me know if it fixes any of the infinite reloading issues?

npm install @prismicio/next@alpha

This version adds support for basePath if your app uses it (see #20 for more details). It also includes some extra protections against infinite loops when the preview hooks do not work as expected. In some cases, you may see a console error that provides more details.

Thanks!

webda2l commented 2 years ago

Hey everyone, thanks for the details. I will be looking into why this is happening and coming up with a solution.

Could everyone provide me details about their app?

1. Do you use [`basePath`](https://nextjs.org/docs/api-reference/next.config.js/basepath) in your app? If not, do you have any other setup that changes your app's URLs (middleware, i18n, etc.)?

No basePath, only a middleware as explain earlier.

export const middleware = async (request: NextRequest) => {
  if (request.nextUrl.pathname === '/') {
    if (!request.cookies[COOKIE_JWT_HP]) {
      return
    }

    const url = request.nextUrl.clone()
    url.pathname = routes.dashboard
    return NextResponse.redirect(url)
  }
}
2. Are you using the recommended `/api/preview` and `/api/exit-preview` API endpoints? If not, what are they?

Yes

3. Are you using an Incognito or some kind of private window for previews?

No

This will help me understand how <PrismicPreview> should support your setup, or identify extra config that is necessary for your app.

Thanks!

Some background info on why the infinite refresh happens: Prismic lets you share preview sessions with others by clicking the Get a sharable link button in the Prismic toolbar. This will only appear when you are in a preview session.

When a users visits the shared preview link, the following happens:

1. User visits the Prismic URL.

2. It sets a cookie that identifies the preview session.

3. User is redirected to your app's page where the shareable preview link was created.

4. Your app sees the Prismic cookie, but also sees that Next.js's Preview Mode is not active.

5. Your app fetches the Preview Mode endpoint (`/api/preview` by default) to set the Preview Mode cookie.

6. Your app refreshes the page, now with Preview Mode active.

If the Preview Mode cookie is not set in Step 5 for any reason, such as accessing the incorrect API endpoint, Steps 4-6 get stuck in an infinite loop.

@jeremytenjo @guilhermefront @chamois-d-or @webda2l

Could you try out a new alpha version, v0.2.0-alpha.0, and let me know if it fixes any of the infinite reloading issues?

npm install @prismicio/next@alpha

This version adds support for basePath if your app uses it (see #20 for more details). It also includes some extra protections against infinite loops when the preview hooks do not work as expected. In some cases, you may see a console error that provides more details.

Thanks!

No improvement on my side with a custom type 'container' case.

const DashboardPage: INextPageWithLayout = () => {
  const { checkingAuth } = useAuthRequired()

  const [document, { state, error }] = usePrismicDocumentByUID(
    'container',
    'banner'
  )

  if (checkingAuth || state !== 'loaded') return <ContainerLoading />

  return (
    <Wrapper>
      ...

      <SliceZone
        slices={document.data.slices}
        components={components}
        context={{ misc: 'misc' }}
      />

      ...

I succeed to preview once the page, but if I do a change & save from prismic.io, or press enter in the url address bar, it start looping. It's not an usual case as explain earlier, and I suspect an issue with Next & middleware https://github.com/prismicio/prismic-next/issues/13#issuecomment-1087491282. I'll see that with them later maybe, so if your alpha release fix the problem for others, feel free to close the issue.

Because, on another case, with a more classic use of Prismic in the way of yours example projects and documentation, the preview works well as expected. :)

const PrismicPage: INextPageWithLayout = ({ slices }) => (
  <>
    <SliceZone slices={slices} components={components} />
  </>
)
...
guitheengineer commented 2 years ago

@jeremytenjo @guilhermefront @chamois-d-or @webda2l

Could you try out a new alpha version, v0.2.0-alpha.0, and let me know if it fixes any of the infinite reloading issues?

npm install @prismicio/next@alpha

This version adds support for basePath if your app uses it (see #20 for more details). It also includes some extra protections against infinite loops when the preview hooks do not work as expected. In some cases, you may see a console error that provides more details.

Thanks!

Still having the same problem.

Do you use basePath in your app? If not, do you have any other setup that changes your app's URLs (middleware, i18n, etc.)?

We don't use basePath, but we have trailingSlash set to true (changing it to false didn't solve here)

Are you using the recommended /api/preview and /api/exit-preview API endpoints? If not, what are they?

Yes

Are you using an Incognito or some kind of private window for previews?

No

angeloashmore commented 2 years ago

Hey everyone, I still have not been able to track down or reproduce this issue. Could someone (@webda2l or @guilhermefront?) share a project that gets stuck in an infinite loop during a preview?

I'll need the following to test on my side:

If you would like to send this privately, you can send me a direct message on the Prismic community forum with this link: https://community.prismic.io/new-message?username=angeloashmore&title=@prismicio/next%20-%20GitHub%20Issue%2013

Thank you!

aaron5670 commented 2 years ago

Same issue here, infinite reloading the website.

Tried with v0.1.2 and alpha v0.2.

angeloashmore commented 2 years ago

Hey everyone, after more investigations, it looks like the issue roots from the Prismic Toolbar, not necessarily @prismicio/next.

A PR fixing two bugs was opened here: https://github.com/prismicio/prismic-toolbar/pull/97

I am working toward getting the fix deployed. Once it is available, I'll post here again to ask everyone to test their previews again. Thank you for your patience! 🙏

angeloashmore commented 2 years ago

Hey everyone, a quick update: The Prismic team is working on validating the toolbar PR link above before deploying publicly.

Once it is available to test, I'll post here again. Thank you!

lihbr commented 2 years ago

Hey there, thank you all for your contribution and patience 🙏

The fixed toolbar was deployed at the beginning of July, you should no longer experience the above.

If you still do, feel free to reopen this issue or open a new one :)