sanity-io / visual-editing

https://visual-editing-studio.sanity.build
MIT License
35 stars 20 forks source link

index.mjs:11 Uncaught Error: Encoded data has invalid length #889

Closed aqilusman45 closed 5 months ago

aqilusman45 commented 7 months ago

Facing an issue when integrating next js draft mode visual editing using @sanity/overlay as well as on the latest sanity/visual-editing package both through the below error on both npm I have also tried the latest versions on production and on locally both it loads the page and then scroll a certain amount of page it throughs the error (index.mjs:11 Uncaught Error: Encoded data has invalid length) It's related to node_modules @sanity/visual-editing I have attached the screenshot below for reference

image

Its my packages json file

"@headlessui/react": "^1.7.18", "@phosphor-icons/react": "^2.0.14", "@portabletext/react": "3.0.4", "@sanity/client": "^6.10.0", "@sanity/demo": "^1.0.2", "@sanity/overlays": "^2.3.14", "@sanity/presentation": "1.2.0", "@sanity/react-loader": "^1.6.4", "@sanity/ui": "^2.0.1", "@sanity/vision": "^3.25.0", "@sanity/visual-editing": "^1.2.2", "@tailwindcss/typography": "0.5.9", "classnames": "^2.3.2", "framer-motion": "^10.16.4", "gsap": "^3.12.4", "js-search": "^2.0.1", "matter-js": "^0.19.0", "next": "13.4.8", "next-sanity": "^5.5.4", "poly-decomp": "^0.3.0", "react": "18.2.0", "react-dom": "18.2.0", "react-media-hook": "^0.5.0", "react-player": "^2.14.1", "react-share": "^5.0.3", "react-slick": "^0.29.0", "react-stars": "^2.2.5", "react-toastify": "^10.0.4", "reading-time": "^1.5.0", "sanity": "3.21.3", "sanity-plugin-iframe-pane": "2.5.5", "styled-components": "5.3.11", "swr": "^2.2.4", "usehooks-ts": "^2.9.1"

sanity.config is look like this 
```
/**

// see https://www.sanity.io/docs/api-versioning for how versioning works import { apiVersion, dataset, previewSecretId, projectId, } from '~/lib/sanity.api' import { PageTypes } from '~/lib/sanity.links' import { schemaTypes } from '~/schemas' import { structureResolver } from '~/schemas/desk' import { presentationTool } from 'sanity/presentation' import { locate } from '~/lib/presentation/locate' import { getClient } from './src/lib/sanity.client' import { groq } from 'next-sanity' // Define the actions that should be available for singleton documents const singletonActions = new Set(['publish', 'discardChanges', 'restore']) // Define the singleton document types

const requiresSlug = [PageTypes['Page'], PageTypes['Post']] const iframeOptions = { url: defineUrlResolver({ base: '/api/draft', requiresSlug, }), urlSecretId: previewSecretId, reload: { button: true }, }

export const previewView = (S) => S.view.component(Iframe).options(iframeOptions).title('Preview')

async function getPreviewUrl(doc) { const { slug: { current = '' } = {}, _id: docId, _type: docType, } = (await doc) || {} if (docId?.startsWith('drafts') && !current) { return ${window.location.origin}/api/draft?type=page&slug=/&secret=${process.env.SANITY_API_READ_TOKEN}&draft=true } else if (current) { return ${window.location.origin}/api/draft?type=${docType}&slug=${current}&secret=${process.env.SANITY_API_READ_TOKEN} } else { const query = groq*[_type == "page" && references(*[_type == '${docType}' && _id == '${docId}']._id)][0] { _id, "slug": slug.current, _type } const client = getClient() const childDoc = await client.fetch(query) if (childDoc) { const { _type: childDocType, slug: childDocSlug } = childDoc const url = ${window.location.origin}/api/draft?type=${childDocType}&slug=${childDocSlug}&secret=${process.env.SANITY_API_READ_TOKEN}&sectionId=${docId} return url } else { const url = ${window.location.origin}/api/draft?type=page&mode=draft&slug=/&secret=${process.env.SANITY_API_READ_TOKEN}&reference=not return url } } }

export const defaultDocumentNode = (S) => { return S.document().views([ S.view.form(), S.view .component(Iframe) .options({ url: (doc) => getPreviewUrl(doc), }) .title('Preview'), ]) }

export default defineConfig({ basePath: '/studio', name: 'wise-digital-partners', title: 'Wise Digital Partners', projectId, dataset, //edit schemas in './src/schemas' schema: { types: schemaTypes, // Filter out singleton types from the global “New document” menu options // templates: (templates) => // templates.filter(({ schemaType }) => !singletonTypes.has(schemaType)), }, plugins: [ deskTool({ structure: structureResolver, defaultDocumentNode, }), // Add the "Open preview" action previewUrl({ base: '/api/draft', requiresSlug, urlSecretId: previewSecretId, }), // Vision lets you query your content with GROQ in the studio // https://www.sanity.io/docs/the-vision-plugin visionTool({ defaultApiVersion: apiVersion }), presentationTool({ locate, previewUrl: { draftMode: { enable: '/api/presentation-draft', disable: '/api/disable-draft', }, }, }), ], }) _app.js is look like this import '~/styles/global.scss'

import { VisualEditing } from '@sanity/visual-editing/next-pages-router' import { useRouter } from 'next/router' import { lazy, Suspense, useEffect, useState } from 'react'

import { hideBodyScroll, showBodyScroll } from '~/utils/helpers'

import Layout from '../components/layout' import SEO from '../components/seo'

const PreviewProvider = lazy(() => import('~/components/PreviewProvider')) // const VisualEditing = lazy(() => import("~/components/VisualEditing"));

export default function App({ Component, pageProps }) { const { draftMode, token, transparentNav, seo } = pageProps const router = useRouter() const pageKey = router.asPath const [toggle, setToggle] = useState('')

const toggleFunc = (flag) => { setToggle(flag) } // useEffect(() => { // if (toggle) { // hideBodyScroll(); // } else { // showBodyScroll(); // } // }, [toggle]); const enableLayout = !pageKey?.split('/')?.includes('studio')

return enableLayout ? ( <Layout toggle={toggle} toggleFunc={toggleFunc} transparentNav={transparentNav}

{draftMode ? (

) : ( <> <SEO {...seo} /> <Component {...pageProps} toggleFunc={toggleFunc} toggle={toggle} /> </> )} ) : draftMode ? (

) : ( <> <SEO {...seo} /> <Component {...pageProps} toggleFunc={toggleFunc} toggle={toggle} /> </> ) } ` and the slug file is look like this

