GriffinJohnston / ldrs

Modern, tree-shakeable loader & spinner web components. Made with CSS, HTML and SVG. https://uiball.com/ldrs
MIT License
1.75k stars 54 forks source link

NextJs: ReferenceError: HTMLElement is not defined #27

Closed Joel-Valentine closed 2 months ago

Joel-Valentine commented 2 months ago

Vercel build logs:

ReferenceError: HTMLElement is not defined
    at 40746 (/vercel/path0/.next/server/chunks/389.js:1:8450)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:128)
    at 33385 (/vercel/path0/.next/server/app/page.js:1:11693)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:128)
    at 54497 (/vercel/path0/.next/server/app/page.js:1:4959)
    at Object.t [as require] (/vercel/path0/.next/server/webpack-runtime.js:1:128)
    at require (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:16:18490)
    at I (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:94362)
    at /vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:96668
    at F._fromJSON (/vercel/path0/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:97106) {
  digest: '2575066004'

This error also happens locally.

Heres my very basic LoadingPage component:

import { quantum } from 'ldrs'
import styles from './LoadingPage.module.css'

const LoadingPage = () => {
  quantum.register()

  return (
    <div className={styles.container}>
      <l-quantum size="60" speed="1.75" color="#282828" />
    </div>
  )
}

export default LoadingPage

What I've tried:

GriffinJohnston commented 2 months ago

Hey, I've got COVID right now, but I'll take a look at this as soon as I can think straight.

The one thing I'll suggest right off the bat is to use the useEffect method, but also move the import there as a dynamic import.

const { quantum } = await import('ldrs')

There's a complete example of this in the NextJS guide.

Joel-Valentine commented 2 months ago

Your pointers helped massively, thanks! Here is what I settled with. I think this technically means there could be a small delay before the loader shows? I'm unsure exactly how NextJS deals with this. But it works now! Thanks.

import { useEffect } from 'react'
import styles from './LoadingPage.module.css'

const registerQuantumLoader = async () => {
  const { quantum } = await import('ldrs')
  quantum.register()
}

const LoadingPage = () => {
  useEffect(() => {
    registerQuantumLoader()
  }, [])

  return (
    <div className={styles.container}>
      <l-quantum size="60" speed="1.75" color="#282828" />
    </div>
  )
}

export default LoadingPage

All works now

GriffinJohnston commented 2 months ago

Happy to help! I'm actually planning to add React components back to this library at some point. Frameworks like Next just don't play nice with web components unfortunately, so the DX suffers.