Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

Discussion on strange page loading behavior in a NextJS project with dynamic imports and getStaticProps.

9 replies
Last updated: Mar 23, 2022
Hey guys, working on a NextJS project, which is live here . Noticing some strange behaviour on first load. Can anyone illuminate me as to why my page might be loading bottom-to-top in a staggered sequence? This content flash is driving me nuts!
Mar 22, 2022, 4:34 AM
Is the green section static html? And I’m assuming that the product details is loaded with ServerSideProps or purely client side with something like a
fetch
method being used in the main function?
Mar 22, 2022, 8:39 AM
Would help to know more about how your site is setup and how the data is fetched.
I would guess it is because the content is fetched async (getServerSideProps) in which case you should consider if ISG may be an option (or getStaticProps) or display a loading spinner while content is fetched.
Mar 22, 2022, 7:53 PM
May also be a FOUC issue if the CSS is not rendered serverside properly
Mar 22, 2022, 7:54 PM
Thanks for replying insanity, Thomas. I’m using
getStaticProps
to fetch data from Sanity, and subscription plans from ReCharge within my standard page component
pages/[…slug].js
:

export async function getStaticProps ({ preview = false, previewData, params }) {
  const { slug } = params
  const pageData = await getStaticPage(
    last(slug),
    {
      active: preview,
      token: previewData?.token
    }
  )

  let subscriptionProductData = null
  const product = get(pageData, 'page.product', false)

  if (product) {
    subscriptionProductData = await getSellingPlans(product.handle)
    if (subscriptionProductData) {
      pageData.page.subscriptions = subscriptionProductData
    }
  }

...
Mar 23, 2022, 1:17 AM
Within Sanity, I let users customise a page by organising modules into ‘slices’. They’re mapped over and rendered to the page like so:

import { useMemo } from 'react'
import forEach from 'lodash/forEach'
import ErrorBoundary from '../ErrorBoundary'
import dynamic from 'next/dynamic'

const ProductHero = dynamic(() => import('./ProductHero'))
const ShopGrid = dynamic(() => import('./ShopGrid'))
const AdditionalInfoSlice = dynamic(() => import('./AdditionalInfoSlice'))
const ReviewsSlice = dynamic(() => import('./ReviewsSlice'))
const TextColumnsSlice = dynamic(() => import('./TextColumnsSlice'))
const PagePreviewSlice = dynamic(() => import('./PagePreviewSlice'))

const sliceComponentSelector = {
  shop_grid_slice: ShopGrid,
  additional_info_slice: AdditionalInfoSlice,
  reviews_slice: ReviewsSlice,
  text_columns_slice: TextColumnsSlice,
  page_preview_tiles: PagePreviewSlice
}

const Slices = ({ page, settings, slices, summary }) => {
  const sliceComponents = useMemo(() => {
    const components = []
    forEach(slices, (slice, i) => {
      const Component = sliceComponentSelector[slice._type]
      if (Component) {
        components.push(
          <ErrorBoundary key={`slice-${slice._key}`}>
            <Component data={slice} page={page} summary={summary} first={i === 0} />
          </ErrorBoundary>
        )
      }
    })
    return components
  }, [slices, page])

  if (page.pageType === 'product') {
    return (
      <>
        <ProductHero page={page} settings={settings} />
        {sliceComponents}
      </>
    )
  }

  return sliceComponents
}

export default Slices
Mar 23, 2022, 1:21 AM
What is the output from
next build
?
Mar 23, 2022, 1:27 AM
It could be the dynamic import of the component, you may need to provide a ‘loading’ state ie. https://nextjs.org/docs/advanced-features/dynamic-import#with-custom-loading-component
Mar 23, 2022, 1:31 AM
Good shout, thanks for the lead 🕵️‍♂️
Mar 23, 2022, 1:39 AM
let us know how it goes
Mar 23, 2022, 1:42 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?