`import { groq } from 'next-sanity' import { useLiveQuery } from 'next-sanity/preview'

import { fragment as modulesFragment } from '~/components/module-renderer' import ModuleRenderer from '~/components/module-renderer' import { readToken } from '~/lib/sanity.api' import { getClient } from '~/lib/sanity.client' export const getPageQuery = (slug) => groq { "page": *[_type == "page" && slug.current == '${slug}'] { _type, "title": title, "slug": slug.current, ..., transparentNav, modules[] { ..., ${modulesFragment} } } }

function Page(props) { const { draftMode, page: { id = '' } = {} } = props || {} const pageQuery = (slug) => groq *[_type == "page" && slug.current == '${slug}'][0] { _type, "title": title, "slug": slug.current, ..., transparentNav, modules[] { ..., ${modulesFragment} } }

switch (props.page?._type) { case 'page': // eslint-disable-next-line react-hooks/exhaustive-deps const [page] = useLiveQuery(props.page, pageQuery(props.slug))

  // eslint-disable-next-line react-hooks/exhaustive-deps
  const { modules } = page || {}
  return (
    <>
      {modules?.length > 0 && (
        <ModuleRenderer
          id={id}
          draftMode={draftMode}
          reviews={props.reviewsSection}
          modules={modules}
          arr_two_Columns_Featured={props?.twoColumnsFeatured}
          allPress={props?.allPress}
          arr={props?.pressFeatured}
          allPosition={props?.allPosition}
          allBlogHub={props?.allBlogHub}
          wiseVideos={props?.wiseVideos}
          teamProfile={props?.teamProfile}
          industryPages={props?.industryPages}
          arr_featured={props?.featured}
          allShowCase={props?.allShowCase}
        />
      )}
    </>
  )
default:
  return null

} }

export async function getStaticPaths() { const client = getClient() // const [ // slugs1, // slugs2, // slugs3, // slugs4, // slugs5, // slugs6, // slugs7, // slugs8, // slugs9, // ] = await client.fetch( // groq[ // *[_type == "page"] { // "title": title, // "slug": slug.current // }, // *[_type == "press"] { // "title": title, // "slug": slug.current // }, // *[_type == "position"] { // "title": title, // "slug": slug.current // }, // *[_type == "teamProfile"] { // "title": name, // "slug": slug.current // }, // *[_type == "technologyPages"] { // "title": name, // "slug": slug.current // }, // *[_type == "services"] { // "title": name, // "slug": slug.current // }, // *[_type == "industryPages"] { // "title": title, // "slug": slug.current // }, // *[_type == "subServices"] { // "title": title, // "slug": slug.current // }, // *[_type == "subIndustryPages"] { // "title": title, // "slug": slug.current // } // ], // )

// const allSlugs = [ // ...slugs1, // ...slugs2, // ...slugs3, // ...slugs4, // ...slugs5, // ...slugs6, // ...slugs7, // ...slugs8, // ...slugs9, // ]

return { paths: ['/'], // allSlugs?.map(({ slug }) => (slug !== '/' ? /${slug} : ${slug})) || // [], fallback: false, } }

export const getStaticProps = async ({ draftMode = false, params }) => { let slug = '/' if (Object.keys(params || {}).length) { const { slug: currentSlug } = params slug = currentSlug?.join('/') }

const client = getClient(draftMode ? readToken : undefined) if (!slug) throw new Error('No slug provided') const pageQuery = getPageQuery(slug)

const { page } = await client.fetch(pageQuery) const pageData = [...page] return { props: { draftMode, token: draftMode ? readToken : '', page: pageData[0], transparentNav: pageData[0]?.transparentNav || false, seo: { seoTitle: pageData[0]?.seoTitle, metaDescription: pageData[0]?.metaDescription, }, slug, }, revalidate: 10, } }

export default Page ` disable end point

`import { resolveHref } from '~/lib/sanity.links'

const token = process.env.SANITY_API_READ_TOKEN if (!token) { throw new Error( 'A secret is provided but there is no SANITY_API_READ_TOKEN environment variable setup.', ) }

export default async function preview(req, res) { if (!token) { res.status(500).send('Misconfigured server') return } const { query } = req

const secret = typeof query.secret === 'string' ? query.secret : undefined const slug = typeof query.slug === 'string' ? query.slug : undefined const type = typeof query.type === 'string' ? query.type : undefined const draft = query.draft ? query.draft : undefined const reference = query.reference ? query.reference : undefined const sectionId = query.sectionId ? query.sectionId : undefined const location = type ? resolveHref(type, slug, sectionId) : '/'

if (!secret) { res.status(401) res.send('Invalid secret') return } if (draft) { res.status(200) res.send( 'Draft mode documents that are not published do not have a preview available.', ) return } if (reference) { res.status(200) res.send( 'The section has been published but has not been referenced on any page.', ) return } res.setDraftMode({ enable: true }) res.writeHead(307, { Location: location, }) res.end() return } presentation draft is look like this // ./src/pages/api/draft.ts

import { validatePreviewUrl } from '@sanity/preview-url-secret' import { createClient } from 'next-sanity'

const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET, apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION, useCdn: false, token: process.env.SANITY_API_READ_TOKEN, })

export default async function handle(req, res) { if (!req.url) { throw new Error('Missing url') }

const { isValid, redirectTo = '/' } = await validatePreviewUrl( client, req.url, ) if (!isValid) { return res.status(401).send('Invalid secret') } // Enable Draft Mode by setting the cookies res.setDraftMode({ enable: true }) res.writeHead(307, { Location: redirectTo }) res.end() } ` locate is look like this

import { map } from 'rxjs'

export const locate = (params, context) => {
  if (params.type === 'post') {
    const doc$ = context.documentStore.listenQuery(
      `*[_id == $id][0]{slug,title}`,
      params,
      { perspective: 'previewDrafts' }, // returns a draft article if it exists
    )

    return doc$.pipe(
      map((doc) => {
        // If the document doesn't exist or have a slug, return null
        if (!doc || !doc.slug?.current) {
          return null
        }
        return {
          locations: [
            {
              title: doc.title || 'Untitled',
              href: `/${doc.slug.current}`,
            },
          ],
        }
      }),
    )
  }
  if (params.type === 'page') {
    const doc$ = context.documentStore.listenQuery(
      `*[_id == $id][0]{slug,title}`,
      params,
      { perspective: 'previewDrafts' }, // returns a draft article if it exists
    )
    return doc$.pipe(
      map((doc) => {
        // If the document doesn't exist or have a slug, return null
        if (!doc || !doc.slug?.current) {
          return null
        }
        return {
          locations: [
            {
              title: doc.title || 'Untitled',
              href: doc.slug.current?.startsWith('/')
                ? doc.slug.current
                : `/${doc.slug.current}`,
              id: doc._type,
            },
          ],
        }
      }),
    )
  }
  return null
}

any feedback regarding this is appreciated

stipsan commented 5 months ago

CLosing this as we're unable to reproduce